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.cpp34
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;