aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Object/ELF.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Object/ELF.cpp')
-rw-r--r--llvm/lib/Object/ELF.cpp132
1 files changed, 87 insertions, 45 deletions
diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp
index f24395b..137f606 100644
--- a/llvm/lib/Object/ELF.cpp
+++ b/llvm/lib/Object/ELF.cpp
@@ -693,6 +693,17 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
for (typename ELFFile<ELFT>::Elf_Rela Rela : *Relas)
FunctionOffsetTranslations[Rela.r_offset] = Rela.r_addend;
}
+ auto GetAddressForRelocation =
+ [&](unsigned RelocationOffsetInSection) -> Expected<unsigned> {
+ 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;
+ };
Expected<ArrayRef<uint8_t>> ContentsOrErr = EF.getSectionContents(Sec);
if (!ContentsOrErr)
return ContentsOrErr.takeError();
@@ -704,9 +715,26 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
Error ULEBSizeErr = Error::success();
Error MetadataDecodeErr = Error::success();
+ // Helper lampda to extract the (possiblly relocatable) address stored at Cur.
+ auto ExtractAddress = [&]() -> Expected<typename ELFFile<ELFT>::uintX_t> {
+ uint64_t RelocationOffsetInSection = Cur.tell();
+ auto Address =
+ static_cast<typename ELFFile<ELFT>::uintX_t>(Data.getAddress(Cur));
+ if (!Cur)
+ return Cur.takeError();
+ if (!IsRelocatable)
+ return Address;
+ assert(Address == 0);
+ Expected<unsigned> AddressOrErr =
+ GetAddressForRelocation(RelocationOffsetInSection);
+ if (!AddressOrErr)
+ return AddressOrErr.takeError();
+ return *AddressOrErr;
+ };
+
uint8_t Version = 0;
uint8_t Feature = 0;
- PGOAnalysisMap::Features FeatEnable{};
+ BBAddrMap::Features FeatEnable{};
while (!ULEBSizeErr && !MetadataDecodeErr && Cur &&
Cur.tell() < Content.size()) {
if (Sec.sh_type == ELF::SHT_LLVM_BB_ADDR_MAP) {
@@ -719,11 +747,10 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
Feature = Data.getU8(Cur); // Feature byte
if (!Cur)
break;
- auto FeatEnableOrErr = PGOAnalysisMap::Features::decode(Feature);
+ auto FeatEnableOrErr = BBAddrMap::Features::decode(Feature);
if (!FeatEnableOrErr)
return FeatEnableOrErr.takeError();
- FeatEnable =
- FeatEnableOrErr ? *FeatEnableOrErr : PGOAnalysisMap::Features{};
+ FeatEnable = *FeatEnableOrErr;
if (Feature != 0 && Version < 2 && Cur)
return createError(
"version should be >= 2 for SHT_LLVM_BB_ADDR_MAP when "
@@ -731,50 +758,65 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
Twine(static_cast<int>(Version)) +
" feature = " + Twine(static_cast<int>(Feature)));
}
- uint64_t SectionOffset = Cur.tell();
- auto Address =
- static_cast<typename ELFFile<ELFT>::uintX_t>(Data.getAddress(Cur));
- if (!Cur)
- return Cur.takeError();
- if (IsRelocatable) {
- assert(Address == 0);
- auto FOTIterator = FunctionOffsetTranslations.find(SectionOffset);
- if (FOTIterator == FunctionOffsetTranslations.end()) {
- return createError("failed to get relocation data for offset: " +
- Twine::utohexstr(SectionOffset) + " in section " +
- describe(EF, Sec));
- }
- Address = FOTIterator->second;
- }
- uint32_t NumBlocks = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
-
+ uint32_t NumBlocksInBBRange = 0;
+ uint32_t NumBBRanges = 1;
+ typename ELFFile<ELFT>::uintX_t RangeBaseAddress = 0;
std::vector<BBAddrMap::BBEntry> BBEntries;
- uint32_t PrevBBEndOffset = 0;
- for (uint32_t BlockIndex = 0;
- !MetadataDecodeErr && !ULEBSizeErr && Cur && (BlockIndex < NumBlocks);
- ++BlockIndex) {
- uint32_t ID = Version >= 2
- ? readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr)
- : BlockIndex;
- uint32_t Offset = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
- uint32_t Size = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
- uint32_t MD = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
- if (Version >= 1) {
- // Offset is calculated relative to the end of the previous BB.
- Offset += PrevBBEndOffset;
- PrevBBEndOffset = Offset + Size;
- }
- Expected<BBAddrMap::BBEntry::Metadata> MetadataOrErr =
- BBAddrMap::BBEntry::Metadata::decode(MD);
- if (!MetadataOrErr) {
- MetadataDecodeErr = MetadataOrErr.takeError();
+ 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);
+ }
+ for (uint32_t BlockIndex = 0; !MetadataDecodeErr && !ULEBSizeErr && Cur &&
+ (BlockIndex < NumBlocksInBBRange);
+ ++BlockIndex) {
+ uint32_t ID = Version >= 2
+ ? readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr)
+ : BlockIndex;
+ uint32_t Offset = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
+ uint32_t Size = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
+ uint32_t MD = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
+ if (Version >= 1) {
+ // Offset is calculated relative to the end of the previous BB.
+ Offset += PrevBBEndOffset;
+ PrevBBEndOffset = Offset + Size;
+ }
+ Expected<BBAddrMap::BBEntry::Metadata> MetadataOrErr =
+ BBAddrMap::BBEntry::Metadata::decode(MD);
+ if (!MetadataOrErr) {
+ MetadataDecodeErr = MetadataOrErr.takeError();
+ break;
+ }
+ BBEntries.push_back({ID, Offset, Size, *MetadataOrErr});
}
- BBEntries.push_back({ID, Offset, Size, *MetadataOrErr});
+ TotalNumBlocks += BBEntries.size();
+ BBRangeEntries.push_back({RangeBaseAddress, std::move(BBEntries)});
}
- FunctionEntries.emplace_back(Address, std::move(BBEntries));
+ FunctionEntries.push_back({std::move(BBRangeEntries)});
- if (PGOAnalyses || FeatEnable.anyEnabled()) {
+ if (PGOAnalyses || FeatEnable.hasPGOAnalysis()) {
// Function entry count
uint64_t FuncEntryCount =
FeatEnable.FuncEntryCount
@@ -783,8 +825,8 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
std::vector<PGOAnalysisMap::PGOBBEntry> PGOBBEntries;
for (uint32_t BlockIndex = 0;
- (FeatEnable.BBFreq || FeatEnable.BrProb) && !MetadataDecodeErr &&
- !ULEBSizeErr && Cur && (BlockIndex < NumBlocks);
+ FeatEnable.hasPGOAnalysisBBData() && !MetadataDecodeErr &&
+ !ULEBSizeErr && Cur && (BlockIndex < TotalNumBlocks);
++BlockIndex) {
// Block frequency
uint64_t BBF = FeatEnable.BBFreq