diff options
Diffstat (limited to 'llvm/lib/Object/ELF.cpp')
-rw-r--r-- | llvm/lib/Object/ELF.cpp | 132 |
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 |