[llvm] 5706ee3 - [Object] Extract format-agnostic BBAddrMap decoder (#188435)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 9 18:33:28 PDT 2026
Author: Haohai Wen
Date: 2026-04-10T09:33:24+08:00
New Revision: 5706ee3d4d7d2cc50595ad080728c2c37ee95f26
URL: https://github.com/llvm/llvm-project/commit/5706ee3d4d7d2cc50595ad080728c2c37ee95f26
DIFF: https://github.com/llvm/llvm-project/commit/5706ee3d4d7d2cc50595ad080728c2c37ee95f26.diff
LOG: [Object] Extract format-agnostic BBAddrMap decoder (#188435)
[Object] Extract format-agnostic BBAddrMap decoder
This is part of patches to port BBAddrMap to COFF.
Move format-agnostic BBAddrMap decode logic out of ELF.cpp into
BBAddrMap.cpp, and expose a shared decodeBBAddrMapPayload helper in
BBAddrMap.h.
Keep ELF-specific steps (section decompression and relocation
translation) in ELF.cpp, and delegate payload decoding to the
shared helper.
Error messages in the decoder are updated to use the generic
"BB address map" instead of the ELF-specific "SHT_LLVM_BB_ADDR_MAP"
since the decoder is now shared across object formats.
This refactor prepares follow-up work to let COFF and ELF share
the same BBAddrMap decoding logic.
Added:
llvm/lib/Object/BBAddrMap.cpp
Modified:
llvm/include/llvm/Object/BBAddrMap.h
llvm/lib/Object/CMakeLists.txt
llvm/lib/Object/ELF.cpp
llvm/lib/Object/ELFObjectFile.cpp
llvm/test/tools/llvm-readobj/ELF/bb-addr-map-feature-warning.test
llvm/test/tools/llvm-readobj/ELF/bb-addr-map-pgo-analysis-map.test
llvm/test/tools/llvm-readobj/ELF/bb-addr-map-relocatable.test
llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test
llvm/tools/llvm-readobj/ELFDumper.cpp
llvm/unittests/Object/ELFObjectFileTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Object/BBAddrMap.h b/llvm/include/llvm/Object/BBAddrMap.h
index e2178e62e947c..49c9b431822e0 100644
--- a/llvm/include/llvm/Object/BBAddrMap.h
+++ b/llvm/include/llvm/Object/BBAddrMap.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/BlockFrequency.h"
#include "llvm/Support/BranchProbability.h"
+#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/UniqueBBID.h"
@@ -251,6 +252,37 @@ struct PGOAnalysisMap {
}
};
+/// Extracts addresses from a data stream.
+/// The base implementation reads the address directly.
+/// Subclasses can override to handle format-specific details such as relocation
+/// resolution.
+class AddressExtractor {
+ const DataExtractor &Data;
+
+public:
+ AddressExtractor(const DataExtractor &Data) : Data(Data) {}
+ virtual ~AddressExtractor() = default;
+
+ const DataExtractor &getDataExtractor() const { return Data; }
+
+ /// Extract and resolve an address at the current \p Cur position.
+ virtual Expected<uint64_t> extractAddress(DataExtractor::Cursor &Cur) {
+ uint64_t Address = Data.getAddress(Cur);
+ if (!Cur)
+ return Cur.takeError();
+ return Address;
+ }
+};
+
+/// Decodes one BB address map section payload.
+///
+/// \p Extractor provides address extraction and the underlying DataExtractor.
+/// \p PGOAnalyses if non-null, receives the decoded PGO analysis data. On
+/// error, \p PGOAnalyses may be partially populated.
+Expected<std::vector<BBAddrMap>>
+decodeBBAddrMapPayload(AddressExtractor &Extractor,
+ std::vector<PGOAnalysisMap> *PGOAnalyses = nullptr);
+
} // end namespace object.
} // end namespace llvm.
diff --git a/llvm/lib/Object/BBAddrMap.cpp b/llvm/lib/Object/BBAddrMap.cpp
new file mode 100644
index 0000000000000..39a5caca36012
--- /dev/null
+++ b/llvm/lib/Object/BBAddrMap.cpp
@@ -0,0 +1,215 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements shared utilities for basic-block address maps.
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Object/BBAddrMap.h"
+#include "llvm/Object/Error.h"
+
+using namespace llvm;
+using namespace object;
+
+namespace {
+
+// Helper to extract and decode the next ULEB128 value as an unsigned integer
+// type. Returns zero and sets ULEBSizeErr if the ULEB128 value exceeds the
+// destination type's limit.
+// Also returns zero if ULEBSizeErr is already in an error state.
+// ULEBSizeErr is an out variable if an error occurs.
+template <typename IntTy, std::enable_if_t<std::is_unsigned_v<IntTy>, int> = 0>
+static IntTy readULEB128As(const DataExtractor &Data,
+ DataExtractor::Cursor &Cur, Error &ULEBSizeErr) {
+ // Bail out and do not extract data if ULEBSizeErr is already set.
+ if (ULEBSizeErr)
+ return 0;
+ uint64_t Offset = Cur.tell();
+ uint64_t Value = Data.getULEB128(Cur);
+ if (Value > std::numeric_limits<IntTy>::max()) {
+ ULEBSizeErr = createError("ULEB128 value at offset 0x" +
+ Twine::utohexstr(Offset) + " exceeds UINT" +
+ Twine(std::numeric_limits<IntTy>::digits) +
+ "_MAX (0x" + Twine::utohexstr(Value) + ")");
+ return 0;
+ }
+ return static_cast<IntTy>(Value);
+}
+} // end anonymous namespace
+
+Expected<std::vector<BBAddrMap>>
+llvm::object::decodeBBAddrMapPayload(AddressExtractor &Extractor,
+ std::vector<PGOAnalysisMap> *PGOAnalyses) {
+ const DataExtractor &Data = Extractor.getDataExtractor();
+ std::vector<BBAddrMap> FunctionEntries;
+
+ DataExtractor::Cursor Cur(0);
+ Error ULEBSizeErr = Error::success();
+ Error MetadataDecodeErr = Error::success();
+
+ // Use int for Version to avoid Twine treating uint8_t as char.
+ int Version = 0;
+ uint16_t Feature = 0;
+ BBAddrMap::Features FeatEnable{};
+ while (!ULEBSizeErr && !MetadataDecodeErr && Cur &&
+ Cur.tell() < Data.getData().size()) {
+ Version = Data.getU8(Cur);
+ if (!Cur)
+ break;
+ if (Version < 2 || Version > 5)
+ return createError("unsupported BB address map version: " +
+ Twine(Version));
+ Feature = Version < 5 ? Data.getU8(Cur) : Data.getU16(Cur);
+ if (!Cur)
+ break;
+ auto FeatEnableOrErr = BBAddrMap::Features::decode(Feature);
+ if (!FeatEnableOrErr)
+ return FeatEnableOrErr.takeError();
+ FeatEnable = *FeatEnableOrErr;
+ if (FeatEnable.CallsiteEndOffsets && Version < 3)
+ return createError("version should be >= 3 for BB address map when "
+ "callsite offsets feature is enabled: version = " +
+ Twine(Version) + " feature = " + Twine(Feature));
+ if (FeatEnable.BBHash && Version < 4)
+ return createError("version should be >= 4 for BB address map when "
+ "basic block hash feature is enabled: version = " +
+ Twine(Version) + " feature = " + Twine(Feature));
+ if (FeatEnable.PostLinkCfg && Version < 5)
+ return createError("version should be >= 5 for BB address map when "
+ "post link cfg feature is enabled: version = " +
+ Twine(Version) + " feature = " + Twine(Feature));
+ uint32_t NumBlocksInBBRange = 0;
+ uint32_t NumBBRanges = 1;
+ uint64_t RangeBaseAddress = 0;
+ if (FeatEnable.MultiBBRange) {
+ NumBBRanges = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
+ if (!Cur || ULEBSizeErr)
+ break;
+ if (!NumBBRanges)
+ return createError("invalid zero number of BB ranges at offset " +
+ Twine::utohexstr(Cur.tell()));
+ } else {
+ auto AddressOrErr = Extractor.extractAddress(Cur);
+ if (!AddressOrErr)
+ return AddressOrErr.takeError();
+ RangeBaseAddress = *AddressOrErr;
+ NumBlocksInBBRange = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
+ }
+ std::vector<BBAddrMap::BBRangeEntry> BBRangeEntries;
+ uint32_t TotalNumBlocks = 0;
+ for (uint32_t BBRangeIndex = 0; BBRangeIndex < NumBBRanges;
+ ++BBRangeIndex) {
+ uint32_t PrevBBEndOffset = 0;
+ if (FeatEnable.MultiBBRange) {
+ auto AddressOrErr = Extractor.extractAddress(Cur);
+ if (!AddressOrErr)
+ return AddressOrErr.takeError();
+ RangeBaseAddress = *AddressOrErr;
+ NumBlocksInBBRange = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
+ }
+ std::vector<BBAddrMap::BBEntry> BBEntries;
+ if (!FeatEnable.OmitBBEntries) {
+ for (uint32_t BlockIndex = 0; !MetadataDecodeErr && !ULEBSizeErr &&
+ Cur && (BlockIndex < NumBlocksInBBRange);
+ ++BlockIndex) {
+ uint32_t ID = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
+ uint32_t Offset = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
+ // Read the callsite offsets.
+ uint32_t LastCallsiteEndOffset = 0;
+ SmallVector<uint32_t, 1> CallsiteEndOffsets;
+ if (FeatEnable.CallsiteEndOffsets) {
+ uint32_t NumCallsites =
+ readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
+ CallsiteEndOffsets.reserve(NumCallsites);
+ for (uint32_t CallsiteIndex = 0;
+ !ULEBSizeErr && Cur && (CallsiteIndex < NumCallsites);
+ ++CallsiteIndex) {
+ LastCallsiteEndOffset +=
+ readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
+ CallsiteEndOffsets.push_back(LastCallsiteEndOffset);
+ }
+ }
+ uint32_t Size = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr) +
+ LastCallsiteEndOffset;
+ uint32_t MD = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
+ uint64_t Hash = FeatEnable.BBHash ? Data.getU64(Cur) : 0;
+ Expected<BBAddrMap::BBEntry::Metadata> MetadataOrErr =
+ BBAddrMap::BBEntry::Metadata::decode(MD);
+ if (!MetadataOrErr) {
+ MetadataDecodeErr = MetadataOrErr.takeError();
+ break;
+ }
+ BBEntries.push_back({ID, Offset + PrevBBEndOffset, Size,
+ *MetadataOrErr, CallsiteEndOffsets, Hash});
+ PrevBBEndOffset += Offset + Size;
+ }
+ TotalNumBlocks += BBEntries.size();
+ }
+ BBRangeEntries.push_back({RangeBaseAddress, std::move(BBEntries)});
+ }
+ FunctionEntries.push_back({std::move(BBRangeEntries)});
+
+ if (PGOAnalyses || FeatEnable.hasPGOAnalysis()) {
+ // Function entry count
+ uint64_t FuncEntryCount =
+ FeatEnable.FuncEntryCount
+ ? readULEB128As<uint64_t>(Data, Cur, ULEBSizeErr)
+ : 0;
+
+ std::vector<PGOAnalysisMap::PGOBBEntry> PGOBBEntries;
+ for (uint32_t BlockIndex = 0;
+ FeatEnable.hasPGOAnalysisBBData() && !MetadataDecodeErr &&
+ !ULEBSizeErr && Cur && (BlockIndex < TotalNumBlocks);
+ ++BlockIndex) {
+ // Block frequency
+ uint64_t BBF = FeatEnable.BBFreq
+ ? readULEB128As<uint64_t>(Data, Cur, ULEBSizeErr)
+ : 0;
+ uint32_t PostLinkBBFreq =
+ FeatEnable.PostLinkCfg
+ ? readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr)
+ : 0;
+
+ // Branch probability
+ llvm::SmallVector<PGOAnalysisMap::PGOBBEntry::SuccessorEntry, 2>
+ Successors;
+ if (FeatEnable.BrProb) {
+ auto SuccCount = readULEB128As<uint64_t>(Data, Cur, ULEBSizeErr);
+ for (uint64_t I = 0; I < SuccCount; ++I) {
+ uint32_t BBID = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
+ uint32_t BrProb = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
+ uint32_t PostLinkFreq =
+ FeatEnable.PostLinkCfg
+ ? readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr)
+ : 0;
+
+ if (PGOAnalyses)
+ Successors.push_back(
+ {BBID, BranchProbability::getRaw(BrProb), PostLinkFreq});
+ }
+ }
+
+ if (PGOAnalyses)
+ PGOBBEntries.push_back(
+ {BlockFrequency(BBF), PostLinkBBFreq, std::move(Successors)});
+ }
+
+ if (PGOAnalyses)
+ PGOAnalyses->push_back(
+ {FuncEntryCount, std::move(PGOBBEntries), FeatEnable});
+ }
+ }
+
+ // Either Cur is in the error state, or we have an error in ULEBSizeErr or
+ // MetadataDecodeErr (but not both), but we join all errors here to be safe.
+ if (!Cur || ULEBSizeErr || MetadataDecodeErr)
+ return joinErrors(joinErrors(Cur.takeError(), std::move(ULEBSizeErr)),
+ std::move(MetadataDecodeErr));
+ return FunctionEntries;
+}
diff --git a/llvm/lib/Object/CMakeLists.txt b/llvm/lib/Object/CMakeLists.txt
index 0f6d2f7c59a5c..77a50f0d631d3 100644
--- a/llvm/lib/Object/CMakeLists.txt
+++ b/llvm/lib/Object/CMakeLists.txt
@@ -1,6 +1,7 @@
add_llvm_component_library(LLVMObject
Archive.cpp
ArchiveWriter.cpp
+ BBAddrMap.cpp
Binary.cpp
BuildID.cpp
COFFImportFile.cpp
diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp
index 660331d5da96d..4c49c8330d3f9 100644
--- a/llvm/lib/Object/ELF.cpp
+++ b/llvm/lib/Object/ELF.cpp
@@ -9,9 +9,9 @@
#include "llvm/Object/ELF.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/Object/BBAddrMap.h"
#include "llvm/Object/Decompressor.h"
#include "llvm/Support/Compiler.h"
-#include "llvm/Support/DataExtractor.h"
using namespace llvm;
using namespace object;
@@ -724,28 +724,72 @@ ELFFile<ELFT>::toMappedAddr(uint64_t VAddr, WarningHandler WarnHandler) const {
return base() + Offset;
}
-// Helper to extract and decode the next ULEB128 value as unsigned int.
-// Returns zero and sets ULEBSizeErr if the ULEB128 value exceeds the unsigned
-// int limit.
-// Also returns zero if ULEBSizeErr is already in an error state.
-// ULEBSizeErr is an out variable if an error occurs.
-template <typename IntTy, std::enable_if_t<std::is_unsigned_v<IntTy>, int> = 0>
-static IntTy readULEB128As(DataExtractor &Data, DataExtractor::Cursor &Cur,
- Error &ULEBSizeErr) {
- // Bail out and do not extract data if ULEBSizeErr is already set.
- if (ULEBSizeErr)
- return 0;
- uint64_t Offset = Cur.tell();
- uint64_t Value = Data.getULEB128(Cur);
- if (Value > std::numeric_limits<IntTy>::max()) {
- ULEBSizeErr = createError("ULEB128 value at offset 0x" +
- Twine::utohexstr(Offset) + " exceeds UINT" +
- Twine(std::numeric_limits<IntTy>::digits) +
- "_MAX (0x" + Twine::utohexstr(Value) + ")");
- return 0;
+/// Address extractor for ELF BB address map sections.
+class ELFBBAddrMapAddressExtractor : public AddressExtractor {
+ bool IsRelocatable;
+ // Maps the offset of each address field in the BB addr map section to the
+ // resolved function address (the relocation addend).
+ DenseMap<uint64_t, uint64_t> FunctionOffsetTranslations;
+
+ ELFBBAddrMapAddressExtractor(
+ const DataExtractor &Data, bool IsRelocatable,
+ DenseMap<uint64_t, uint64_t> FunctionOffsetTranslations)
+ : AddressExtractor(Data), IsRelocatable(IsRelocatable),
+ FunctionOffsetTranslations(std::move(FunctionOffsetTranslations)) {}
+
+public:
+ template <typename ELFT>
+ static Expected<ELFBBAddrMapAddressExtractor>
+ create(const DataExtractor &Data, const ELFFile<ELFT> &EF,
+ const typename ELFFile<ELFT>::Elf_Shdr &Sec,
+ const typename ELFFile<ELFT>::Elf_Shdr *RelaSec) {
+ bool IsRelocatable = EF.getHeader().e_type == ELF::ET_REL;
+
+ // Build relocation offset-to-addend map.
+ DenseMap<uint64_t, uint64_t> FunctionOffsetTranslations;
+ if (IsRelocatable && RelaSec) {
+ assert(RelaSec &&
+ "Can't read a SHT_LLVM_BB_ADDR_MAP section in a relocatable "
+ "object file without providing a relocation section.");
+ if (RelaSec->sh_type == ELF::SHT_CREL) {
+ Expected<typename ELFFile<ELFT>::RelsOrRelas> Relas =
+ EF.crels(*RelaSec);
+ if (!Relas)
+ return createError("unable to read CREL relocations for section " +
+ describe(EF, Sec) + ": " +
+ toString(Relas.takeError()));
+ for (typename ELFFile<ELFT>::Elf_Rela Rela : std::get<1>(*Relas))
+ FunctionOffsetTranslations[Rela.r_offset] = Rela.r_addend;
+ } else {
+ Expected<typename ELFFile<ELFT>::Elf_Rela_Range> Relas =
+ EF.relas(*RelaSec);
+ if (!Relas)
+ return createError("unable to read relocations for section " +
+ describe(EF, Sec) + ": " +
+ toString(Relas.takeError()));
+ for (typename ELFFile<ELFT>::Elf_Rela Rela : *Relas)
+ FunctionOffsetTranslations[Rela.r_offset] = Rela.r_addend;
+ }
+ }
+
+ return ELFBBAddrMapAddressExtractor(Data, IsRelocatable,
+ std::move(FunctionOffsetTranslations));
}
- return static_cast<IntTy>(Value);
-}
+
+ Expected<uint64_t> extractAddress(DataExtractor::Cursor &Cur) override {
+ uint64_t Offset = Cur.tell();
+ Expected<uint64_t> AddressOrErr = AddressExtractor::extractAddress(Cur);
+ if (!AddressOrErr)
+ return AddressOrErr.takeError();
+ if (!IsRelocatable)
+ return *AddressOrErr;
+ auto FOTIterator = FunctionOffsetTranslations.find(Offset);
+ if (FOTIterator == FunctionOffsetTranslations.end())
+ return createError("failed to get relocation data for offset: " +
+ Twine::utohexstr(Offset));
+ return FOTIterator->second;
+ }
+};
template <typename ELFT>
static Expected<std::vector<BBAddrMap>>
@@ -753,53 +797,12 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
const typename ELFFile<ELFT>::Elf_Shdr &Sec,
const typename ELFFile<ELFT>::Elf_Shdr *RelaSec,
std::vector<PGOAnalysisMap> *PGOAnalyses) {
- bool IsRelocatable = EF.getHeader().e_type == ELF::ET_REL;
-
- // This DenseMap maps the offset of each function (the location of the
- // reference to the function in the SHT_LLVM_BB_ADDR_MAP section) to the
- // addend (the location of the function in the text section).
- llvm::DenseMap<uint64_t, uint64_t> FunctionOffsetTranslations;
- if (IsRelocatable && RelaSec) {
- assert(RelaSec &&
- "Can't read a SHT_LLVM_BB_ADDR_MAP section in a relocatable "
- "object file without providing a relocation section.");
- if (RelaSec->sh_type == ELF::SHT_CREL) {
- Expected<typename ELFFile<ELFT>::RelsOrRelas> Relas = EF.crels(*RelaSec);
- if (!Relas)
- return createError("unable to read CREL relocations for section " +
- describe(EF, Sec) + ": " +
- toString(Relas.takeError()));
- for (typename ELFFile<ELFT>::Elf_Rela Rela : std::get<1>(*Relas)) {
- FunctionOffsetTranslations[Rela.r_offset] = Rela.r_addend;
- }
- } else {
- Expected<typename ELFFile<ELFT>::Elf_Rela_Range> Relas =
- EF.relas(*RelaSec);
- if (!Relas)
- return createError("unable to read relocations for section " +
- describe(EF, Sec) + ": " +
- toString(Relas.takeError()));
- for (typename ELFFile<ELFT>::Elf_Rela Rela : *Relas)
- FunctionOffsetTranslations[Rela.r_offset] = Rela.r_addend;
- }
- }
- auto GetAddressForRelocation =
- [&](uint64_t RelocationOffsetInSection) -> Expected<uint64_t> {
- auto FOTIterator =
- FunctionOffsetTranslations.find(RelocationOffsetInSection);
- if (FOTIterator == FunctionOffsetTranslations.end()) {
- return createError("failed to get relocation data for offset: " +
- Twine::utohexstr(RelocationOffsetInSection) +
- " in section " + describe(EF, Sec));
- }
- return FOTIterator->second;
- };
+ // Read and optionally decompress section contents.
Expected<ArrayRef<uint8_t>> ContentsOrErr = EF.getSectionContents(Sec);
if (!ContentsOrErr)
return ContentsOrErr.takeError();
ArrayRef<uint8_t> Content = *ContentsOrErr;
- // Decompress the section if needed.
std::unique_ptr<uint8_t[]> DecompressedContent;
if (Sec.sh_flags & llvm::ELF::SHF_COMPRESSED) {
Expected<StringRef> SectionNameOrErr = EF.getSectionName(Sec);
@@ -821,189 +824,15 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
DataExtractor Data(Content, EF.isLE(),
sizeof(typename ELFFile<ELFT>::uintX_t));
- std::vector<BBAddrMap> FunctionEntries;
-
- DataExtractor::Cursor Cur(0);
- Error ULEBSizeErr = Error::success();
- Error MetadataDecodeErr = Error::success();
-
- // Helper lambda to extract the (possibly relocatable) address stored at Cur.
- auto ExtractAddress = [&]() -> Expected<uint64_t> {
- uint64_t RelocationOffsetInSection = Cur.tell();
- uint64_t Address = Data.getAddress(Cur);
- if (!Cur)
- return Cur.takeError();
- if (!IsRelocatable)
- return Address;
- assert(Address == 0);
- Expected<uint64_t> AddressOrErr =
- GetAddressForRelocation(RelocationOffsetInSection);
- if (!AddressOrErr)
- return AddressOrErr.takeError();
- return *AddressOrErr;
- };
-
- uint8_t Version = 0;
- uint16_t Feature = 0;
- BBAddrMap::Features FeatEnable{};
- while (!ULEBSizeErr && !MetadataDecodeErr && Cur &&
- Cur.tell() < Content.size()) {
- Version = Data.getU8(Cur);
- if (!Cur)
- break;
- if (Version < 2 || Version > 5)
- return createError("unsupported SHT_LLVM_BB_ADDR_MAP version: " +
- Twine(static_cast<int>(Version)));
- Feature = Version < 5 ? Data.getU8(Cur) : Data.getU16(Cur);
- if (!Cur)
- break;
- auto FeatEnableOrErr = BBAddrMap::Features::decode(Feature);
- if (!FeatEnableOrErr)
- return FeatEnableOrErr.takeError();
- FeatEnable = *FeatEnableOrErr;
- if (FeatEnable.CallsiteEndOffsets && Version < 3)
- return createError("version should be >= 3 for SHT_LLVM_BB_ADDR_MAP when "
- "callsite offsets feature is enabled: version = " +
- Twine(static_cast<int>(Version)) +
- " feature = " + Twine(static_cast<int>(Feature)));
- if (FeatEnable.BBHash && Version < 4)
- return createError("version should be >= 4 for SHT_LLVM_BB_ADDR_MAP when "
- "basic block hash feature is enabled: version = " +
- Twine(static_cast<int>(Version)) +
- " feature = " + Twine(static_cast<int>(Feature)));
- if (FeatEnable.PostLinkCfg && Version < 5)
- return createError("version should be >= 5 for SHT_LLVM_BB_ADDR_MAP when "
- "post link cfg feature is enabled: version = " +
- Twine(static_cast<int>(Version)) +
- " feature = " + Twine(static_cast<int>(Feature)));
- uint32_t NumBlocksInBBRange = 0;
- uint32_t NumBBRanges = 1;
- uint64_t RangeBaseAddress = 0;
- if (FeatEnable.MultiBBRange) {
- NumBBRanges = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
- if (!Cur || ULEBSizeErr)
- break;
- if (!NumBBRanges)
- return createError("invalid zero number of BB ranges at offset " +
- Twine::utohexstr(Cur.tell()) + " in " +
- describe(EF, Sec));
- } else {
- auto AddressOrErr = ExtractAddress();
- if (!AddressOrErr)
- return AddressOrErr.takeError();
- RangeBaseAddress = *AddressOrErr;
- NumBlocksInBBRange = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
- }
- std::vector<BBAddrMap::BBRangeEntry> BBRangeEntries;
- uint32_t TotalNumBlocks = 0;
- for (uint32_t BBRangeIndex = 0; BBRangeIndex < NumBBRanges;
- ++BBRangeIndex) {
- uint32_t PrevBBEndOffset = 0;
- if (FeatEnable.MultiBBRange) {
- auto AddressOrErr = ExtractAddress();
- if (!AddressOrErr)
- return AddressOrErr.takeError();
- RangeBaseAddress = *AddressOrErr;
- NumBlocksInBBRange = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
- }
- std::vector<BBAddrMap::BBEntry> BBEntries;
- if (!FeatEnable.OmitBBEntries) {
- for (uint32_t BlockIndex = 0; !MetadataDecodeErr && !ULEBSizeErr &&
- Cur && (BlockIndex < NumBlocksInBBRange);
- ++BlockIndex) {
- uint32_t ID = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
- uint32_t Offset = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
- // Read the callsite offsets.
- uint32_t LastCallsiteEndOffset = 0;
- SmallVector<uint32_t, 1> CallsiteEndOffsets;
- if (FeatEnable.CallsiteEndOffsets) {
- uint32_t NumCallsites =
- readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
- CallsiteEndOffsets.reserve(NumCallsites);
- for (uint32_t CallsiteIndex = 0;
- !ULEBSizeErr && Cur && (CallsiteIndex < NumCallsites);
- ++CallsiteIndex) {
- LastCallsiteEndOffset +=
- readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
- CallsiteEndOffsets.push_back(LastCallsiteEndOffset);
- }
- }
- uint32_t Size = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr) +
- LastCallsiteEndOffset;
- uint32_t MD = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
- uint64_t Hash = FeatEnable.BBHash ? Data.getU64(Cur) : 0;
- Expected<BBAddrMap::BBEntry::Metadata> MetadataOrErr =
- BBAddrMap::BBEntry::Metadata::decode(MD);
- if (!MetadataOrErr) {
- MetadataDecodeErr = MetadataOrErr.takeError();
- break;
- }
- BBEntries.push_back({ID, Offset + PrevBBEndOffset, Size,
- *MetadataOrErr, CallsiteEndOffsets, Hash});
- PrevBBEndOffset += Offset + Size;
- }
- TotalNumBlocks += BBEntries.size();
- }
- BBRangeEntries.push_back({RangeBaseAddress, std::move(BBEntries)});
- }
- FunctionEntries.push_back({std::move(BBRangeEntries)});
-
- if (PGOAnalyses || FeatEnable.hasPGOAnalysis()) {
- // Function entry count
- uint64_t FuncEntryCount =
- FeatEnable.FuncEntryCount
- ? readULEB128As<uint64_t>(Data, Cur, ULEBSizeErr)
- : 0;
-
- std::vector<PGOAnalysisMap::PGOBBEntry> PGOBBEntries;
- for (uint32_t BlockIndex = 0;
- FeatEnable.hasPGOAnalysisBBData() && !MetadataDecodeErr &&
- !ULEBSizeErr && Cur && (BlockIndex < TotalNumBlocks);
- ++BlockIndex) {
- // Block frequency
- uint64_t BBF = FeatEnable.BBFreq
- ? readULEB128As<uint64_t>(Data, Cur, ULEBSizeErr)
- : 0;
- uint32_t PostLinkBBFreq =
- FeatEnable.PostLinkCfg
- ? readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr)
- : 0;
-
- // Branch probability
- llvm::SmallVector<PGOAnalysisMap::PGOBBEntry::SuccessorEntry, 2>
- Successors;
- if (FeatEnable.BrProb) {
- auto SuccCount = readULEB128As<uint64_t>(Data, Cur, ULEBSizeErr);
- for (uint64_t I = 0; I < SuccCount; ++I) {
- uint32_t BBID = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
- uint32_t BrProb = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
- uint32_t PostLinkFreq =
- FeatEnable.PostLinkCfg
- ? readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr)
- : 0;
-
- if (PGOAnalyses)
- Successors.push_back(
- {BBID, BranchProbability::getRaw(BrProb), PostLinkFreq});
- }
- }
-
- if (PGOAnalyses)
- PGOBBEntries.push_back(
- {BlockFrequency(BBF), PostLinkBBFreq, std::move(Successors)});
- }
-
- if (PGOAnalyses)
- PGOAnalyses->push_back(
- {FuncEntryCount, std::move(PGOBBEntries), FeatEnable});
- }
- }
- // Either Cur is in the error state, or we have an error in ULEBSizeErr or
- // MetadataDecodeErr (but not both), but we join all errors here to be safe.
- if (!Cur || ULEBSizeErr || MetadataDecodeErr)
- return joinErrors(joinErrors(Cur.takeError(), std::move(ULEBSizeErr)),
- std::move(MetadataDecodeErr));
- return FunctionEntries;
+ auto ExtractorOrErr =
+ ELFBBAddrMapAddressExtractor::create(Data, EF, Sec, RelaSec);
+ if (!ExtractorOrErr)
+ return ExtractorOrErr.takeError();
+ auto BBAddrMapsOrErr = decodeBBAddrMapPayload(*ExtractorOrErr, PGOAnalyses);
+ if (!BBAddrMapsOrErr)
+ return createError(toString(BBAddrMapsOrErr.takeError()) + " in " +
+ describe(EF, Sec));
+ return BBAddrMapsOrErr;
}
template <class ELFT>
diff --git a/llvm/lib/Object/ELFObjectFile.cpp b/llvm/lib/Object/ELFObjectFile.cpp
index dba22bd54af2d..7e4aecf7d1ae1 100644
--- a/llvm/lib/Object/ELFObjectFile.cpp
+++ b/llvm/lib/Object/ELFObjectFile.cpp
@@ -818,7 +818,7 @@ Expected<std::vector<BBAddrMap>> static readBBAddrMapImpl(
if (!BBAddrMapOrErr) {
if (PGOAnalyses)
PGOAnalyses->clear();
- return createError("unable to read " + describe(EF, *Sec) + ": " +
+ return createError("unable to read BB addr map section: " +
toString(BBAddrMapOrErr.takeError()));
}
std::move(BBAddrMapOrErr->begin(), BBAddrMapOrErr->end(),
diff --git a/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-feature-warning.test b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-feature-warning.test
index 24726c34d3509..7600e725ea0df 100644
--- a/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-feature-warning.test
+++ b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-feature-warning.test
@@ -10,7 +10,7 @@ FileHeader:
Type: ET_EXEC
# CHECK: BBAddrMap [
-# CHECK-NEXT: warning: '[[FILE]]': unable to dump SHT_LLVM_BB_ADDR_MAP section with index 1: version should be >= 3 for SHT_LLVM_BB_ADDR_MAP when callsite offsets feature is enabled: version = 2 feature = 32
+# CHECK-NEXT: warning: '[[FILE]]': unable to dump BB addr map section: version should be >= 3 for BB address map when callsite offsets feature is enabled: version = 2 feature = 32 in SHT_LLVM_BB_ADDR_MAP section with index 1
Sections:
- Name: '.llvm_bb_addr_map (1)'
Type: SHT_LLVM_BB_ADDR_MAP
@@ -19,7 +19,7 @@ Sections:
Feature: 0x20
# CHECK: BBAddrMap [
-# CHECK-NEXT: warning: '[[FILE]]': unable to dump SHT_LLVM_BB_ADDR_MAP section with index 2: version should be >= 4 for SHT_LLVM_BB_ADDR_MAP when basic block hash feature is enabled: version = 3 feature = 64
+# CHECK-NEXT: warning: '[[FILE]]': unable to dump BB addr map section: version should be >= 4 for BB address map when basic block hash feature is enabled: version = 3 feature = 64 in SHT_LLVM_BB_ADDR_MAP section with index 2
- Name: '.llvm_bb_addr_map (2)'
Type: SHT_LLVM_BB_ADDR_MAP
@@ -28,7 +28,7 @@ Sections:
Feature: 0x40
# CHECK: BBAddrMap [
-# CHECK-NEXT: warning: '[[FILE]]': unable to dump SHT_LLVM_BB_ADDR_MAP section with index 3: version should be >= 5 for SHT_LLVM_BB_ADDR_MAP when post link cfg feature is enabled: version = 4 feature = 128
+# CHECK-NEXT: warning: '[[FILE]]': unable to dump BB addr map section: version should be >= 5 for BB address map when post link cfg feature is enabled: version = 4 feature = 128 in SHT_LLVM_BB_ADDR_MAP section with index 3
- Name: '.llvm_bb_addr_map (3)'
Type: SHT_LLVM_BB_ADDR_MAP
diff --git a/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-pgo-analysis-map.test b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-pgo-analysis-map.test
index 8e9d2271b8721..8ae5dc481e850 100644
--- a/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-pgo-analysis-map.test
+++ b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-pgo-analysis-map.test
@@ -116,7 +116,7 @@
# PRETTY-NO-BAM: warning: --bb-addr-map must be enabled for --pretty-pgo-analysis-map to have an effect
# TRUNCATED: BBAddrMap [
-# TRUNCATED-NEXT: {{.*}}: warning: '[[FILE]]': unable to dump SHT_LLVM_BB_ADDR_MAP section with index 3: unable to decode LEB128 at offset [[OFFSET]]: malformed uleb128, extends past end
+# TRUNCATED-NEXT: {{.*}}: warning: '[[FILE]]': unable to dump BB addr map section: unable to decode LEB128 at offset [[OFFSET]]: malformed uleb128, extends past end in SHT_LLVM_BB_ADDR_MAP section with index 3
# TRUNCATED-NEXT: ]
## Check that the other valid section is properly dumped.
# TRUNCATED-NEXT: BBAddrMap [
@@ -156,7 +156,7 @@
# TRUNCATED-NEXT: }
# TRUNCATED-NEXT: ]
-# INVALIDFT: warning: '[[FILE]]': unable to dump SHT_LLVM_BB_ADDR_MAP section with index 5: unable to decode LEB128 at offset 0x00000010: malformed uleb128, extends past end
+# INVALIDFT: warning: '[[FILE]]': unable to dump BB addr map section: unable to decode LEB128 at offset 0x00000010: malformed uleb128, extends past end in SHT_LLVM_BB_ADDR_MAP section with index 5
--- !ELF
FileHeader:
diff --git a/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-relocatable.test b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-relocatable.test
index 325a956e78591..bd35c12fd19ea 100644
--- a/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-relocatable.test
+++ b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-relocatable.test
@@ -155,7 +155,7 @@ Sections:
# RUN: yaml2obj %s --docnum=3 -o %t3.o
# RUN: llvm-readobj %t3.o --bb-addr-map 2>&1 | FileCheck %s --check-prefix=MISSING-RELOCATION -DFILE=%t3.o
-# MISSING-RELOCATION: warning: '[[FILE]]': unable to dump SHT_LLVM_BB_ADDR_MAP section with index 2: failed to get relocation data for offset: 2 in section SHT_LLVM_BB_ADDR_MAP section with index 2
+# MISSING-RELOCATION: warning: '[[FILE]]': unable to dump BB addr map section: failed to get relocation data for offset: 2 in SHT_LLVM_BB_ADDR_MAP section with index 2
## Check that if we have a missing relocated section, we fail and give the
## appropriate warning.
diff --git a/llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test
index bcffd402d36a0..00e63f2e2b8c4 100644
--- a/llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test
+++ b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test
@@ -89,7 +89,7 @@
# GNU: GNUStyle::printBBAddrMaps not implemented
# TRUNCATED: BBAddrMap [
-# TRUNCATED-NEXT: warning: '[[FILE]]': unable to dump SHT_LLVM_BB_ADDR_MAP section with index 3: unable to decode LEB128 at offset [[OFFSET]]: malformed uleb128, extends past end
+# TRUNCATED-NEXT: warning: '[[FILE]]': unable to dump BB addr map section: unable to decode LEB128 at offset [[OFFSET]]: malformed uleb128, extends past end in SHT_LLVM_BB_ADDR_MAP section with index 3
# TRUNCATED-NEXT: ]
## Check that the other valid section is properly dumped.
# TRUNCATED-NEXT: BBAddrMap [
@@ -127,7 +127,7 @@
# TRUNCATED-NEXT: ]
# INVALIDMD: BBAddrMap [
-# INVALIDMD-NEXT: warning: '[[FILE]]': unable to dump SHT_LLVM_BB_ADDR_MAP section with index 3: invalid encoding for BBEntry::Metadata: 0xf000002
+# INVALIDMD-NEXT: warning: '[[FILE]]': unable to dump BB addr map section: invalid encoding for BBEntry::Metadata: 0xf000002 in SHT_LLVM_BB_ADDR_MAP section with index 3
--- !ELF
FileHeader:
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index bcb580119fb85..ca8a95f9772c3 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -8379,8 +8379,8 @@ void LLVMELFDumper<ELFT>::printBBAddrMaps(bool PrettyPGOAnalysis) {
Expected<std::vector<BBAddrMap>> BBAddrMapOrErr =
this->Obj.decodeBBAddrMap(*Sec, RelocSec, &PGOAnalyses);
if (!BBAddrMapOrErr) {
- this->reportUniqueWarning("unable to dump " + this->describe(*Sec) +
- ": " + toString(BBAddrMapOrErr.takeError()));
+ this->reportUniqueWarning("unable to dump BB addr map section: " +
+ toString(BBAddrMapOrErr.takeError()));
continue;
}
for (const auto &[AM, PAM] : zip_equal(*BBAddrMapOrErr, PGOAnalyses)) {
diff --git a/llvm/unittests/Object/ELFObjectFileTest.cpp b/llvm/unittests/Object/ELFObjectFileTest.cpp
index 1e2955ae40a66..6113bae63828f 100644
--- a/llvm/unittests/Object/ELFObjectFileTest.cpp
+++ b/llvm/unittests/Object/ELFObjectFileTest.cpp
@@ -543,7 +543,8 @@ TEST(ELFObjectFileTest, InvalidDecodeBBAddrMap) {
{
SCOPED_TRACE("unsupported version");
DoCheck(UnsupportedVersionYamlString,
- "unsupported SHT_LLVM_BB_ADDR_MAP version: 6");
+ "unsupported BB address map version: 6 in SHT_LLVM_BB_ADDR_MAP "
+ "section with index 1");
}
SmallString<128> ZeroBBRangesYamlString(CommonYamlString);
@@ -579,8 +580,8 @@ TEST(ELFObjectFileTest, InvalidDecodeBBAddrMap) {
{
SCOPED_TRACE("truncated section");
DoCheck(TruncatedYamlString,
- "unable to decode LEB128 at offset 0x0000000b: "
- "malformed uleb128, extends past end");
+ "unable to decode LEB128 at offset 0x0000000b: malformed uleb128, "
+ "extends past end in SHT_LLVM_BB_ADDR_MAP section with index 1");
}
// Check that we can detect when the encoded BB entry fields exceed the UINT32
@@ -611,11 +612,14 @@ TEST(ELFObjectFileTest, InvalidDecodeBBAddrMap) {
{
SCOPED_TRACE("overlimit fields");
DoCheck(OverInt32LimitYamlStrings[0],
- "ULEB128 value at offset 0x10 exceeds UINT32_MAX (0x100000000)");
+ "ULEB128 value at offset 0x10 exceeds UINT32_MAX (0x100000000) in "
+ "SHT_LLVM_BB_ADDR_MAP section with index 1");
DoCheck(OverInt32LimitYamlStrings[1],
- "ULEB128 value at offset 0x15 exceeds UINT32_MAX (0x100000000)");
+ "ULEB128 value at offset 0x15 exceeds UINT32_MAX (0x100000000) in "
+ "SHT_LLVM_BB_ADDR_MAP section with index 1");
DoCheck(OverInt32LimitYamlStrings[2],
- "ULEB128 value at offset 0x1a exceeds UINT32_MAX (0x100000000)");
+ "ULEB128 value at offset 0x1a exceeds UINT32_MAX (0x100000000) in "
+ "SHT_LLVM_BB_ADDR_MAP section with index 1");
}
// Check the proper error handling when the section has fields exceeding
@@ -640,11 +644,13 @@ TEST(ELFObjectFileTest, InvalidDecodeBBAddrMap) {
SCOPED_TRACE("overlimit fields, truncated section");
DoCheck(OverInt32LimitAndTruncated[0],
"unable to decode LEB128 at offset 0x00000015: malformed uleb128, "
- "extends past end");
+ "extends past end in SHT_LLVM_BB_ADDR_MAP section with index 1");
DoCheck(OverInt32LimitAndTruncated[1],
- "ULEB128 value at offset 0x15 exceeds UINT32_MAX (0x100000000)");
+ "ULEB128 value at offset 0x15 exceeds UINT32_MAX (0x100000000) in "
+ "SHT_LLVM_BB_ADDR_MAP section with index 1");
DoCheck(OverInt32LimitAndTruncated[2],
- "ULEB128 value at offset 0x15 exceeds UINT32_MAX (0x100000000)");
+ "ULEB128 value at offset 0x15 exceeds UINT32_MAX (0x100000000) in "
+ "SHT_LLVM_BB_ADDR_MAP section with index 1");
}
// Check for proper error handling when the 'NumBlocks' field is overridden
@@ -657,7 +663,8 @@ TEST(ELFObjectFileTest, InvalidDecodeBBAddrMap) {
{
SCOPED_TRACE("overlimit 'NumBlocks' field");
DoCheck(OverLimitNumBlocks,
- "ULEB128 value at offset 0xa exceeds UINT32_MAX (0x100000000)");
+ "ULEB128 value at offset 0xa exceeds UINT32_MAX (0x100000000) in "
+ "SHT_LLVM_BB_ADDR_MAP section with index 1");
}
// Check for proper error handling when the 'NumBBRanges' field is overridden
@@ -668,7 +675,8 @@ TEST(ELFObjectFileTest, InvalidDecodeBBAddrMap) {
Feature: 0x8
)";
DoCheck(OverLimitNumBBRanges,
- "ULEB128 value at offset 0x2 exceeds UINT32_MAX (0x100000000)");
+ "ULEB128 value at offset 0x2 exceeds UINT32_MAX (0x100000000) in "
+ "SHT_LLVM_BB_ADDR_MAP section with index 1");
// Check that we can detect unsupported version for callsite offsets.
SmallString<128> UnsupportedLowVersionYamlString(CommonYamlString);
@@ -686,8 +694,9 @@ TEST(ELFObjectFileTest, InvalidDecodeBBAddrMap) {
{
SCOPED_TRACE("unsupported version");
DoCheck(UnsupportedLowVersionYamlString,
- "version should be >= 3 for SHT_LLVM_BB_ADDR_MAP when callsite"
- " offsets feature is enabled: version = 2 feature = 32");
+ "version should be >= 3 for BB address map when callsite offsets "
+ "feature is enabled: version = 2 feature = 32 in "
+ "SHT_LLVM_BB_ADDR_MAP section with index 1");
}
}
@@ -856,9 +865,9 @@ TEST(ELFObjectFileTest, ReadBBAddrMap) {
{
SCOPED_TRACE("truncated section");
DoCheckFails(TruncatedYamlString, /*TextSectionIndex=*/std::nullopt,
- "unable to read SHT_LLVM_BB_ADDR_MAP section with index 4: "
- "unable to decode LEB128 at offset 0x0000000a: malformed "
- "uleb128, extends past end");
+ "unable to read BB addr map section: unable to decode LEB128 "
+ "at offset 0x0000000a: malformed uleb128, extends past end in "
+ "SHT_LLVM_BB_ADDR_MAP section with index 4");
// Check that we can read the other section's bb-address-maps which are
// valid.
@@ -915,7 +924,8 @@ TEST(ELFObjectFileTest, InvalidDecodePGOAnalysisMap) {
{
SCOPED_TRACE("unsupported version");
DoCheck(UnsupportedLowVersionYamlString,
- "unsupported SHT_LLVM_BB_ADDR_MAP version: 1");
+ "unsupported BB address map version: 1 in SHT_LLVM_BB_ADDR_MAP "
+ "section with index 1");
}
// Check that we fail when function entry count is enabled but not provided.
@@ -928,7 +938,8 @@ TEST(ELFObjectFileTest, InvalidDecodePGOAnalysisMap) {
{
SCOPED_TRACE("missing function entry count");
DoCheck(MissingFuncEntryCount,
- "unexpected end of data at offset 0x2 while reading [0x2, 0xa)");
+ "unexpected end of data at offset 0x2 while reading [0x2, 0xa) in "
+ "SHT_LLVM_BB_ADDR_MAP section with index 1");
}
// Check that we fail when basic block frequency is enabled but not provided.
@@ -946,8 +957,9 @@ TEST(ELFObjectFileTest, InvalidDecodePGOAnalysisMap) {
{
SCOPED_TRACE("missing bb frequency");
- DoCheck(MissingBBFreq, "unable to decode LEB128 at offset 0x0000000f: "
- "malformed uleb128, extends past end");
+ DoCheck(MissingBBFreq,
+ "unable to decode LEB128 at offset 0x0000000f: malformed uleb128, "
+ "extends past end in SHT_LLVM_BB_ADDR_MAP section with index 1");
}
// Check that we fail when branch probability is enabled but not provided.
@@ -983,8 +995,9 @@ TEST(ELFObjectFileTest, InvalidDecodePGOAnalysisMap) {
{
SCOPED_TRACE("missing branch probability");
- DoCheck(MissingBrProb, "unable to decode LEB128 at offset 0x00000017: "
- "malformed uleb128, extends past end");
+ DoCheck(MissingBrProb,
+ "unable to decode LEB128 at offset 0x00000017: malformed uleb128, "
+ "extends past end in SHT_LLVM_BB_ADDR_MAP section with index 1");
}
}
@@ -1471,10 +1484,10 @@ TEST(ELFObjectFileTest, ReadPGOAnalysisMap) {
{
SCOPED_TRACE("truncated section");
- DoCheckFails(
- TruncatedYamlString, /*TextSectionIndex=*/std::nullopt,
- "unable to read SHT_LLVM_BB_ADDR_MAP section with index 6: "
- "unexpected end of data at offset 0xa while reading [0x4, 0xc)");
+ DoCheckFails(TruncatedYamlString, /*TextSectionIndex=*/std::nullopt,
+ "unable to read BB addr map section: unexpected end of data "
+ "at offset 0xa while reading [0x4, 0xc) in "
+ "SHT_LLVM_BB_ADDR_MAP section with index 6");
// Check that we can read the other section's bb-address-maps which are
// valid.
DoCheckSucceeds(TruncatedYamlString, /*TextSectionIndex=*/2,
More information about the llvm-commits
mailing list