[llvm] r204557 - InstrProf: Check pointer size in raw profile

Duncan P. N. Exon Smith dexonsmith at apple.com
Sat Mar 22 20:38:12 PDT 2014


Author: dexonsmith
Date: Sat Mar 22 22:38:12 2014
New Revision: 204557

URL: http://llvm.org/viewvc/llvm-project?rev=204557&view=rev
Log:
InstrProf: Check pointer size in raw profile

Since the profile can come from 32-bit machines, we need to check the
pointer size.  Change the magic number to facilitate this.

Adds tests for reading 32-bit and 64-bit binaries (both big- and
little-endian).  The tests write a binary using printf in RUN lines
(like raw-magic-but-no-header.test).  Assuming the bots don't complain,
this seems like a better way forward for testing RawInstrProfReader than
committing binary files.

<rdar://problem/16400648>

Added:
    llvm/trunk/test/tools/llvm-profdata/raw-32-bits-be.test
    llvm/trunk/test/tools/llvm-profdata/raw-32-bits-le.test
    llvm/trunk/test/tools/llvm-profdata/raw-64-bits-be.test
    llvm/trunk/test/tools/llvm-profdata/raw-64-bits-le.test
Modified:
    llvm/trunk/include/llvm/ProfileData/InstrProfReader.h
    llvm/trunk/lib/ProfileData/InstrProfReader.cpp

Modified: llvm/trunk/include/llvm/ProfileData/InstrProfReader.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/InstrProfReader.h?rev=204557&r1=204556&r2=204557&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ProfileData/InstrProfReader.h (original)
+++ llvm/trunk/include/llvm/ProfileData/InstrProfReader.h Sat Mar 22 22:38:12 2014
@@ -126,6 +126,10 @@ public:
 ///
 /// This format is a raw memory dump of the instrumentation-baed profiling data
 /// from the runtime.  It has no index.
