diff options
Diffstat (limited to 'llvm/lib/Object/ELF.cpp')
-rw-r--r-- | llvm/lib/Object/ELF.cpp | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp index 46e1b13..715cb5c 100644 --- a/llvm/lib/Object/ELF.cpp +++ b/llvm/lib/Object/ELF.cpp @@ -640,7 +640,26 @@ ELFFile<ELFT>::toMappedAddr(uint64_t VAddr, WarningHandler WarnHandler) const { template <class ELFT> Expected<std::vector<BBAddrMap>> -ELFFile<ELFT>::decodeBBAddrMap(const Elf_Shdr &Sec) const { +ELFFile<ELFT>::decodeBBAddrMap(const Elf_Shdr &Sec, + const Elf_Shdr *RelaSec) const { + bool IsRelocatable = 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."); + Expected<Elf_Rela_Range> Relas = this->relas(*RelaSec); + if (!Relas) + return createError("unable to read relocations for section " + + describe(*this, Sec) + ": " + + toString(Relas.takeError())); + for (Elf_Rela Rela : *Relas) + FunctionOffsetTranslations[Rela.r_offset] = Rela.r_addend; + } Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec); if (!ContentsOrErr) return ContentsOrErr.takeError(); @@ -680,7 +699,20 @@ ELFFile<ELFT>::decodeBBAddrMap(const Elf_Shdr &Sec) const { Twine(static_cast<int>(Version))); Data.getU8(Cur); // Feature byte } + uint64_t SectionOffset = Cur.tell(); uintX_t Address = static_cast<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(*this, Sec)); + } + Address = FOTIterator->second; + } uint32_t NumBlocks = ReadULEB128AsUInt32(); std::vector<BBAddrMap::BBEntry> BBEntries; uint32_t PrevBBEndOffset = 0; |