From: Snehasish Kumar Date: Mon, 13 Mar 2023 20:11:58 +0000 (+0000) Subject: [memprof] Record BuildIDs in the raw profile. X-Git-Tag: upstream/17.0.6~14838 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a1bbf5ac3cbd1238c0ee8c5deae2b0c595663ac7;p=platform%2Fupstream%2Fllvm.git [memprof] Record BuildIDs in the raw profile. This patch adds support for recording BuildIds usng the sanitizer ListOfModules API. We add another entry to the SegmentEntry struct and change the memprof raw version. Reviewed By: tejohnson Differential Revision: https://reviews.llvm.org/D145190 --- diff --git a/clang/test/CodeGen/Inputs/memprof.exe b/clang/test/CodeGen/Inputs/memprof.exe index ad7a041..bde5f3e 100755 Binary files a/clang/test/CodeGen/Inputs/memprof.exe and b/clang/test/CodeGen/Inputs/memprof.exe differ diff --git a/clang/test/CodeGen/Inputs/memprof.memprofraw b/clang/test/CodeGen/Inputs/memprof.memprofraw index e64214a..a7aa405 100644 Binary files a/clang/test/CodeGen/Inputs/memprof.memprofraw and b/clang/test/CodeGen/Inputs/memprof.memprofraw differ diff --git a/compiler-rt/include/profile/MemProfData.inc b/compiler-rt/include/profile/MemProfData.inc index c533073..b82a4ba 100644 --- a/compiler-rt/include/profile/MemProfData.inc +++ b/compiler-rt/include/profile/MemProfData.inc @@ -19,6 +19,7 @@ * synced up. * \*===----------------------------------------------------------------------===*/ +#include #ifdef _MSC_VER #define PACKED(...) __pragma(pack(push,1)) __VA_ARGS__ __pragma(pack(pop)) @@ -32,7 +33,9 @@ (uint64_t)'o' << 24 | (uint64_t)'f' << 16 | (uint64_t)'r' << 8 | (uint64_t)129) // The version number of the raw binary format. -#define MEMPROF_RAW_VERSION 2ULL +#define MEMPROF_RAW_VERSION 3ULL + +#define MEMPROF_BUILDID_MAX_SIZE 32ULL namespace llvm { namespace memprof { @@ -46,37 +49,40 @@ PACKED(struct Header { uint64_t StackOffset; }); - // A struct describing the information necessary to describe a /proc/maps // segment entry for a particular binary/library identified by its build id. PACKED(struct SegmentEntry { uint64_t Start; uint64_t End; uint64_t Offset; - // This field is unused until sanitizer procmaps support for build ids for - // Linux-Elf is implemented. - uint8_t BuildId[32] = {0}; + uint64_t BuildIdSize; + uint8_t BuildId[MEMPROF_BUILDID_MAX_SIZE] = {0}; - SegmentEntry(uint64_t S, uint64_t E, uint64_t O) : - Start(S), End(E), Offset(O) {} + // This constructor is only used in tests so don't set the BuildId. + SegmentEntry(uint64_t S, uint64_t E, uint64_t O) + : Start(S), End(E), Offset(O), BuildIdSize(0) {} SegmentEntry(const SegmentEntry& S) { Start = S.Start; End = S.End; Offset = S.Offset; + BuildIdSize = S.BuildIdSize; + memcpy(BuildId, S.BuildId, S.BuildIdSize); } SegmentEntry& operator=(const SegmentEntry& S) { Start = S.Start; End = S.End; Offset = S.Offset; + BuildIdSize = S.BuildIdSize; + memcpy(BuildId, S.BuildId, S.BuildIdSize); return *this; } bool operator==(const SegmentEntry& S) const { - return Start == S.Start && - End == S.End && - Offset == S.Offset; + return Start == S.Start && End == S.End && Offset == S.Offset && + BuildIdSize == S.BuildIdSize && + memcmp(BuildId, S.BuildId, S.BuildIdSize) == 0; } }); diff --git a/compiler-rt/lib/memprof/memprof_allocator.cpp b/compiler-rt/lib/memprof/memprof_allocator.cpp index 6e3fa7f..51c3a66 100644 --- a/compiler-rt/lib/memprof/memprof_allocator.cpp +++ b/compiler-rt/lib/memprof/memprof_allocator.cpp @@ -23,11 +23,11 @@ #include "sanitizer_common/sanitizer_allocator_checks.h" #include "sanitizer_common/sanitizer_allocator_interface.h" #include "sanitizer_common/sanitizer_allocator_report.h" +#include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_errno.h" #include "sanitizer_common/sanitizer_file.h" #include "sanitizer_common/sanitizer_flags.h" #include "sanitizer_common/sanitizer_internal_defs.h" -#include "sanitizer_common/sanitizer_procmaps.h" #include "sanitizer_common/sanitizer_stackdepot.h" #include @@ -295,8 +295,10 @@ struct Allocator { // memprof_rawprofile.h. char *Buffer = nullptr; - MemoryMappingLayout Layout(/*cache_enabled=*/true); - u64 BytesSerialized = SerializeToRawProfile(MIBMap, Layout, Buffer); + __sanitizer::ListOfModules List; + List.init(); + ArrayRef Modules(List.begin(), List.end()); + u64 BytesSerialized = SerializeToRawProfile(MIBMap, Modules, Buffer); CHECK(Buffer && BytesSerialized && "could not serialize to buffer"); report_file.Write(Buffer, BytesSerialized); } diff --git a/compiler-rt/lib/memprof/memprof_rawprofile.cpp b/compiler-rt/lib/memprof/memprof_rawprofile.cpp index 88f3c34..1a65fbb 100644 --- a/compiler-rt/lib/memprof/memprof_rawprofile.cpp +++ b/compiler-rt/lib/memprof/memprof_rawprofile.cpp @@ -33,12 +33,14 @@ void RecordStackId(const uptr Key, UNUSED LockedMemInfoBlock *const &MIB, } } // namespace -u64 SegmentSizeBytes(MemoryMappingLayoutBase &Layout) { +u64 SegmentSizeBytes(ArrayRef Modules) { u64 NumSegmentsToRecord = 0; - MemoryMappedSegment segment; - for (Layout.Reset(); Layout.Next(&segment);) - if (segment.IsReadable() && segment.IsExecutable()) - NumSegmentsToRecord++; + for (const auto &Module : Modules) { + for (const auto &Segment : Module.ranges()) { + if (Segment.executable) + NumSegmentsToRecord++; + } + } return sizeof(u64) // A header which stores the number of records. + sizeof(SegmentEntry) * NumSegmentsToRecord; @@ -51,28 +53,31 @@ u64 SegmentSizeBytes(MemoryMappingLayoutBase &Layout) { // Start // End // Offset -// BuildID 32B +// UuidSize +// Uuid 32B // ---------- // ... -void SerializeSegmentsToBuffer(MemoryMappingLayoutBase &Layout, +void SerializeSegmentsToBuffer(ArrayRef Modules, const u64 ExpectedNumBytes, char *&Buffer) { char *Ptr = Buffer; // Reserve space for the final count. Ptr += sizeof(u64); u64 NumSegmentsRecorded = 0; - MemoryMappedSegment segment; - - for (Layout.Reset(); Layout.Next(&segment);) { - if (segment.IsReadable() && segment.IsExecutable()) { - // TODO: Record segment.uuid when it is implemented for Linux-Elf. - SegmentEntry Entry(segment.start, segment.end, segment.offset); - memcpy(Ptr, &Entry, sizeof(SegmentEntry)); - Ptr += sizeof(SegmentEntry); - NumSegmentsRecorded++; + + for (const auto &Module : Modules) { + for (const auto &Segment : Module.ranges()) { + if (Segment.executable) { + SegmentEntry Entry(Segment.beg, Segment.end, Module.base_address()); + CHECK(Module.uuid_size() <= MEMPROF_BUILDID_MAX_SIZE); + Entry.BuildIdSize = Module.uuid_size(); + memcpy(Entry.BuildId, Module.uuid(), Module.uuid_size()); + memcpy(Ptr, &Entry, sizeof(SegmentEntry)); + Ptr += sizeof(SegmentEntry); + NumSegmentsRecorded++; + } } } - // Store the number of segments we recorded in the space we reserved. *((u64 *)Buffer) = NumSegmentsRecorded; CHECK(ExpectedNumBytes >= static_cast(Ptr - Buffer) && @@ -198,11 +203,11 @@ void SerializeMIBInfoToBuffer(MIBMapTy &MIBMap, const Vector &StackIds, // ---------- // Optional Padding Bytes // ... -u64 SerializeToRawProfile(MIBMapTy &MIBMap, MemoryMappingLayoutBase &Layout, +u64 SerializeToRawProfile(MIBMapTy &MIBMap, ArrayRef Modules, char *&Buffer) { // Each section size is rounded up to 8b since the first entry in each section // is a u64 which holds the number of entries in the section by convention. - const u64 NumSegmentBytes = RoundUpTo(SegmentSizeBytes(Layout), 8); + const u64 NumSegmentBytes = RoundUpTo(SegmentSizeBytes(Modules), 8); Vector StackIds; MIBMap.ForEach(RecordStackId, reinterpret_cast(&StackIds)); @@ -232,7 +237,7 @@ u64 SerializeToRawProfile(MIBMapTy &MIBMap, MemoryMappingLayoutBase &Layout, sizeof(Header) + NumSegmentBytes + NumMIBInfoBytes}; Ptr = WriteBytes(header, Ptr); - SerializeSegmentsToBuffer(Layout, NumSegmentBytes, Ptr); + SerializeSegmentsToBuffer(Modules, NumSegmentBytes, Ptr); Ptr += NumSegmentBytes; SerializeMIBInfoToBuffer(MIBMap, StackIds, NumMIBInfoBytes, Ptr); diff --git a/compiler-rt/lib/memprof/memprof_rawprofile.h b/compiler-rt/lib/memprof/memprof_rawprofile.h index 575104e..a4e9fd4 100644 --- a/compiler-rt/lib/memprof/memprof_rawprofile.h +++ b/compiler-rt/lib/memprof/memprof_rawprofile.h @@ -2,12 +2,12 @@ #define MEMPROF_RAWPROFILE_H_ #include "memprof_mibmap.h" -#include "sanitizer_common/sanitizer_procmaps.h" +#include "sanitizer_common/sanitizer_common.h" namespace __memprof { // Serialize the in-memory representation of the memprof profile to the raw // binary format. The format itself is documented memprof_rawprofile.cpp. -u64 SerializeToRawProfile(MIBMapTy &BlockCache, MemoryMappingLayoutBase &Layout, +u64 SerializeToRawProfile(MIBMapTy &BlockCache, ArrayRef Modules, char *&Buffer); } // namespace __memprof diff --git a/compiler-rt/lib/memprof/tests/rawprofile.cpp b/compiler-rt/lib/memprof/tests/rawprofile.cpp index 7f6398d..3c7372a 100644 --- a/compiler-rt/lib/memprof/tests/rawprofile.cpp +++ b/compiler-rt/lib/memprof/tests/rawprofile.cpp @@ -15,22 +15,9 @@ namespace { using ::__memprof::MIBMapTy; using ::__memprof::SerializeToRawProfile; -using ::__sanitizer::MemoryMappedSegment; -using ::__sanitizer::MemoryMappingLayoutBase; using ::__sanitizer::StackDepotPut; using ::__sanitizer::StackTrace; using ::llvm::memprof::MemInfoBlock; -using ::testing::_; -using ::testing::Action; -using ::testing::DoAll; -using ::testing::Return; -using ::testing::SetArgPointee; - -class MockMemoryMappingLayout final : public MemoryMappingLayoutBase { -public: - MOCK_METHOD(bool, Next, (MemoryMappedSegment *), (override)); - MOCK_METHOD(void, Reset, (), (override)); -}; uint64_t PopulateFakeMap(const MemInfoBlock &FakeMIB, uint64_t StackPCBegin, MIBMapTy &FakeMap) { @@ -56,26 +43,13 @@ template T Read(char *&Buffer) { } TEST(MemProf, Basic) { - MockMemoryMappingLayout Layout; - MemoryMappedSegment FakeSegment; - memset(&FakeSegment, 0, sizeof(FakeSegment)); - FakeSegment.start = 0x10; - FakeSegment.end = 0x20; - FakeSegment.offset = 0x10; - uint8_t uuid[__sanitizer::kModuleUUIDSize] = {0xC, 0x0, 0xF, 0xF, 0xE, 0xE}; - memcpy(FakeSegment.uuid, uuid, __sanitizer::kModuleUUIDSize); - FakeSegment.protection = - __sanitizer::kProtectionExecute | __sanitizer::kProtectionRead; - - const Action SetSegment = - DoAll(SetArgPointee<0>(FakeSegment), Return(true)); - EXPECT_CALL(Layout, Next(_)) - .WillOnce(SetSegment) - .WillOnce(Return(false)) - .WillOnce(SetSegment) - .WillRepeatedly(Return(false)); - - EXPECT_CALL(Layout, Reset).Times(2); + __sanitizer::LoadedModule FakeModule; + FakeModule.addAddressRange(/*begin=*/0x10, /*end=*/0x20, /*executable=*/true, + /*writable=*/false, /*name=*/""); + const char uuid[MEMPROF_BUILDID_MAX_SIZE] = {0xC, 0x0, 0xF, 0xF, 0xE, 0xE}; + FakeModule.setUuid(uuid, MEMPROF_BUILDID_MAX_SIZE); + __sanitizer::ArrayRef<__sanitizer::LoadedModule> Modules(&FakeModule, + (&FakeModule) + 1); MIBMapTy FakeMap; MemInfoBlock FakeMIB; @@ -90,7 +64,7 @@ TEST(MemProf, Basic) { FakeIds[1] = PopulateFakeMap(FakeMIB, /*StackPCBegin=*/3, FakeMap); char *Ptr = nullptr; - uint64_t NumBytes = SerializeToRawProfile(FakeMap, Layout, Ptr); + uint64_t NumBytes = SerializeToRawProfile(FakeMap, Modules, Ptr); const char *Buffer = Ptr; ASSERT_GT(NumBytes, 0ULL); @@ -111,16 +85,16 @@ TEST(MemProf, Basic) { // Should be equal to the size of the raw profile header. EXPECT_EQ(SegmentOffset, 48ULL); - // We expect only 1 segment entry, 8b for the count and 56b for SegmentEntry + // We expect only 1 segment entry, 8b for the count and 64b for SegmentEntry // in memprof_rawprofile.cpp. - EXPECT_EQ(MIBOffset - SegmentOffset, 64ULL); + EXPECT_EQ(MIBOffset - SegmentOffset, 72ULL); - EXPECT_EQ(MIBOffset, 112ULL); + EXPECT_EQ(MIBOffset, 120ULL); // We expect 2 mib entry, 8b for the count and sizeof(uint64_t) + // sizeof(MemInfoBlock) contains stack id + MeminfoBlock. EXPECT_EQ(StackOffset - MIBOffset, 8 + 2 * (8 + sizeof(MemInfoBlock))); - EXPECT_EQ(StackOffset, 336ULL); + EXPECT_EQ(StackOffset, 408ULL); // We expect 2 stack entries, with 5 frames - 8b for total count, // 2 * (8b for id, 8b for frame count and 5*8b for fake frames). // Since this is the last section, there may be additional padding at the end @@ -128,16 +102,15 @@ TEST(MemProf, Basic) { EXPECT_GE(TotalSize - StackOffset, 8ULL + 2 * (8 + 8 + 5 * 8)); // ============= Check contents. - // The Uuid field is not yet populated on Linux-Elf by the sanitizer procmaps - // library, so we expect it to be filled with 0 for now. - unsigned char ExpectedSegmentBytes[64] = { - 0x01, 0, 0, 0, 0, 0, 0, 0, // Number of entries - 0x10, 0, 0, 0, 0, 0, 0, 0, // Start - 0x20, 0, 0, 0, 0, 0, 0, 0, // End - 0x10, 0, 0, 0, 0, 0, 0, 0, // Offset - 0x0, // Uuid + unsigned char ExpectedSegmentBytes[72] = { + 0x01, 0, 0, 0, 0, 0, 0, 0, // Number of entries + 0x10, 0, 0, 0, 0, 0, 0, 0, // Start + 0x20, 0, 0, 0, 0, 0, 0, 0, // End + 0x0, 0, 0, 0, 0, 0, 0, 0, // Offset + 0x20, 0, 0, 0, 0, 0, 0, 0, // UuidSize + 0xC, 0x0, 0xF, 0xF, 0xE, 0xE // Uuid }; - EXPECT_EQ(memcmp(Buffer + SegmentOffset, ExpectedSegmentBytes, 64), 0); + EXPECT_EQ(memcmp(Buffer + SegmentOffset, ExpectedSegmentBytes, 72), 0); // Check that the number of entries is 2. EXPECT_EQ(*reinterpret_cast(Buffer + MIBOffset), 2ULL); @@ -193,5 +166,4 @@ TEST(MemProf, Basic) { sizeof(ExpectedStackBytes[1])), 0); } - } // namespace diff --git a/llvm/include/llvm/ProfileData/MemProfData.inc b/llvm/include/llvm/ProfileData/MemProfData.inc index c533073..b82a4ba 100644 --- a/llvm/include/llvm/ProfileData/MemProfData.inc +++ b/llvm/include/llvm/ProfileData/MemProfData.inc @@ -19,6 +19,7 @@ * synced up. * \*===----------------------------------------------------------------------===*/ +#include #ifdef _MSC_VER #define PACKED(...) __pragma(pack(push,1)) __VA_ARGS__ __pragma(pack(pop)) @@ -32,7 +33,9 @@ (uint64_t)'o' << 24 | (uint64_t)'f' << 16 | (uint64_t)'r' << 8 | (uint64_t)129) // The version number of the raw binary format. -#define MEMPROF_RAW_VERSION 2ULL +#define MEMPROF_RAW_VERSION 3ULL + +#define MEMPROF_BUILDID_MAX_SIZE 32ULL namespace llvm { namespace memprof { @@ -46,37 +49,40 @@ PACKED(struct Header { uint64_t StackOffset; }); - // A struct describing the information necessary to describe a /proc/maps // segment entry for a particular binary/library identified by its build id. PACKED(struct SegmentEntry { uint64_t Start; uint64_t End; uint64_t Offset; - // This field is unused until sanitizer procmaps support for build ids for - // Linux-Elf is implemented. - uint8_t BuildId[32] = {0}; + uint64_t BuildIdSize; + uint8_t BuildId[MEMPROF_BUILDID_MAX_SIZE] = {0}; - SegmentEntry(uint64_t S, uint64_t E, uint64_t O) : - Start(S), End(E), Offset(O) {} + // This constructor is only used in tests so don't set the BuildId. + SegmentEntry(uint64_t S, uint64_t E, uint64_t O) + : Start(S), End(E), Offset(O), BuildIdSize(0) {} SegmentEntry(const SegmentEntry& S) { Start = S.Start; End = S.End; Offset = S.Offset; + BuildIdSize = S.BuildIdSize; + memcpy(BuildId, S.BuildId, S.BuildIdSize); } SegmentEntry& operator=(const SegmentEntry& S) { Start = S.Start; End = S.End; Offset = S.Offset; + BuildIdSize = S.BuildIdSize; + memcpy(BuildId, S.BuildId, S.BuildIdSize); return *this; } bool operator==(const SegmentEntry& S) const { - return Start == S.Start && - End == S.End && - Offset == S.Offset; + return Start == S.Start && End == S.End && Offset == S.Offset && + BuildIdSize == S.BuildIdSize && + memcmp(BuildId, S.BuildId, S.BuildIdSize) == 0; } }); diff --git a/llvm/lib/ProfileData/RawMemProfReader.cpp b/llvm/lib/ProfileData/RawMemProfReader.cpp index 958bbc5..dd62a2f 100644 --- a/llvm/lib/ProfileData/RawMemProfReader.cpp +++ b/llvm/lib/ProfileData/RawMemProfReader.cpp @@ -158,15 +158,13 @@ bool isRuntimePath(const StringRef Path) { } std::string getBuildIdString(const SegmentEntry &Entry) { - constexpr size_t Size = sizeof(Entry.BuildId) / sizeof(uint8_t); - constexpr uint8_t Zeros[Size] = {0}; // If the build id is unset print a helpful string instead of all zeros. - if (memcmp(Entry.BuildId, Zeros, Size) == 0) + if (Entry.BuildIdSize == 0) return ""; std::string Str; raw_string_ostream OS(Str); - for (size_t I = 0; I < Size; I++) { + for (size_t I = 0; I < Entry.BuildIdSize; I++) { OS << format_hex_no_prefix(Entry.BuildId[I], 2); } return OS.str(); diff --git a/llvm/test/Transforms/PGOProfile/Inputs/memprof.exe b/llvm/test/Transforms/PGOProfile/Inputs/memprof.exe index 0ed4016..b10c2f9 100755 Binary files a/llvm/test/Transforms/PGOProfile/Inputs/memprof.exe and b/llvm/test/Transforms/PGOProfile/Inputs/memprof.exe differ diff --git a/llvm/test/Transforms/PGOProfile/Inputs/memprof.memprofraw b/llvm/test/Transforms/PGOProfile/Inputs/memprof.memprofraw index 7511ca7..790249a 100644 Binary files a/llvm/test/Transforms/PGOProfile/Inputs/memprof.memprofraw and b/llvm/test/Transforms/PGOProfile/Inputs/memprof.memprofraw differ diff --git a/llvm/test/Transforms/PGOProfile/Inputs/memprof_pgo.profraw b/llvm/test/Transforms/PGOProfile/Inputs/memprof_pgo.profraw index 04330fe..d5160e7 100644 Binary files a/llvm/test/Transforms/PGOProfile/Inputs/memprof_pgo.profraw and b/llvm/test/Transforms/PGOProfile/Inputs/memprof_pgo.profraw differ diff --git a/llvm/test/tools/llvm-profdata/Inputs/basic.memprofexe b/llvm/test/tools/llvm-profdata/Inputs/basic.memprofexe index d321a05..d03894b 100755 Binary files a/llvm/test/tools/llvm-profdata/Inputs/basic.memprofexe and b/llvm/test/tools/llvm-profdata/Inputs/basic.memprofexe differ diff --git a/llvm/test/tools/llvm-profdata/Inputs/basic.memprofraw b/llvm/test/tools/llvm-profdata/Inputs/basic.memprofraw index 612eaa0..62b7d29 100644 Binary files a/llvm/test/tools/llvm-profdata/Inputs/basic.memprofraw and b/llvm/test/tools/llvm-profdata/Inputs/basic.memprofraw differ diff --git a/llvm/test/tools/llvm-profdata/Inputs/buildid.memprofexe b/llvm/test/tools/llvm-profdata/Inputs/buildid.memprofexe new file mode 100755 index 0000000..5687d06 Binary files /dev/null and b/llvm/test/tools/llvm-profdata/Inputs/buildid.memprofexe differ diff --git a/llvm/test/tools/llvm-profdata/Inputs/buildid.memprofraw b/llvm/test/tools/llvm-profdata/Inputs/buildid.memprofraw new file mode 100644 index 0000000..43f9ca9 Binary files /dev/null and b/llvm/test/tools/llvm-profdata/Inputs/buildid.memprofraw differ diff --git a/llvm/test/tools/llvm-profdata/Inputs/inline.memprofexe b/llvm/test/tools/llvm-profdata/Inputs/inline.memprofexe index 6a5594eb..766d2c47 100755 Binary files a/llvm/test/tools/llvm-profdata/Inputs/inline.memprofexe and b/llvm/test/tools/llvm-profdata/Inputs/inline.memprofexe differ diff --git a/llvm/test/tools/llvm-profdata/Inputs/inline.memprofraw b/llvm/test/tools/llvm-profdata/Inputs/inline.memprofraw index 8e0ad19..26254ae 100644 Binary files a/llvm/test/tools/llvm-profdata/Inputs/inline.memprofraw and b/llvm/test/tools/llvm-profdata/Inputs/inline.memprofraw differ diff --git a/llvm/test/tools/llvm-profdata/Inputs/multi.memprofexe b/llvm/test/tools/llvm-profdata/Inputs/multi.memprofexe index 02100d0..d5c3ec6 100755 Binary files a/llvm/test/tools/llvm-profdata/Inputs/multi.memprofexe and b/llvm/test/tools/llvm-profdata/Inputs/multi.memprofexe differ diff --git a/llvm/test/tools/llvm-profdata/Inputs/multi.memprofraw b/llvm/test/tools/llvm-profdata/Inputs/multi.memprofraw index 8756698..a1018aa 100644 Binary files a/llvm/test/tools/llvm-profdata/Inputs/multi.memprofraw and b/llvm/test/tools/llvm-profdata/Inputs/multi.memprofraw differ diff --git a/llvm/test/tools/llvm-profdata/Inputs/pic.memprofexe b/llvm/test/tools/llvm-profdata/Inputs/pic.memprofexe index 900a453..d854186 100755 Binary files a/llvm/test/tools/llvm-profdata/Inputs/pic.memprofexe and b/llvm/test/tools/llvm-profdata/Inputs/pic.memprofexe differ diff --git a/llvm/test/tools/llvm-profdata/Inputs/pic.memprofraw b/llvm/test/tools/llvm-profdata/Inputs/pic.memprofraw index b56b9a9..992022f 100644 Binary files a/llvm/test/tools/llvm-profdata/Inputs/pic.memprofraw and b/llvm/test/tools/llvm-profdata/Inputs/pic.memprofraw differ diff --git a/llvm/test/tools/llvm-profdata/Inputs/update_memprof_inputs.sh b/llvm/test/tools/llvm-profdata/Inputs/update_memprof_inputs.sh index e709254..5365a0b 100755 --- a/llvm/test/tools/llvm-profdata/Inputs/update_memprof_inputs.sh +++ b/llvm/test/tools/llvm-profdata/Inputs/update_memprof_inputs.sh @@ -72,6 +72,7 @@ INPUTS["basic"]="BASIC" INPUTS["inline"]="INLINE" INPUTS["multi"]="MULTI" INPUTS["pic"]="BASIC;-pie" +INPUTS["buildid"]="BASIC;-Wl,-build-id=sha1" for name in "${!INPUTS[@]}"; do IFS=";" read -r src flags <<< "${INPUTS[$name]}" diff --git a/llvm/test/tools/llvm-profdata/memprof-basic.test b/llvm/test/tools/llvm-profdata/memprof-basic.test index 2d17251..8eaa2fa 100644 --- a/llvm/test/tools/llvm-profdata/memprof-basic.test +++ b/llvm/test/tools/llvm-profdata/memprof-basic.test @@ -8,17 +8,17 @@ additional allocations which do not originate from the main binary are pruned. CHECK: MemprofProfile: CHECK-NEXT: Summary: -CHECK-NEXT: Version: 2 +CHECK-NEXT: Version: 3 CHECK-NEXT: NumSegments: {{[0-9]+}} CHECK-NEXT: NumMibInfo: 2 CHECK-NEXT: NumAllocFunctions: 1 CHECK-NEXT: NumStackOffsets: 2 CHECK-NEXT: Segments: CHECK-NEXT: - -CHECK-NEXT: BuildId: -CHECK-NEXT: Start: 0x{{[0-9]+}} -CHECK-NEXT: End: 0x{{[0-9]+}} -CHECK-NEXT: Offset: 0x{{[0-9]+}} +CHECK-NEXT: BuildId: {{[[:xdigit:]]+}} +CHECK-NEXT: Start: 0x{{[[:xdigit:]]+}} +CHECK-NEXT: End: 0x{{[[:xdigit:]]+}} +CHECK-NEXT: Offset: 0x{{[[:xdigit:]]+}} CHECK-NEXT: - CHECK: Records: diff --git a/llvm/test/tools/llvm-profdata/memprof-buildid.test b/llvm/test/tools/llvm-profdata/memprof-buildid.test new file mode 100644 index 0000000..9b055d3a --- /dev/null +++ b/llvm/test/tools/llvm-profdata/memprof-buildid.test @@ -0,0 +1,12 @@ +REQUIRES: x86_64-linux + +To update the inputs used below run Inputs/update_memprof_inputs.sh /path/to/updated/clang +RUN: llvm-readelf --notes %p/Inputs/buildid.memprofexe > %t1.txt +RUN: llvm-profdata show --memory %p/Inputs/buildid.memprofraw --profiled-binary %p/Inputs/buildid.memprofexe -o - > %t2.txt +RUN: cat %t1.txt %t2.txt | FileCheck %s + +COM: First extract the id from the llvm-readelf output. +CHECK: Build ID: [[ID:[[:xdigit:]]+]] + +COM: Then match it with the profdata output. +CHECK: BuildId: {{.*}}[[ID]] diff --git a/llvm/test/tools/llvm-profdata/memprof-inline.test b/llvm/test/tools/llvm-profdata/memprof-inline.test index 571beb9..dd842c0 100644 --- a/llvm/test/tools/llvm-profdata/memprof-inline.test +++ b/llvm/test/tools/llvm-profdata/memprof-inline.test @@ -5,17 +5,17 @@ RUN: llvm-profdata show --memory %p/Inputs/inline.memprofraw --profiled-binary % CHECK: MemprofProfile: CHECK-NEXT: Summary: -CHECK-NEXT: Version: 2 +CHECK-NEXT: Version: 3 CHECK-NEXT: NumSegments: {{[0-9]+}} CHECK-NEXT: NumMibInfo: 2 CHECK-NEXT: NumAllocFunctions: 2 CHECK-NEXT: NumStackOffsets: 1 CHECK-NEXT: Segments: CHECK-NEXT: - -CHECK-NEXT: BuildId: -CHECK-NEXT: Start: 0x{{[0-9]+}} -CHECK-NEXT: End: 0x{{[0-9]+}} -CHECK-NEXT: Offset: 0x{{[0-9]+}} +CHECK-NEXT: BuildId: {{[[:xdigit:]]+}} +CHECK-NEXT: Start: 0x{{[[:xdigit:]]+}} +CHECK-NEXT: End: 0x{{[[:xdigit:]]+}} +CHECK-NEXT: Offset: 0x{{[[:xdigit:]]+}} CHECK-NEXT: - CHECK: Records: diff --git a/llvm/test/tools/llvm-profdata/memprof-multi.test b/llvm/test/tools/llvm-profdata/memprof-multi.test index 5918a95..f3cdbd1 100644 --- a/llvm/test/tools/llvm-profdata/memprof-multi.test +++ b/llvm/test/tools/llvm-profdata/memprof-multi.test @@ -7,7 +7,7 @@ We expect 2 MIB entries, 1 each for the malloc calls in the program. CHECK: MemprofProfile: CHECK-NEXT: Summary: -CHECK-NEXT: Version: 2 +CHECK-NEXT: Version: 3 CHECK-NEXT: NumSegments: {{[0-9]+}} CHECK-NEXT: NumMibInfo: 2 CHECK-NEXT: NumAllocFunctions: 1