+///
+/// Templated on the unsigned type whose size matches pointers on the platform
+/// that wrote the profile.
+template <class IntPtrT>
 class RawInstrProfReader : public InstrProfReader {
 private:
   /// The profile data file contents.
@@ -136,8 +140,8 @@ private:
     const uint32_t NameSize;
     const uint32_t NumCounters;
     const uint64_t FuncHash;
-    const uint64_t NamePtr;
-    const uint64_t CounterPtr;
+    const IntPtrT NamePtr;
+    const IntPtrT CounterPtr;
   };
   struct RawHeader {
     const uint64_t Magic;
@@ -174,16 +178,19 @@ private:
   IntT swap(IntT Int) const {
     return ShouldSwapBytes ? sys::SwapByteOrder(Int) : Int;
   }
-  const uint64_t *getCounter(uint64_t CounterPtr) const {
+  const uint64_t *getCounter(IntPtrT CounterPtr) const {
     ptrdiff_t Offset = (swap(CounterPtr) - CountersDelta) / sizeof(uint64_t);
     return CountersStart + Offset;
   }
-  const char *getName(uint64_t NamePtr) const {
+  const char *getName(IntPtrT NamePtr) const {
     ptrdiff_t Offset = (swap(NamePtr) - NamesDelta) / sizeof(char);
     return NamesStart + Offset;
   }
 };
 
+typedef RawInstrProfReader<uint32_t> RawInstrProfReader32;
+typedef RawInstrProfReader<uint64_t> RawInstrProfReader64;
+
 } // end namespace llvm
 
 #endif // LLVM_PROFILEDATA_INSTRPROF_READER_H_

Modified: llvm/trunk/lib/ProfileData/InstrProfReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/InstrProfReader.cpp?rev=204557&r1=204556&r2=204557&view=diff
==============================================================================
--- llvm/trunk/lib/ProfileData/InstrProfReader.cpp (original)
+++ llvm/trunk/lib/ProfileData/InstrProfReader.cpp Sat Mar 22 22:38:12 2014
@@ -30,8 +30,10 @@ error_code InstrProfReader::create(std::
     return instrprof_error::too_large;
 
   // Create the reader.
-  if (RawInstrProfReader::hasFormat(*Buffer))
-    Result.reset(new RawInstrProfReader(std::move(Buffer)));
+  if (RawInstrProfReader64::hasFormat(*Buffer))
+    Result.reset(new RawInstrProfReader64(std::move(Buffer)));
+  else if (RawInstrProfReader32::hasFormat(*Buffer))
+    Result.reset(new RawInstrProfReader32(std::move(Buffer)));
   else
     Result.reset(new TextInstrProfReader(std::move(Buffer)));
 
@@ -85,7 +87,11 @@ error_code TextInstrProfReader::readNext
   return success();
 }
 
-static uint64_t getRawMagic() {
+template <class IntPtrT>
+static uint64_t getRawMagic();
+
+template <>
+uint64_t getRawMagic<uint64_t>() {
   return
     uint64_t(255) << 56 |
     uint64_t('l') << 48 |
@@ -97,21 +103,36 @@ static uint64_t getRawMagic() {
     uint64_t(129);
 }
 
-bool RawInstrProfReader::hasFormat(const MemoryBuffer &DataBuffer) {
-  if (DataBuffer.getBufferSize() < sizeof(getRawMagic()))
+template <>
+uint64_t getRawMagic<uint32_t>() {
+  return
+    uint64_t(255) << 56 |
+    uint64_t('l') << 48 |
+    uint64_t('p') << 40 |
+    uint64_t('r') << 32 |
+    uint64_t('o') << 24 |
+    uint64_t('f') << 16 |
+    uint64_t('R') <<  8 |
+    uint64_t(129);
+}
+
+template <class IntPtrT>
+bool RawInstrProfReader<IntPtrT>::hasFormat(const MemoryBuffer &DataBuffer) {
+  if (DataBuffer.getBufferSize() < sizeof(getRawMagic<IntPtrT>()))
     return false;
   const RawHeader *Header = (const RawHeader *)DataBuffer.getBufferStart();
-  return getRawMagic() == Header->Magic ||
-    sys::SwapByteOrder(getRawMagic()) == Header->Magic;
+  return getRawMagic<IntPtrT>() == Header->Magic ||
+    sys::SwapByteOrder(getRawMagic<IntPtrT>()) == Header->Magic;
 }
 
-error_code RawInstrProfReader::readHeader() {
+template <class IntPtrT>
+error_code RawInstrProfReader<IntPtrT>::readHeader() {
   if (!hasFormat(*DataBuffer))
     return error(instrprof_error::bad_magic);
   if (DataBuffer->getBufferSize() < sizeof(RawHeader))
     return error(instrprof_error::bad_header);
   const RawHeader *Header = (const RawHeader *)DataBuffer->getBufferStart();
-  ShouldSwapBytes = Header->Magic != getRawMagic();
+  ShouldSwapBytes = Header->Magic != getRawMagic<IntPtrT>();
   return readHeader(*Header);
 }
 
@@ -119,7 +140,8 @@ static uint64_t getRawVersion() {
   return 1;
 }
 
-error_code RawInstrProfReader::readHeader(const RawHeader &Header) {
+template <class IntPtrT>
+error_code RawInstrProfReader<IntPtrT>::readHeader(const RawHeader &Header) {
   if (swap(Header.Version) != getRawVersion())
     return error(instrprof_error::unsupported_version);
 
@@ -145,7 +167,9 @@ error_code RawInstrProfReader::readHeade
   return success();
 }
 
-error_code RawInstrProfReader::readNextRecord(InstrProfRecord &Record) {
+template <class IntPtrT>
+error_code
+RawInstrProfReader<IntPtrT>::readNextRecord(InstrProfRecord &Record) {
   if (Data == DataEnd)
     return error(instrprof_error::eof);
 
@@ -177,3 +201,8 @@ error_code RawInstrProfReader::readNextR
   ++Data;
   return success();
 }
+
+namespace llvm {
+template class RawInstrProfReader<uint32_t>;
+template class RawInstrProfReader<uint64_t>;
+}

Added: llvm/trunk/test/tools/llvm-profdata/raw-32-bits-be.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-profdata/raw-32-bits-be.test?rev=204557&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-profdata/raw-32-bits-be.test (added)
+++ llvm/trunk/test/tools/llvm-profdata/raw-32-bits-be.test Sat Mar 22 22:38:12 2014
@@ -0,0 +1,42 @@
+RUN: printf '\377lprofR\201' > %t
+RUN: printf '\0\0\0\0\0\0\0\1' >> %t
+RUN: printf '\0\0\0\0\0\0\0\2' >> %t
+RUN: printf '\0\0\0\0\0\0\0\3' >> %t
+RUN: printf '\0\0\0\0\0\0\0\6' >> %t
+RUN: printf '\0\0\0\0\1\0\0\0' >> %t
+RUN: printf '\0\0\0\0\2\0\0\0' >> %t
+
+RUN: printf '\0\0\0\3' >> %t
+RUN: printf '\0\0\0\1' >> %t
+RUN: printf '\0\0\0\0\0\0\0\1' >> %t
+RUN: printf '\2\0\0\0' >> %t
+RUN: printf '\1\0\0\0' >> %t
+
+RUN: printf '\0\0\0\3' >> %t
+RUN: printf '\0\0\0\2' >> %t
+RUN: printf '\0\0\0\0\0\0\0\2' >> %t
+RUN: printf '\2\0\0\03' >> %t
+RUN: printf '\1\0\0\10' >> %t
+
+RUN: printf '\0\0\0\0\0\0\0\023' >> %t
+RUN: printf '\0\0\0\0\0\0\0\067' >> %t
+RUN: printf '\0\0\0\0\0\0\0\101' >> %t
+RUN: printf 'foobar' >> %t
+
+RUN: llvm-profdata show %t -all-functions -counts | FileCheck %s
+
+CHECK: Counters:
+CHECK:   foo:
+CHECK:     Hash: 0x0000000000000001
+CHECK:     Counters: 1
+CHECK:     Function count: 19
+CHECK:     Block counts: []
+CHECK:   bar:
+CHECK:     Hash: 0x0000000000000002
+CHECK:     Counters: 2
+CHECK:     Function count: 55
+CHECK:     Block counts: [65]
+CHECK: Functions shown: 2
+CHECK: Total functions: 2
+CHECK: Maximum function count: 55
+CHECK: Maximum internal block count: 65

Added: llvm/trunk/test/tools/llvm-profdata/raw-32-bits-le.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-profdata/raw-32-bits-le.test?rev=204557&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-profdata/raw-32-bits-le.test (added)
+++ llvm/trunk/test/tools/llvm-profdata/raw-32-bits-le.test Sat Mar 22 22:38:12 2014
@@ -0,0 +1,42 @@
+RUN: printf '\201Rforpl\377' > %t
+RUN: printf '\1\0\0\0\0\0\0\0' >> %t
+RUN: printf '\2\0\0\0\0\0\0\0' >> %t
+RUN: printf '\3\0\0\0\0\0\0\0' >> %t
+RUN: printf '\6\0\0\0\0\0\0\0' >> %t
+RUN: printf '\0\0\0\1\0\0\0\0' >> %t
+RUN: printf '\0\0\0\2\0\0\0\0' >> %t
+
+RUN: printf '\3\0\0\0' >> %t
+RUN: printf '\1\0\0\0' >> %t
+RUN: printf '\1\0\0\0\0\0\0\0' >> %t
+RUN: printf '\0\0\0\2' >> %t
+RUN: printf '\0\0\0\1' >> %t
+
+RUN: printf '\3\0\0\0' >> %t
+RUN: printf '\2\0\0\0' >> %t
+RUN: printf '\02\0\0\0\0\0\0\0' >> %t
+RUN: printf '\03\0\0\2' >> %t
+RUN: printf '\10\0\0\1' >> %t
+
+RUN: printf '\023\0\0\0\0\0\0\0' >> %t
+RUN: printf '\067\0\0\0\0\0\0\0' >> %t
+RUN: printf '\101\0\0\0\0\0\0\0' >> %t
+RUN: printf 'foobar' >> %t
+
+RUN: llvm-profdata show %t -all-functions -counts | FileCheck %s
+
+CHECK: Counters:
+CHECK:   foo:
+CHECK:     Hash: 0x0000000000000001
+CHECK:     Counters: 1
+CHECK:     Function count: 19
+CHECK:     Block counts: []
+CHECK:   bar:
+CHECK:     Hash: 0x0000000000000002
+CHECK:     Counters: 2
+CHECK:     Function count: 55
+CHECK:     Block counts: [65]
+CHECK: Functions shown: 2
+CHECK: Total functions: 2
+CHECK: Maximum function count: 55
+CHECK: Maximum internal block count: 65

Added: llvm/trunk/test/tools/llvm-profdata/raw-64-bits-be.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-profdata/raw-64-bits-be.test?rev=204557&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-profdata/raw-64-bits-be.test (added)
+++ llvm/trunk/test/tools/llvm-profdata/raw-64-bits-be.test Sat Mar 22 22:38:12 2014
@@ -0,0 +1,42 @@
+RUN: printf '\377lprofr\201' > %t
+RUN: printf '\0\0\0\0\0\0\0\1' >> %t
+RUN: printf '\0\0\0\0\0\0\0\2' >> %t
+RUN: printf '\0\0\0\0\0\0\0\3' >> %t
+RUN: printf '\0\0\0\0\0\0\0\6' >> %t
+RUN: printf '\0\0\0\1\0\4\0\0' >> %t
+RUN: printf '\0\0\0\2\0\4\0\0' >> %t
+
+RUN: printf '\0\0\0\3' >> %t
+RUN: printf '\0\0\0\1' >> %t
+RUN: printf '\0\0\0\0\0\0\0\1' >> %t
+RUN: printf '\0\0\0\2\0\4\0\0' >> %t
+RUN: printf '\0\0\0\1\0\4\0\0' >> %t
+
+RUN: printf '\0\0\0\3' >> %t
+RUN: printf '\0\0\0\2' >> %t
+RUN: printf '\0\0\0\0\0\0\0\02' >> %t
+RUN: printf '\0\0\0\2\0\4\0\03' >> %t
+RUN: printf '\0\0\0\1\0\4\0\10' >> %t
+
+RUN: printf '\0\0\0\0\0\0\0\023' >> %t
+RUN: printf '\0\0\0\0\0\0\0\067' >> %t
+RUN: printf '\0\0\0\0\0\0\0\101' >> %t
+RUN: printf 'foobar' >> %t
+
+RUN: llvm-profdata show %t -all-functions -counts | FileCheck %s
+
+CHECK: Counters:
+CHECK:   foo:
+CHECK:     Hash: 0x0000000000000001
+CHECK:     Counters: 1
+CHECK:     Function count: 19
+CHECK:     Block counts: []
+CHECK:   bar:
+CHECK:     Hash: 0x0000000000000002
+CHECK:     Counters: 2
+CHECK:     Function count: 55
+CHECK:     Block counts: [65]
+CHECK: Functions shown: 2
+CHECK: Total functions: 2
+CHECK: Maximum function count: 55
+CHECK: Maximum internal block count: 65

Added: llvm/trunk/test/tools/llvm-profdata/raw-64-bits-le.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-profdata/raw-64-bits-le.test?rev=204557&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-profdata/raw-64-bits-le.test (added)
+++ llvm/trunk/test/tools/llvm-profdata/raw-64-bits-le.test Sat Mar 22 22:38:12 2014
@@ -0,0 +1,42 @@
+RUN: printf '\201rforpl\377' > %t
+RUN: printf '\1\0\0\0\0\0\0\0' >> %t
+RUN: printf '\2\0\0\0\0\0\0\0' >> %t
+RUN: printf '\3\0\0\0\0\0\0\0' >> %t
+RUN: printf '\6\0\0\0\0\0\0\0' >> %t
+RUN: printf '\0\0\4\0\1\0\0\0' >> %t
+RUN: printf '\0\0\4\0\2\0\0\0' >> %t
+
+RUN: printf '\3\0\0\0' >> %t
+RUN: printf '\1\0\0\0' >> %t
+RUN: printf '\1\0\0\0\0\0\0\0' >> %t
+RUN: printf '\0\0\4\0\2\0\0\0' >> %t
+RUN: printf '\0\0\4\0\1\0\0\0' >> %t
+
+RUN: printf '\03\0\0\0' >> %t
+RUN: printf '\02\0\0\0' >> %t
+RUN: printf '\02\0\0\0\0\0\0\0' >> %t
+RUN: printf '\03\0\4\0\2\0\0\0' >> %t
+RUN: printf '\10\0\4\0\1\0\0\0' >> %t
+
+RUN: printf '\023\0\0\0\0\0\0\0' >> %t
+RUN: printf '\067\0\0\0\0\0\0\0' >> %t
+RUN: printf '\101\0\0\0\0\0\0\0' >> %t
+RUN: printf 'foobar' >> %t
+
+RUN: llvm-profdata show %t -all-functions -counts | FileCheck %s
+
+CHECK: Counters:
+CHECK:   foo:
+CHECK:     Hash: 0x0000000000000001
+CHECK:     Counters: 1
+CHECK:     Function count: 19
+CHECK:     Block counts: []
+CHECK:   bar:
+CHECK:     Hash: 0x0000000000000002
+CHECK:     Counters: 2
+CHECK:     Function count: 55
+CHECK:     Block counts: [65]
+CHECK: Functions shown: 2
+CHECK: Total functions: 2
+CHECK: Maximum function count: 55
+CHECK: Maximum internal block count: 65





More information about the llvm-commits mailing list