/// Return a pointer to \c ValueProfData instance ready to be streamed.
static std::unique_ptr<ValueProfData>
serializeFrom(const InstrProfRecord &Record);
+ /// Check the integrity of the record. Return the error code when
+ /// an error is detected, otherwise return instrprof_error::success.
+ instrprof_error checkIntegrity();
/// Return a pointer to \c ValueProfileData instance ready to be read.
/// All data in the instance are properly byte swapped. The input
/// data is assumed to be in little endian order.
ValueProfData());
}
+instrprof_error ValueProfData::checkIntegrity() {
+ if (NumValueKinds > IPVK_Last + 1)
+ return instrprof_error::malformed;
+ // Total size needs to be mulltiple of quadword size.
+ if (TotalSize % sizeof(uint64_t))
+ return instrprof_error::malformed;
+
+ ValueProfRecord *VR = getFirstValueProfRecord(this);
+ for (uint32_t K = 0; K < this->NumValueKinds; K++) {
+ if (VR->Kind > IPVK_Last)
+ return instrprof_error::malformed;
+ VR = getValueProfRecordNext(VR);
+ if ((char *)VR - (char *)this > (ptrdiff_t)TotalSize)
+ return instrprof_error::malformed;
+ }
+ return instrprof_error::success;
+}
+
ErrorOr<std::unique_ptr<ValueProfData>>
ValueProfData::getValueProfData(const unsigned char *D,
const unsigned char *const BufferEnd,
const unsigned char *Header = D;
uint32_t TotalSize = swapToHostOrder<uint32_t>(Header, Endianness);
- uint32_t NumValueKinds = swapToHostOrder<uint32_t>(Header, Endianness);
-
if (D + TotalSize > BufferEnd)
return instrprof_error::too_large;
- if (NumValueKinds > IPVK_Last + 1)
- return instrprof_error::malformed;
- // Total size needs to be mulltiple of quadword size.
- if (TotalSize % sizeof(uint64_t))
- return instrprof_error::malformed;
std::unique_ptr<ValueProfData> VPD = allocValueProfData(TotalSize);
-
memcpy(VPD.get(), D, TotalSize);
// Byte swap.
VPD->swapBytesToHost(Endianness);
- // Data integrity check:
- ValueProfRecord *VR = getFirstValueProfRecord(VPD.get());
- for (uint32_t K = 0; K < VPD->NumValueKinds; K++) {
- if (VR->Kind > IPVK_Last)
- return instrprof_error::malformed;
- VR = getValueProfRecordNext(VR);
- if ((char *)VR - (char *)VPD.get() > (ptrdiff_t)TotalSize)
- return instrprof_error::malformed;
- }
+ instrprof_error EC = VPD->checkIntegrity();
+ if (EC != instrprof_error::success)
+ return EC;
return std::move(VPD);
}