[llvm] r253309 - Fix unaligned memory read issue exposed by ubsan

Xinliang David Li via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 16 19:47:21 PST 2015


Author: davidxl
Date: Mon Nov 16 21:47:21 2015
New Revision: 253309

URL: http://llvm.org/viewvc/llvm-project?rev=253309&view=rev
Log:
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).

Modified:
    llvm/trunk/lib/ProfileData/InstrProf.cpp

Modified: llvm/trunk/lib/ProfileData/InstrProf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/InstrProf.cpp?rev=253309&r1=253308&r2=253309&view=diff
==============================================================================
--- llvm/trunk/lib/ProfileData/InstrProf.cpp (original)
+++ llvm/trunk/lib/ProfileData/InstrProf.cpp Mon Nov 16 21:47:21 2015
@@ -184,11 +184,13 @@ void ValueProfRecord::serializeFrom(cons
   }
 }
 
-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 un
   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 un
       return instrprof_error::malformed;
   }
 
-  D += TotalSize;
   return std::move(VPD);
 }
 




More information about the llvm-commits mailing list