diff options
author | George Rimar <grimar@accesssoftek.com> | 2017-05-27 18:10:23 +0000 |
---|---|---|
committer | George Rimar <grimar@accesssoftek.com> | 2017-05-27 18:10:23 +0000 |
commit | a25d329b3334e228c0b0553c80816a166e6174a7 (patch) | |
tree | 5788be337d3e7f183f10bcb62abc64ce43750acb /llvm/lib | |
parent | a568c72b7dbb8152034d2a3f1a7732b020d85b54 (diff) | |
download | bcm5719-llvm-a25d329b3334e228c0b0553c80816a166e6174a7.tar.gz bcm5719-llvm-a25d329b3334e228c0b0553c80816a166e6174a7.zip |
Recommit "[DWARF] - Make collectAddressRanges() return section index in addition to Low/High PC"
With fix of uninitialized variable.
Original commit message:
This change is intended to use for LLD in D33183.
Problem we have in LLD when building .gdb_index is that we need to know section which address range belongs to.
Previously it was solved on LLD side by providing fake section addresses with use of llvm::LoadedObjectInfo
interface. We assigned file offsets as addressed. Then after obtaining ranges lists, for each range we had to find section ID's.
That not only was slow, but also complicated implementation and was the reason of incorrect behavior when
sections share the same offsets, like D33176 shows.
This patch makes DWARF parsers to return section index as well. That solves problem mentioned above.
Differential revision: https://reviews.llvm.org/D33184
llvm-svn: 304078
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 59 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFDie.cpp | 13 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Object/COFFObjectFile.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Object/MachOObjectFile.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Object/WasmObjectFile.cpp | 4 |
7 files changed, 62 insertions, 34 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp index 896837c8547..5ed55ce4c0d 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -60,12 +60,15 @@ typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind; typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind; uint64_t llvm::getRelocatedValue(const DataExtractor &Data, uint32_t Size, - uint32_t *Off, const RelocAddrMap *Relocs) { + uint32_t *Off, const RelocAddrMap *Relocs, + uint64_t *SectionIndex) { if (!Relocs) return Data.getUnsigned(Off, Size); RelocAddrMap::const_iterator AI = Relocs->find(*Off); if (AI == Relocs->end()) return Data.getUnsigned(Off, Size); + if (SectionIndex) + *SectionIndex = AI->second.SectionIndex; return Data.getUnsigned(Off, Size) + AI->second.Value; } @@ -958,23 +961,29 @@ static Error createError(const Twine &Reason, llvm::Error E) { inconvertibleErrorCode()); } -/// Returns the address of symbol relocation used against. Used for futher -/// relocations computation. Symbol's section load address is taken in account if -/// LoadedObjectInfo interface is provided. -static Expected<uint64_t> -getSymbolAddress(const object::ObjectFile &Obj, const RelocationRef &Reloc, - const LoadedObjectInfo *L, - std::map<SymbolRef, uint64_t> &Cache) { - uint64_t Ret = 0; +/// SymInfo contains information about symbol: it's address +/// and section index which is -1LL for absolute symbols. +struct SymInfo { + uint64_t Address; + uint64_t SectionIndex; +}; + +/// Returns the address of symbol relocation used against and a section index. +/// Used for futher relocations computation. Symbol's section load address is +static Expected<SymInfo> getSymbolInfo(const object::ObjectFile &Obj, + const RelocationRef &Reloc, + const LoadedObjectInfo *L, + std::map<SymbolRef, SymInfo> &Cache) { + SymInfo Ret = {0, (uint64_t)-1LL}; object::section_iterator RSec = Obj.section_end(); object::symbol_iterator Sym = Reloc.getSymbol(); - std::map<SymbolRef, uint64_t>::iterator CacheIt = Cache.end(); + std::map<SymbolRef, SymInfo>::iterator CacheIt = Cache.end(); // First calculate the address of the symbol or section as it appears // in the object file if (Sym != Obj.symbol_end()) { bool New; - std::tie(CacheIt, New) = Cache.insert({*Sym, 0}); + std::tie(CacheIt, New) = Cache.insert({*Sym, {0, 0}}); if (!New) return CacheIt->second; @@ -990,12 +999,15 @@ getSymbolAddress(const object::ObjectFile &Obj, const RelocationRef &Reloc, SectOrErr.takeError()); RSec = *SectOrErr; - Ret = *SymAddrOrErr; + Ret.Address = *SymAddrOrErr; } else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) { RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl()); - Ret = RSec->getAddress(); + Ret.Address = RSec->getAddress(); } + if (RSec != Obj.section_end()) + Ret.SectionIndex = RSec->getIndex(); + // If we are given load addresses for the sections, we need to adjust: // SymAddr = (Address of Symbol Or Section in File) - // (Address of Section in File) + @@ -1005,7 +1017,7 @@ getSymbolAddress(const object::ObjectFile &Obj, const RelocationRef &Reloc, // we need to perform the same computation. if (L && RSec != Obj.section_end()) if (uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec)) - Ret += SectionLoadAddress - RSec->getAddress(); + Ret.Address += SectionLoadAddress - RSec->getAddress(); if (CacheIt != Cache.end()) CacheIt->second = Ret; @@ -1064,7 +1076,7 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj, // Try to obtain an already relocated version of this section. // Else use the unrelocated section from the object file. We'll have to // apply relocations ourselves later. - if (!L || !L->getLoadedSectionContents(*RelocatedSection,data)) + if (!L || !L->getLoadedSectionContents(*RelocatedSection, data)) Section.getContents(data); if (auto Err = maybeDecompress(Section, name, data)) { @@ -1103,7 +1115,7 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj, // If the section we're relocating was relocated already by the JIT, // then we used the relocated version above, so we do not need to process // relocations for it now. - if (L && L->getLoadedSectionContents(*RelocatedSection,RelSecData)) + if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData)) continue; // In Mach-o files, the relocations do not need to be applied if @@ -1147,29 +1159,30 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj, if (Section.relocation_begin() == Section.relocation_end()) continue; - std::map<SymbolRef, uint64_t> AddrCache; + // Symbol to [address, section index] cache mapping. + std::map<SymbolRef, SymInfo> AddrCache; for (const RelocationRef &Reloc : Section.relocations()) { // FIXME: it's not clear how to correctly handle scattered // relocations. if (isRelocScattered(Obj, Reloc)) continue; - Expected<uint64_t> SymAddrOrErr = - getSymbolAddress(Obj, Reloc, L, AddrCache); - if (!SymAddrOrErr) { - errs() << toString(SymAddrOrErr.takeError()) << '\n'; + Expected<SymInfo> SymInfoOrErr = getSymbolInfo(Obj, Reloc, L, AddrCache); + if (!SymInfoOrErr) { + errs() << toString(SymInfoOrErr.takeError()) << '\n'; continue; } object::RelocVisitor V(Obj); - uint64_t Val = V.visit(Reloc.getType(), Reloc, *SymAddrOrErr); + uint64_t Val = V.visit(Reloc.getType(), Reloc, SymInfoOrErr->Address); if (V.error()) { SmallString<32> Name; Reloc.getTypeName(Name); errs() << "error: failed to compute relocation: " << Name << "\n"; continue; } - Map->insert({Reloc.getOffset(), {Val}}); + llvm::RelocAddrEntry Rel = {SymInfoOrErr->SectionIndex, Val}; + Map->insert({Reloc.getOffset(), Rel}); } } } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp index 8da797750ab..6b5e1d3c931 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp @@ -35,8 +35,8 @@ bool DWARFDebugRangeList::extract(DataExtractor data, uint32_t *offset_ptr, while (true) { RangeListEntry entry; uint32_t prev_offset = *offset_ptr; - entry.StartAddress = - getRelocatedValue(data, AddressSize, offset_ptr, &Relocs); + entry.StartAddress = getRelocatedValue(data, AddressSize, offset_ptr, + &Relocs, &entry.SectionIndex); entry.EndAddress = getRelocatedValue(data, AddressSize, offset_ptr, &Relocs); @@ -69,8 +69,8 @@ DWARFDebugRangeList::getAbsoluteRanges(uint64_t BaseAddress) const { if (RLE.isBaseAddressSelectionEntry(AddressSize)) { BaseAddress = RLE.EndAddress; } else { - Res.push_back( - {BaseAddress + RLE.StartAddress, BaseAddress + RLE.EndAddress}); + Res.push_back({BaseAddress + RLE.StartAddress, + BaseAddress + RLE.EndAddress, RLE.SectionIndex}); } } return Res; diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp index e3bd759ba94..fd45c77d374 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp @@ -211,13 +211,16 @@ Optional<uint64_t> DWARFDie::getHighPC(uint64_t LowPC) const { return None; } -bool DWARFDie::getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC) const { - auto LowPcAddr = toAddress(find(DW_AT_low_pc)); +bool DWARFDie::getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC, + uint64_t &SectionIndex) const { + auto F = find(DW_AT_low_pc); + auto LowPcAddr = toAddress(F); if (!LowPcAddr) return false; if (auto HighPcAddr = getHighPC(*LowPcAddr)) { LowPC = *LowPcAddr; HighPC = *HighPcAddr; + SectionIndex = F->getSectionIndex(); return true; } return false; @@ -228,9 +231,9 @@ DWARFDie::getAddressRanges() const { if (isNULL()) return DWARFAddressRangesVector(); // Single range specified by low/high PC. - uint64_t LowPC, HighPC; - if (getLowAndHighPC(LowPC, HighPC)) - return {{LowPC, HighPC}}; + uint64_t LowPC, HighPC, Index; + if (getLowAndHighPC(LowPC, HighPC, Index)) + return {{LowPC, HighPC, Index}}; // Multiple ranges from .debug_ranges section. auto RangesOffset = toSectionOffset(find(DW_AT_ranges)); diff --git a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp index 1cbd3ea2c86..0963d7bfd71 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp @@ -333,8 +333,8 @@ bool DWARFFormValue::extractValue(const DataExtractor &Data, return false; uint16_t AddrSize = (Form == DW_FORM_addr) ? U->getAddressByteSize() : U->getRefAddrByteSize(); - Value.uval = - getRelocatedValue(Data, AddrSize, OffsetPtr, U->getRelocMap()); + Value.uval = getRelocatedValue(Data, AddrSize, OffsetPtr, + U->getRelocMap(), &Value.SectionIndex); break; } case DW_FORM_exprloc: diff --git a/llvm/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp index 28531feccfe..7372f24cb9a 100644 --- a/llvm/lib/Object/COFFObjectFile.cpp +++ b/llvm/lib/Object/COFFObjectFile.cpp @@ -293,6 +293,10 @@ uint64_t COFFObjectFile::getSectionAddress(DataRefImpl Ref) const { return Result; } +uint64_t COFFObjectFile::getSectionIndex(DataRefImpl Sec) const { + return toSec(Sec) - SectionTable; +} + uint64_t COFFObjectFile::getSectionSize(DataRefImpl Ref) const { return getSectionSize(toSec(Ref)); } diff --git a/llvm/lib/Object/MachOObjectFile.cpp b/llvm/lib/Object/MachOObjectFile.cpp index 3d3fa07db3f..bfb8875f47d 100644 --- a/llvm/lib/Object/MachOObjectFile.cpp +++ b/llvm/lib/Object/MachOObjectFile.cpp @@ -1820,6 +1820,10 @@ uint64_t MachOObjectFile::getSectionAddress(DataRefImpl Sec) const { return getSection(Sec).addr; } +uint64_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const { + return Sec.d.a; +} + uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const { // In the case if a malformed Mach-O file where the section offset is past // the end of the file or some part of the section size is past the end of diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp index 058686e4db9..f565d7a33e5 100644 --- a/llvm/lib/Object/WasmObjectFile.cpp +++ b/llvm/lib/Object/WasmObjectFile.cpp @@ -743,6 +743,10 @@ std::error_code WasmObjectFile::getSectionName(DataRefImpl Sec, uint64_t WasmObjectFile::getSectionAddress(DataRefImpl Sec) const { return 0; } +uint64_t WasmObjectFile::getSectionIndex(DataRefImpl Sec) const { + return Sec.d.a; +} + uint64_t WasmObjectFile::getSectionSize(DataRefImpl Sec) const { const WasmSection &S = Sections[Sec.d.a]; return S.Content.size(); |