summaryrefslogtreecommitdiffstats
path: root/llvm/lib/ProfileData
diff options
context:
space:
mode:
authorXinliang David Li <davidxl@google.com>2015-11-17 03:47:21 +0000
committerXinliang David Li <davidxl@google.com>2015-11-17 03:47:21 +0000
commitb8c3ad1d0561f5ce4e3e8042637b9e9736ab4887 (patch)
tree772364c74f4a2d426f68ec6e865f797caff27156 /llvm/lib/ProfileData
parent055a08a4887d8e7108c3893e71bc1d8ad56c9585 (diff)
downloadbcm5719-llvm-b8c3ad1d0561f5ce4e3e8042637b9e9736ab4887.tar.gz
bcm5719-llvm-b8c3ad1d0561f5ce4e3e8042637b9e9736ab4887.zip
Fix unaligned memory read issue exposed by ubsan
Indexed profile data as designed today does not guarantee counter data to be well aligned, so reading needs to use the slower form (with memcpy). This is less than ideal and should be improved in the future (i.e., with fixed length function key instead of variable length name key). llvm-svn: 253309
Diffstat (limited to 'llvm/lib/ProfileData')
-rw-r--r--llvm/lib/ProfileData/InstrProf.cpp20
1 files changed, 10 insertions, 10 deletions
diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp
index 762f00b48b6..ef7b19b2882 100644
--- a/llvm/lib/ProfileData/InstrProf.cpp
+++ b/llvm/lib/ProfileData/InstrProf.cpp
@@ -184,11 +184,13 @@ void ValueProfRecord::serializeFrom(const InstrProfRecord &Record,
}
}
-template <class T> static T swapToHostOrder(T v, support::endianness Orig) {
- if (Orig == getHostEndianness())
- return v;
- sys::swapByteOrder<T>(v);
- return v;
+template <class T>
+static T swapToHostOrder(const unsigned char *&D, support::endianness Orig) {
+ using namespace support;
+ if (Orig == little)
+ return endian::readNext<T, little, unaligned>(D);
+ else
+ return endian::readNext<T, big, unaligned>(D);
}
// For writing/serializing, Old is the host endianness, and New is
@@ -278,10 +280,9 @@ ValueProfData::getValueProfData(const unsigned char *D,
if (D + sizeof(ValueProfData) > BufferEnd)
return instrprof_error::truncated;
- uint32_t TotalSize = swapToHostOrder<uint32_t>(
- reinterpret_cast<const uint32_t *>(D)[0], Endianness);
- uint32_t NumValueKinds = swapToHostOrder<uint32_t>(
- reinterpret_cast<const uint32_t *>(D)[1], Endianness);
+ 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;
@@ -307,7 +308,6 @@ ValueProfData::getValueProfData(const unsigned char *D,
return instrprof_error::malformed;
}
- D += TotalSize;
return std::move(VPD);
}
OpenPOWER on IntegriCloud