diff --git a/lld/ELF/DWARF.cpp b/lld/ELF/DWARF.cpp index 4d84c09a0185db..789820ba7a8e9c 100644 --- a/lld/ELF/DWARF.cpp +++ b/lld/ELF/DWARF.cpp @@ -27,8 +27,7 @@ using namespace lld::elf; template LLDDwarfObj::LLDDwarfObj(ObjFile *obj) { // Get the ELF sections to retrieve sh_flags. See the SHF_GROUP comment below. - ArrayRef objSections = - CHECK(obj->getObj().sections(), obj); + ArrayRef objSections = obj->template getELFShdrs(); assert(objSections.size() == obj->getSections().size()); for (auto it : llvm::enumerate(obj->getSections())) { InputSectionBase *sec = it.value(); diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index e4d3e1d50b0f3e..19266cb280b9ba 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -846,14 +846,13 @@ static bool processCallGraphRelocations(SmallVector &symbolIndices, ArrayRef &cgProfile, ObjFile *inputObj) { - symbolIndices.clear(); - const ELFFile &obj = inputObj->getObj(); - ArrayRef> objSections = - CHECK(obj.sections(), "could not retrieve object sections"); - if (inputObj->cgProfileSectionIndex == SHN_UNDEF) return false; + ArrayRef> objSections = + inputObj->template getELFShdrs(); + symbolIndices.clear(); + const ELFFile &obj = inputObj->getObj(); cgProfile = check(obj.template getSectionContentsAsArray( objSections[inputObj->cgProfileSectionIndex])); diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 964898fb790e7b..0badf2c55e5bf7 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -370,6 +370,8 @@ template void ELFFileBase::init() { abiVersion = obj.getHeader().e_ident[llvm::ELF::EI_ABIVERSION]; ArrayRef sections = CHECK(obj.sections(), this); + elfShdrs = sections.data(); + numELFShdrs = sections.size(); // Find a symbol table. bool isDSO = @@ -477,8 +479,7 @@ bool ObjFile::shouldMerge(const Elf_Shdr &sec, StringRef name) { // When the option is given, we link "just symbols". The section table is // initialized with null pointers. template void ObjFile::initializeJustSymbols() { - ArrayRef sections = CHECK(this->getObj().sections(), this); - this->sections.resize(sections.size()); + sections.resize(numELFShdrs); } // An ELF object file may contain a `.deplibs` section. If it exists, the @@ -544,7 +545,7 @@ template void ObjFile::initializeSections(bool ignoreComdats) { const ELFFile &obj = this->getObj(); - ArrayRef objSections = CHECK(obj.sections(), this); + ArrayRef objSections = getELFShdrs(); StringRef shstrtab = CHECK(obj.getSectionStringTable(objSections), this); uint64_t size = objSections.size(); this->sections.resize(size); @@ -1410,7 +1411,7 @@ template void SharedFile::parse() { ArrayRef dynamicTags; const ELFFile obj = this->getObj(); - ArrayRef sections = CHECK(obj.sections(), this); + ArrayRef sections = getELFShdrs(); const Elf_Shdr *versymSec = nullptr; const Elf_Shdr *verdefSec = nullptr; diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index 6111df5218407e..f58e76e484336f 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -189,6 +189,10 @@ class ELFFileBase : public InputFile { .slice(firstGlobal); } + template typename ELFT::ShdrRange getELFShdrs() const { + return typename ELFT::ShdrRange( + reinterpret_cast(elfShdrs), numELFShdrs); + } template typename ELFT::SymRange getELFSyms() const { return typename ELFT::SymRange( reinterpret_cast(elfSyms), numELFSyms); @@ -201,7 +205,9 @@ class ELFFileBase : public InputFile { // Initializes this class's member variables. template void init(); + const void *elfShdrs = nullptr; const void *elfSyms = nullptr; + uint32_t numELFShdrs = 0; uint32_t numELFSyms = 0; uint32_t firstGlobal = 0; StringRef stringTable; diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index e3871260fe5bc2..33a42ff3f4a52a 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -163,16 +163,16 @@ template RelsOrRelas InputSectionBase::relsOrRelas() const { if (relSecIdx == 0) return {}; RelsOrRelas ret; - const ELFFile obj = cast(file)->getObj(); - typename ELFT::Shdr shdr = cantFail(obj.sections())[relSecIdx]; + typename ELFT::Shdr shdr = + cast(file)->getELFShdrs()[relSecIdx]; if (shdr.sh_type == SHT_REL) { ret.rels = makeArrayRef(reinterpret_cast( - obj.base() + shdr.sh_offset), + file->mb.getBufferStart() + shdr.sh_offset), shdr.sh_size / sizeof(typename ELFT::Rel)); } else { assert(shdr.sh_type == SHT_RELA); ret.relas = makeArrayRef(reinterpret_cast( - obj.base() + shdr.sh_offset), + file->mb.getBufferStart() + shdr.sh_offset), shdr.sh_size / sizeof(typename ELFT::Rela)); } return ret; @@ -433,8 +433,7 @@ void InputSection::copyRelocations(uint8_t *buf, ArrayRef rels) { sec->name != ".gcc_except_table" && sec->name != ".got2" && sec->name != ".toc") { uint32_t secIdx = cast(sym).discardedSecIdx; - Elf_Shdr_Impl sec = - CHECK(file->getObj().sections(), file)[secIdx]; + Elf_Shdr_Impl sec = file->template getELFShdrs()[secIdx]; warn("relocation refers to a discarded section: " + CHECK(file->getObj().getSectionName(sec), file) + "\n>>> referenced by " + getObjMsg(p->r_offset)); diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 38e0d84e6271dc..23612ec48dedd0 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -472,8 +472,8 @@ static std::string maybeReportDiscarded(Undefined &sym) { if (!file || !sym.discardedSecIdx || file->getSections()[sym.discardedSecIdx] != &InputSection::discarded) return ""; - ArrayRef> objSections = - CHECK(file->getObj().sections(), file); + ArrayRef objSections = + file->template getELFShdrs(); std::string msg; if (sym.type == ELF::STT_SECTION) {