Skip to content

Commit

Permalink
[ELF] Add ELFFileBase::{elfShdrs,numELFShdrs} to avoid duplicate llvm…
Browse files Browse the repository at this point in the history
…::object::ELFFile::sections()

This mainly avoid `relsOrRelas` cost in `InputSectionBase::relocate`.
`llvm::object::ELFFile::sections()` has redundant and expensive checks.
  • Loading branch information
MaskRay committed Dec 25, 2021
1 parent 2709fd1 commit b5a0f0f
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 19 deletions.
3 changes: 1 addition & 2 deletions lld/ELF/DWARF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ using namespace lld::elf;

template <class ELFT> LLDDwarfObj<ELFT>::LLDDwarfObj(ObjFile<ELFT> *obj) {
// Get the ELF sections to retrieve sh_flags. See the SHF_GROUP comment below.
ArrayRef<typename ELFT::Shdr> objSections =
CHECK(obj->getObj().sections(), obj);
ArrayRef<typename ELFT::Shdr> objSections = obj->template getELFShdrs<ELFT>();
assert(objSections.size() == obj->getSections().size());
for (auto it : llvm::enumerate(obj->getSections())) {
InputSectionBase *sec = it.value();
Expand Down
9 changes: 4 additions & 5 deletions lld/ELF/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -846,14 +846,13 @@ static bool
processCallGraphRelocations(SmallVector<uint32_t, 32> &symbolIndices,
ArrayRef<typename ELFT::CGProfile> &cgProfile,
ObjFile<ELFT> *inputObj) {
symbolIndices.clear();
const ELFFile<ELFT> &obj = inputObj->getObj();
ArrayRef<Elf_Shdr_Impl<ELFT>> objSections =
CHECK(obj.sections(), "could not retrieve object sections");

if (inputObj->cgProfileSectionIndex == SHN_UNDEF)
return false;

ArrayRef<Elf_Shdr_Impl<ELFT>> objSections =
inputObj->template getELFShdrs<ELFT>();
symbolIndices.clear();
const ELFFile<ELFT> &obj = inputObj->getObj();
cgProfile =
check(obj.template getSectionContentsAsArray<typename ELFT::CGProfile>(
objSections[inputObj->cgProfileSectionIndex]));
Expand Down
9 changes: 5 additions & 4 deletions lld/ELF/InputFiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,8 @@ template <class ELFT> void ELFFileBase::init() {
abiVersion = obj.getHeader().e_ident[llvm::ELF::EI_ABIVERSION];

ArrayRef<Elf_Shdr> sections = CHECK(obj.sections(), this);
elfShdrs = sections.data();
numELFShdrs = sections.size();

// Find a symbol table.
bool isDSO =
Expand Down Expand Up @@ -477,8 +479,7 @@ bool ObjFile<ELFT>::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 <class ELFT> void ObjFile<ELFT>::initializeJustSymbols() {
ArrayRef<Elf_Shdr> 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
Expand Down Expand Up @@ -544,7 +545,7 @@ template <class ELFT>
void ObjFile<ELFT>::initializeSections(bool ignoreComdats) {
const ELFFile<ELFT> &obj = this->getObj();

ArrayRef<Elf_Shdr> objSections = CHECK(obj.sections(), this);
ArrayRef<Elf_Shdr> objSections = getELFShdrs<ELFT>();
StringRef shstrtab = CHECK(obj.getSectionStringTable(objSections), this);
uint64_t size = objSections.size();
this->sections.resize(size);
Expand Down Expand Up @@ -1410,7 +1411,7 @@ template <class ELFT> void SharedFile::parse() {

ArrayRef<Elf_Dyn> dynamicTags;
const ELFFile<ELFT> obj = this->getObj<ELFT>();
ArrayRef<Elf_Shdr> sections = CHECK(obj.sections(), this);
ArrayRef<Elf_Shdr> sections = getELFShdrs<ELFT>();

const Elf_Shdr *versymSec = nullptr;
const Elf_Shdr *verdefSec = nullptr;
Expand Down
6 changes: 6 additions & 0 deletions lld/ELF/InputFiles.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ class ELFFileBase : public InputFile {
.slice(firstGlobal);
}

template <typename ELFT> typename ELFT::ShdrRange getELFShdrs() const {
return typename ELFT::ShdrRange(
reinterpret_cast<const typename ELFT::Shdr *>(elfShdrs), numELFShdrs);
}
template <typename ELFT> typename ELFT::SymRange getELFSyms() const {
return typename ELFT::SymRange(
reinterpret_cast<const typename ELFT::Sym *>(elfSyms), numELFSyms);
Expand All @@ -201,7 +205,9 @@ class ELFFileBase : public InputFile {
// Initializes this class's member variables.
template <typename ELFT> void init();

const void *elfShdrs = nullptr;
const void *elfSyms = nullptr;
uint32_t numELFShdrs = 0;
uint32_t numELFSyms = 0;
uint32_t firstGlobal = 0;
StringRef stringTable;
Expand Down
11 changes: 5 additions & 6 deletions lld/ELF/InputSection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,16 +163,16 @@ template <class ELFT> RelsOrRelas<ELFT> InputSectionBase::relsOrRelas() const {
if (relSecIdx == 0)
return {};
RelsOrRelas<ELFT> ret;
const ELFFile<ELFT> obj = cast<ELFFileBase>(file)->getObj<ELFT>();
typename ELFT::Shdr shdr = cantFail(obj.sections())[relSecIdx];
typename ELFT::Shdr shdr =
cast<ELFFileBase>(file)->getELFShdrs<ELFT>()[relSecIdx];
if (shdr.sh_type == SHT_REL) {
ret.rels = makeArrayRef(reinterpret_cast<const typename ELFT::Rel *>(
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<const typename ELFT::Rela *>(
obj.base() + shdr.sh_offset),
file->mb.getBufferStart() + shdr.sh_offset),
shdr.sh_size / sizeof(typename ELFT::Rela));
}
return ret;
Expand Down Expand Up @@ -433,8 +433,7 @@ void InputSection::copyRelocations(uint8_t *buf, ArrayRef<RelTy> rels) {
sec->name != ".gcc_except_table" && sec->name != ".got2" &&
sec->name != ".toc") {
uint32_t secIdx = cast<Undefined>(sym).discardedSecIdx;
Elf_Shdr_Impl<ELFT> sec =
CHECK(file->getObj().sections(), file)[secIdx];
Elf_Shdr_Impl<ELFT> sec = file->template getELFShdrs<ELFT>()[secIdx];
warn("relocation refers to a discarded section: " +
CHECK(file->getObj().getSectionName(sec), file) +
"\n>>> referenced by " + getObjMsg(p->r_offset));
Expand Down
4 changes: 2 additions & 2 deletions lld/ELF/Relocations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -472,8 +472,8 @@ static std::string maybeReportDiscarded(Undefined &sym) {
if (!file || !sym.discardedSecIdx ||
file->getSections()[sym.discardedSecIdx] != &InputSection::discarded)
return "";
ArrayRef<Elf_Shdr_Impl<ELFT>> objSections =
CHECK(file->getObj().sections(), file);
ArrayRef<typename ELFT::Shdr> objSections =
file->template getELFShdrs<ELFT>();

std::string msg;
if (sym.type == ELF::STT_SECTION) {
Expand Down

0 comments on commit b5a0f0f

Please sign in to comment.