[PGO] Extract VP data integrity check code into a helper function (NFC)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@254217 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Xinliang David Li 2015-11-28 04:56:07 +00:00
parent 66f5f81e89
commit 170357c9b7
2 changed files with 24 additions and 17 deletions

View File

@ -506,6 +506,9 @@ typedef struct ValueProfData {
/// Return a pointer to \c ValueProfData instance ready to be streamed. /// Return a pointer to \c ValueProfData instance ready to be streamed.
static std::unique_ptr<ValueProfData> static std::unique_ptr<ValueProfData>
serializeFrom(const InstrProfRecord &Record); 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. /// Return a pointer to \c ValueProfileData instance ready to be read.
/// All data in the instance are properly byte swapped. The input /// All data in the instance are properly byte swapped. The input
/// data is assumed to be in little endian order. /// data is assumed to be in little endian order.

View File

@ -442,6 +442,24 @@ static std::unique_ptr<ValueProfData> allocValueProfData(uint32_t TotalSize) {
ValueProfData()); 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>> ErrorOr<std::unique_ptr<ValueProfData>>
ValueProfData::getValueProfData(const unsigned char *D, ValueProfData::getValueProfData(const unsigned char *D,
const unsigned char *const BufferEnd, const unsigned char *const BufferEnd,
@ -452,31 +470,17 @@ ValueProfData::getValueProfData(const unsigned char *D,
const unsigned char *Header = D; const unsigned char *Header = D;
uint32_t TotalSize = swapToHostOrder<uint32_t>(Header, Endianness); uint32_t TotalSize = swapToHostOrder<uint32_t>(Header, Endianness);
uint32_t NumValueKinds = swapToHostOrder<uint32_t>(Header, Endianness);
if (D + TotalSize > BufferEnd) if (D + TotalSize > BufferEnd)
return instrprof_error::too_large; 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); std::unique_ptr<ValueProfData> VPD = allocValueProfData(TotalSize);
memcpy(VPD.get(), D, TotalSize); memcpy(VPD.get(), D, TotalSize);
// Byte swap. // Byte swap.
VPD->swapBytesToHost(Endianness); VPD->swapBytesToHost(Endianness);
// Data integrity check: instrprof_error EC = VPD->checkIntegrity();
ValueProfRecord *VR = getFirstValueProfRecord(VPD.get()); if (EC != instrprof_error::success)
for (uint32_t K = 0; K < VPD->NumValueKinds; K++) { return EC;
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;
}
return std::move(VPD); return std::move(VPD);
} }