/// Reads a value from data extractor and applies a relocation to the result if
/// one exists for the given offset.
uint64_t getRelocatedValue(const DataExtractor &Data, uint32_t Size,
- uint32_t *Off, const RelocAddrMap *Relocs,
- uint64_t *SecNdx = nullptr);
+ uint32_t *Off, const RelocAddrMap *Relocs);
/// DWARFContext
/// This data structure is the top level entity that deals with dwarf debug
struct DWARFAddressRange {
uint64_t LowPC;
uint64_t HighPC;
- uint64_t SectionIndex;
};
/// DWARFAddressRangesVector - represents a set of absolute address ranges.
/// address past the end of the address range. The ending address must
/// be greater than or equal to the beginning address.
uint64_t EndAddress;
- /// A section index this range belongs to.
- uint64_t SectionIndex;
/// The end of any given range list is marked by an end of list entry,
/// which consists of a 0 for the beginning address offset
/// Retrieves DW_AT_low_pc and DW_AT_high_pc from CU.
/// Returns true if both attributes are present.
- bool getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC,
- uint64_t &SectionIndex) const;
+ bool getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC) const;
/// Get the address ranges for this DIE.
///
const char *cstr;
};
const uint8_t *data = nullptr;
- uint64_t SectionIndex; /// Section index for reference forms.
};
dwarf::Form Form; /// Form for this value.
dwarf::Form getForm() const { return Form; }
uint64_t getRawUValue() const { return Value.uval; }
- uint64_t getSectionIndex() const { return Value.SectionIndex; }
void setForm(dwarf::Form F) { Form = F; }
void setUValue(uint64_t V) { Value.uval = V; }
void setSValue(int64_t V) { Value.sval = V; }
namespace llvm {
struct RelocAddrEntry {
- uint64_t SectionIndex;
uint64_t Value;
};
std::error_code getSectionName(DataRefImpl Sec,
StringRef &Res) const override;
uint64_t getSectionAddress(DataRefImpl Sec) const override;
- uint64_t getSectionIndex(DataRefImpl Sec) const override;
uint64_t getSectionSize(DataRefImpl Sec) const override;
std::error_code getSectionContents(DataRefImpl Sec,
StringRef &Res) const override;
std::error_code getSectionName(DataRefImpl Sec,
StringRef &Res) const override;
uint64_t getSectionAddress(DataRefImpl Sec) const override;
- uint64_t getSectionIndex(DataRefImpl Sec) const override;
uint64_t getSectionSize(DataRefImpl Sec) const override;
std::error_code getSectionContents(DataRefImpl Sec,
StringRef &Res) const override;
}
template <class ELFT>
-uint64_t ELFObjectFile<ELFT>::getSectionIndex(DataRefImpl Sec) const {
- auto SectionsOrErr = EF.sections();
- handleAllErrors(std::move(SectionsOrErr.takeError()),
- [](const ErrorInfoBase &) {
- llvm_unreachable("unable to get section index");
- });
- const Elf_Shdr *First = SectionsOrErr->begin();
- return getSection(Sec) - First;
-}
-
-template <class ELFT>
uint64_t ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec) const {
return getSection(Sec)->sh_size;
}
std::error_code getSectionName(DataRefImpl Sec,
StringRef &Res) const override;
uint64_t getSectionAddress(DataRefImpl Sec) const override;
- uint64_t getSectionIndex(DataRefImpl Sec) const override;
uint64_t getSectionSize(DataRefImpl Sec) const override;
std::error_code getSectionContents(DataRefImpl Sec,
StringRef &Res) const override;
std::error_code getName(StringRef &Result) const;
uint64_t getAddress() const;
- uint64_t getIndex() const;
uint64_t getSize() const;
std::error_code getContents(StringRef &Result) const;
virtual std::error_code getSectionName(DataRefImpl Sec,
StringRef &Res) const = 0;
virtual uint64_t getSectionAddress(DataRefImpl Sec) const = 0;
- virtual uint64_t getSectionIndex(DataRefImpl Sec) const = 0;
virtual uint64_t getSectionSize(DataRefImpl Sec) const = 0;
virtual std::error_code getSectionContents(DataRefImpl Sec,
StringRef &Res) const = 0;
return OwningObject->getSectionAddress(SectionPimpl);
}
-inline uint64_t SectionRef::getIndex() const {
- return OwningObject->getSectionIndex(SectionPimpl);
-}
-
inline uint64_t SectionRef::getSize() const {
return OwningObject->getSectionSize(SectionPimpl);
}
std::error_code getSectionName(DataRefImpl Sec,
StringRef &Res) const override;
uint64_t getSectionAddress(DataRefImpl Sec) const override;
- uint64_t getSectionIndex(DataRefImpl Sec) const override;
uint64_t getSectionSize(DataRefImpl Sec) const override;
std::error_code getSectionContents(DataRefImpl Sec,
StringRef &Res) const override;
typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
uint64_t llvm::getRelocatedValue(const DataExtractor &Data, uint32_t Size,
- uint32_t *Off, const RelocAddrMap *Relocs,
- uint64_t *SectionIndex) {
+ uint32_t *Off, const RelocAddrMap *Relocs) {
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;
}
inconvertibleErrorCode());
}
-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;
+/// 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;
object::section_iterator RSec = Obj.section_end();
object::symbol_iterator Sym = Reloc.getSymbol();
- std::map<SymbolRef, SymInfo>::iterator CacheIt = Cache.end();
+ std::map<SymbolRef, uint64_t>::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, 0}});
+ std::tie(CacheIt, New) = Cache.insert({*Sym, 0});
if (!New)
return CacheIt->second;
SectOrErr.takeError());
RSec = *SectOrErr;
- Ret.Address = *SymAddrOrErr;
+ Ret = *SymAddrOrErr;
} else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl());
- Ret.Address = RSec->getAddress();
+ Ret = RSec->getAddress();
}
- 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) +
// we need to perform the same computation.
if (L && RSec != Obj.section_end())
if (uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec))
- Ret.Address += SectionLoadAddress - RSec->getAddress();
+ Ret += SectionLoadAddress - RSec->getAddress();
if (CacheIt != Cache.end())
CacheIt->second = Ret;
// 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)) {
// 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
if (Section.relocation_begin() == Section.relocation_end())
continue;
- // Symbol to [address, section index] cache mapping.
- std::map<SymbolRef, SymInfo> AddrCache;
+ std::map<SymbolRef, uint64_t> AddrCache;
for (const RelocationRef &Reloc : Section.relocations()) {
// FIXME: it's not clear how to correctly handle scattered
// relocations.
if (isRelocScattered(Obj, Reloc))
continue;
- Expected<SymInfo> SymInfoOrErr = getSymbolInfo(Obj, Reloc, L, AddrCache);
- if (!SymInfoOrErr) {
- errs() << toString(SymInfoOrErr.takeError()) << '\n';
+ Expected<uint64_t> SymAddrOrErr =
+ getSymbolAddress(Obj, Reloc, L, AddrCache);
+ if (!SymAddrOrErr) {
+ errs() << toString(SymAddrOrErr.takeError()) << '\n';
continue;
}
object::RelocVisitor V(Obj);
- uint64_t Val = V.visit(Reloc.getType(), Reloc, SymInfoOrErr->Address);
+ uint64_t Val = V.visit(Reloc.getType(), Reloc, *SymAddrOrErr);
if (V.error()) {
SmallString<32> Name;
Reloc.getTypeName(Name);
errs() << "error: failed to compute relocation: " << Name << "\n";
continue;
}
- llvm::RelocAddrEntry Rel = {SymInfoOrErr->SectionIndex, Val};
- Map->insert({Reloc.getOffset(), Rel});
+ Map->insert({Reloc.getOffset(), {Val}});
}
}
}
while (true) {
RangeListEntry entry;
uint32_t prev_offset = *offset_ptr;
- entry.StartAddress = getRelocatedValue(data, AddressSize, offset_ptr,
- &Relocs, &entry.SectionIndex);
+ entry.StartAddress =
+ getRelocatedValue(data, AddressSize, offset_ptr, &Relocs);
entry.EndAddress =
getRelocatedValue(data, AddressSize, offset_ptr, &Relocs);
if (RLE.isBaseAddressSelectionEntry(AddressSize)) {
BaseAddress = RLE.EndAddress;
} else {
- Res.push_back({BaseAddress + RLE.StartAddress,
- BaseAddress + RLE.EndAddress, RLE.SectionIndex});
+ Res.push_back(
+ {BaseAddress + RLE.StartAddress, BaseAddress + RLE.EndAddress});
}
}
return Res;
return None;
}
-bool DWARFDie::getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC,
- uint64_t &SectionIndex) const {
- auto F = find(DW_AT_low_pc);
- auto LowPcAddr = toAddress(F);
+bool DWARFDie::getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC) const {
+ auto LowPcAddr = toAddress(find(DW_AT_low_pc));
if (!LowPcAddr)
return false;
if (auto HighPcAddr = getHighPC(*LowPcAddr)) {
LowPC = *LowPcAddr;
HighPC = *HighPcAddr;
- SectionIndex = F->getSectionIndex();
return true;
}
return false;
if (isNULL())
return DWARFAddressRangesVector();
// Single range specified by low/high PC.
- uint64_t LowPC, HighPC, Index;
- if (getLowAndHighPC(LowPC, HighPC, Index))
- return {{LowPC, HighPC, Index}};
+ uint64_t LowPC, HighPC;
+ if (getLowAndHighPC(LowPC, HighPC))
+ return {{LowPC, HighPC}};
// Multiple ranges from .debug_ranges section.
auto RangesOffset = toSectionOffset(find(DW_AT_ranges));
return false;
uint16_t AddrSize = (Form == DW_FORM_addr) ? U->getAddressByteSize()
: U->getRefAddrByteSize();
- Value.uval = getRelocatedValue(Data, AddrSize, OffsetPtr,
- U->getRelocMap(), &Value.SectionIndex);
+ Value.uval =
+ getRelocatedValue(Data, AddrSize, OffsetPtr, U->getRelocMap());
break;
}
case DW_FORM_exprloc:
return Result;
}
-uint64_t COFFObjectFile::getSectionIndex(DataRefImpl Sec) const {
- return toSec(Sec) - SectionTable;
-}
-
uint64_t COFFObjectFile::getSectionSize(DataRefImpl Ref) const {
return getSectionSize(toSec(Ref));
}
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
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();
// Get the compile unit DIE is valid.
auto DieDG = U->getUnitDIE(false);
EXPECT_TRUE(DieDG.isValid());
-
- uint64_t LowPC, HighPC, SectionIndex;
+
+ uint64_t LowPC, HighPC;
Optional<uint64_t> OptU64;
// Verify the that our subprogram with no PC value fails appropriately when
// asked for any PC values.
EXPECT_FALSE((bool)OptU64);
OptU64 = toAddress(SubprogramDieNoPC.find(DW_AT_high_pc));
EXPECT_FALSE((bool)OptU64);
- EXPECT_FALSE(SubprogramDieNoPC.getLowAndHighPC(LowPC, HighPC, SectionIndex));
+ EXPECT_FALSE(SubprogramDieNoPC.getLowAndHighPC(LowPC, HighPC));
OptU64 = toAddress(SubprogramDieNoPC.find(DW_AT_high_pc));
EXPECT_FALSE((bool)OptU64);
OptU64 = toUnsigned(SubprogramDieNoPC.find(DW_AT_high_pc));
EXPECT_FALSE((bool)OptU64);
OptU64 = SubprogramDieNoPC.getHighPC(ActualLowPC);
EXPECT_FALSE((bool)OptU64);
- EXPECT_FALSE(SubprogramDieNoPC.getLowAndHighPC(LowPC, HighPC, SectionIndex));
+ EXPECT_FALSE(SubprogramDieNoPC.getLowAndHighPC(LowPC, HighPC));
// Verify the that our subprogram with only a low PC value succeeds when
// we ask for the Low PC, but fails appropriately when asked for the high PC
EXPECT_FALSE((bool)OptU64);
OptU64 = SubprogramDieLowPC.getHighPC(ActualLowPC);
EXPECT_FALSE((bool)OptU64);
- EXPECT_FALSE(SubprogramDieLowPC.getLowAndHighPC(LowPC, HighPC, SectionIndex));
+ EXPECT_FALSE(SubprogramDieLowPC.getLowAndHighPC(LowPC, HighPC));
// Verify the that our subprogram with only a low PC value succeeds when
// we ask for the Low PC, but fails appropriately when asked for the high PC
EXPECT_TRUE((bool)OptU64);
EXPECT_EQ(OptU64.getValue(), ActualHighPC);
- EXPECT_TRUE(SubprogramDieLowHighPC.getLowAndHighPC(LowPC, HighPC, SectionIndex));
+ EXPECT_TRUE(SubprogramDieLowHighPC.getLowAndHighPC(LowPC, HighPC));
EXPECT_EQ(LowPC, ActualLowPC);
EXPECT_EQ(HighPC, ActualHighPC);
}