diff options
Diffstat (limited to 'ELF/SyntheticSections.cpp')
-rw-r--r-- | ELF/SyntheticSections.cpp | 65 |
1 files changed, 38 insertions, 27 deletions
diff --git a/ELF/SyntheticSections.cpp b/ELF/SyntheticSections.cpp index 995d05692ee2..fd724fac327c 100644 --- a/ELF/SyntheticSections.cpp +++ b/ELF/SyntheticSections.cpp @@ -1071,10 +1071,11 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() { return; // Already finalized. this->Link = InX::DynStrTab->getParent()->SectionIndex; - if (In<ELFT>::RelaDyn->getParent()->Size > 0) { + if (In<ELFT>::RelaDyn->getParent() && !In<ELFT>::RelaDyn->empty()) { bool IsRela = Config->IsRela; add({IsRela ? DT_RELA : DT_REL, In<ELFT>::RelaDyn}); - add({IsRela ? DT_RELASZ : DT_RELSZ, In<ELFT>::RelaDyn->getParent()->Size}); + add({IsRela ? DT_RELASZ : DT_RELSZ, In<ELFT>::RelaDyn->getParent(), + Entry::SecSize}); add({IsRela ? DT_RELAENT : DT_RELENT, uint64_t(IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel))}); @@ -1087,9 +1088,9 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() { add({IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels}); } } - if (In<ELFT>::RelaPlt->getParent()->Size > 0) { + if (In<ELFT>::RelaPlt->getParent() && !In<ELFT>::RelaPlt->empty()) { add({DT_JMPREL, In<ELFT>::RelaPlt}); - add({DT_PLTRELSZ, In<ELFT>::RelaPlt->getParent()->Size}); + add({DT_PLTRELSZ, In<ELFT>::RelaPlt->getParent(), Entry::SecSize}); switch (Config->EMachine) { case EM_MIPS: add({DT_MIPS_PLTGOT, In<ELFT>::GotPlt}); @@ -1699,9 +1700,9 @@ unsigned PltSection::getPltRelocOff() const { return (HeaderSize == 0) ? InX::Plt->getSize() : 0; } -GdbIndexSection::GdbIndexSection() +GdbIndexSection::GdbIndexSection(std::vector<GdbIndexChunk> &&Chunks) : SyntheticSection(0, SHT_PROGBITS, 1, ".gdb_index"), - StringPool(llvm::StringTableBuilder::ELF) {} + StringPool(llvm::StringTableBuilder::ELF), Chunks(std::move(Chunks)) {} // Iterative hash function for symbol's name is described in .gdb_index format // specification. Note that we use one for version 5 to 7 here, it is different @@ -1713,11 +1714,10 @@ static uint32_t hash(StringRef Str) { return R; } -static std::vector<CompilationUnitEntry> readCuList(DWARFContext &Dwarf, - InputSection *Sec) { +static std::vector<CompilationUnitEntry> readCuList(DWARFContext &Dwarf) { std::vector<CompilationUnitEntry> Ret; for (std::unique_ptr<DWARFCompileUnit> &CU : Dwarf.compile_units()) - Ret.push_back({Sec->OutSecOff + CU->getOffset(), CU->getLength() + 4}); + Ret.push_back({CU->getOffset(), CU->getLength() + 4}); return Ret; } @@ -1764,19 +1764,15 @@ static std::vector<InputSection *> getDebugInfoSections() { std::vector<InputSection *> Ret; for (InputSectionBase *S : InputSections) if (InputSection *IS = dyn_cast<InputSection>(S)) - if (IS->getParent() && IS->Name == ".debug_info") + if (IS->Name == ".debug_info") Ret.push_back(IS); return Ret; } void GdbIndexSection::buildIndex() { - std::vector<InputSection *> V = getDebugInfoSections(); - if (V.empty()) + if (Chunks.empty()) return; - for (InputSection *Sec : V) - Chunks.push_back(readDwarf(Sec)); - uint32_t CuId = 0; for (GdbIndexChunk &D : Chunks) { for (AddressEntry &E : D.AddressArea) @@ -1802,23 +1798,33 @@ void GdbIndexSection::buildIndex() { } } -GdbIndexChunk GdbIndexSection::readDwarf(InputSection *Sec) { - Expected<std::unique_ptr<object::ObjectFile>> Obj = - object::ObjectFile::createObjectFile(Sec->File->MB); - if (!Obj) { - error(toString(Sec->File) + ": error creating DWARF context"); - return {}; - } - - DWARFContextInMemory Dwarf(*Obj.get()); - +static GdbIndexChunk readDwarf(DWARFContextInMemory &Dwarf, InputSection *Sec) { GdbIndexChunk Ret; - Ret.CompilationUnits = readCuList(Dwarf, Sec); + Ret.DebugInfoSec = Sec; + Ret.CompilationUnits = readCuList(Dwarf); Ret.AddressArea = readAddressArea(Dwarf, Sec); Ret.NamesAndTypes = readPubNamesAndTypes(Dwarf, Config->IsLE); return Ret; } +template <class ELFT> GdbIndexSection *elf::createGdbIndex() { + std::vector<GdbIndexChunk> Chunks; + for (InputSection *Sec : getDebugInfoSections()) { + InputFile *F = Sec->File; + std::error_code EC; + ELFObjectFile<ELFT> Obj(F->MB, EC); + if (EC) + fatal(EC.message()); + DWARFContextInMemory Dwarf(Obj, nullptr, [&](Error E) { + error(toString(F) + ": error parsing DWARF data:\n>>> " + + toString(std::move(E))); + return ErrorPolicy::Continue; + }); + Chunks.push_back(readDwarf(Dwarf, Sec)); + } + return make<GdbIndexSection>(std::move(Chunks)); +} + static size_t getCuSize(std::vector<GdbIndexChunk> &C) { size_t Ret = 0; for (GdbIndexChunk &D : C) @@ -1876,7 +1882,7 @@ void GdbIndexSection::writeTo(uint8_t *Buf) { // Write the CU list. for (GdbIndexChunk &D : Chunks) { for (CompilationUnitEntry &Cu : D.CompilationUnits) { - write64le(Buf, Cu.CuOffset); + write64le(Buf, D.DebugInfoSec->OutSecOff + Cu.CuOffset); write64le(Buf + 8, Cu.CuLength); Buf += 16; } @@ -2345,6 +2351,11 @@ StringTableSection *InX::ShStrTab; StringTableSection *InX::StrTab; SymbolTableBaseSection *InX::SymTab; +template GdbIndexSection *elf::createGdbIndex<ELF32LE>(); +template GdbIndexSection *elf::createGdbIndex<ELF32BE>(); +template GdbIndexSection *elf::createGdbIndex<ELF64LE>(); +template GdbIndexSection *elf::createGdbIndex<ELF64BE>(); + template void PltSection::addEntry<ELF32LE>(SymbolBody &Sym); template void PltSection::addEntry<ELF32BE>(SymbolBody &Sym); template void PltSection::addEntry<ELF64LE>(SymbolBody &Sym); |