Skip to content

Commit

Permalink
[ELF] Cache global variable target in relocate*
Browse files Browse the repository at this point in the history
This avoid repeated load of the unique_ptr in hot paths.
  • Loading branch information
MaskRay committed Dec 25, 2021
1 parent b5a0f0f commit 745420d
Showing 1 changed file with 24 additions and 21 deletions.
45 changes: 24 additions & 21 deletions lld/ELF/InputSection.cpp
Expand Up @@ -395,6 +395,7 @@ InputSectionBase *InputSection::getRelocatedSection() const {
// for each relocation. So we copy relocations one by one.
template <class ELFT, class RelTy>
void InputSection::copyRelocations(uint8_t *buf, ArrayRef<RelTy> rels) {
const TargetInfo &target = *elf::target;
InputSectionBase *sec = getRelocatedSection();

for (const RelTy &rel : rels) {
Expand Down Expand Up @@ -450,10 +451,10 @@ void InputSection::copyRelocations(uint8_t *buf, ArrayRef<RelTy> rels) {
int64_t addend = getAddend<ELFT>(rel);
const uint8_t *bufLoc = sec->data().begin() + rel.r_offset;
if (!RelTy::IsRela)
addend = target->getImplicitAddend(bufLoc, type);
addend = target.getImplicitAddend(bufLoc, type);

if (config->emachine == EM_MIPS &&
target->getRelExpr(type, sym, bufLoc) == R_MIPS_GOTREL) {
target.getRelExpr(type, sym, bufLoc) == R_MIPS_GOTREL) {
// Some MIPS relocations depend on "gp" value. By default,
// this value has 0x7ff0 offset from a .got section. But
// relocatable files produced by a compiler or a linker
Expand All @@ -470,7 +471,7 @@ void InputSection::copyRelocations(uint8_t *buf, ArrayRef<RelTy> rels) {

if (RelTy::IsRela)
p->r_addend = sym.getVA(addend) - section->getOutputSection()->addr;
else if (config->relocatable && type != target->noneRel)
else if (config->relocatable && type != target.noneRel)
sec->relocations.push_back({R_ABS, type, rel.r_offset, addend, &sym});
} else if (config->emachine == EM_PPC && type == R_PPC_PLTREL24 &&
p->r_addend >= 0x8000 && sec->file->ppc32Got2) {
Expand Down Expand Up @@ -864,6 +865,7 @@ uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type,
template <class ELFT, class RelTy>
void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) {
const unsigned bits = sizeof(typename ELFT::uint) * 8;
const TargetInfo &target = *elf::target;
const bool isDebug = isDebugSection(*this);
const bool isDebugLocOrRanges =
isDebug && (name == ".debug_loc" || name == ".debug_ranges");
Expand All @@ -889,16 +891,16 @@ void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) {
uint8_t *bufLoc = buf + offset;
int64_t addend = getAddend<ELFT>(rel);
if (!RelTy::IsRela)
addend += target->getImplicitAddend(bufLoc, type);
addend += target.getImplicitAddend(bufLoc, type);

Symbol &sym = getFile<ELFT>()->getRelocTargetSym(rel);
RelExpr expr = target->getRelExpr(type, sym, bufLoc);
RelExpr expr = target.getRelExpr(type, sym, bufLoc);
if (expr == R_NONE)
continue;

if (expr == R_SIZE) {
target->relocateNoSym(bufLoc, type,
SignExtend64<bits>(sym.getSize() + addend));
target.relocateNoSym(bufLoc, type,
SignExtend64<bits>(sym.getSize() + addend));
continue;
}

Expand All @@ -922,14 +924,14 @@ void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) {
// address 0. For bug-compatibilty, we accept them with warnings. We
// know Steel Bank Common Lisp as of 2018 have this bug.
warn(msg);
target->relocateNoSym(
target.relocateNoSym(
bufLoc, type,
SignExtend64<bits>(sym.getVA(addend - offset - outSecOff)));
continue;
}

if (tombstone ||
(isDebug && (type == target->symbolicRel || expr == R_DTPREL))) {
(isDebug && (type == target.symbolicRel || expr == R_DTPREL))) {
// Resolve relocations in .debug_* referencing (discarded symbols or ICF
// folded section symbols) to a tombstone value. Resolving to addend is
// unsatisfactory because the result address range may collide with a
Expand Down Expand Up @@ -963,11 +965,11 @@ void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) {
// If -z dead-reloc-in-nonalloc= is specified, respect it.
const uint64_t value = tombstone ? SignExtend64<bits>(*tombstone)
: (isDebugLocOrRanges ? 1 : 0);
target->relocateNoSym(bufLoc, type, value);
target.relocateNoSym(bufLoc, type, value);
continue;
}
}
target->relocateNoSym(bufLoc, type, SignExtend64<bits>(sym.getVA(addend)));
target.relocateNoSym(bufLoc, type, SignExtend64<bits>(sym.getVA(addend)));
}
}

Expand Down Expand Up @@ -1013,6 +1015,7 @@ void InputSectionBase::relocate(uint8_t *buf, uint8_t *bufEnd) {
void InputSectionBase::relocateAlloc(uint8_t *buf, uint8_t *bufEnd) {
assert(flags & SHF_ALLOC);
const unsigned bits = config->wordsize * 8;
const TargetInfo &target = *elf::target;
uint64_t lastPPCRelaxedRelocOff = UINT64_C(-1);

for (const Relocation &rel : relocations) {
Expand All @@ -1031,7 +1034,7 @@ void InputSectionBase::relocateAlloc(uint8_t *buf, uint8_t *bufEnd) {
switch (rel.expr) {
case R_RELAX_GOT_PC:
case R_RELAX_GOT_PC_NOPIC:
target->relaxGot(bufLoc, rel, targetVA);
target.relaxGot(bufLoc, rel, targetVA);
break;
case R_PPC64_RELAX_GOT_PC: {
// The R_PPC64_PCREL_OPT relocation must appear immediately after
Expand All @@ -1044,7 +1047,7 @@ void InputSectionBase::relocateAlloc(uint8_t *buf, uint8_t *bufEnd) {
lastPPCRelaxedRelocOff = offset;
if (rel.type == R_PPC64_PCREL_OPT && offset != lastPPCRelaxedRelocOff)
break;
target->relaxGot(bufLoc, rel, targetVA);
target.relaxGot(bufLoc, rel, targetVA);
break;
}
case R_PPC64_RELAX_TOC:
Expand All @@ -1055,25 +1058,25 @@ void InputSectionBase::relocateAlloc(uint8_t *buf, uint8_t *bufEnd) {
// opportunities but is safe.
if (ppc64noTocRelax.count({rel.sym, rel.addend}) ||
!tryRelaxPPC64TocIndirection(rel, bufLoc))
target->relocate(bufLoc, rel, targetVA);
target.relocate(bufLoc, rel, targetVA);
break;
case R_RELAX_TLS_IE_TO_LE:
target->relaxTlsIeToLe(bufLoc, rel, targetVA);
target.relaxTlsIeToLe(bufLoc, rel, targetVA);
break;
case R_RELAX_TLS_LD_TO_LE:
case R_RELAX_TLS_LD_TO_LE_ABS:
target->relaxTlsLdToLe(bufLoc, rel, targetVA);
target.relaxTlsLdToLe(bufLoc, rel, targetVA);
break;
case R_RELAX_TLS_GD_TO_LE:
case R_RELAX_TLS_GD_TO_LE_NEG:
target->relaxTlsGdToLe(bufLoc, rel, targetVA);
target.relaxTlsGdToLe(bufLoc, rel, targetVA);
break;
case R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC:
case R_RELAX_TLS_GD_TO_IE:
case R_RELAX_TLS_GD_TO_IE_ABS:
case R_RELAX_TLS_GD_TO_IE_GOT_OFF:
case R_RELAX_TLS_GD_TO_IE_GOTPLT:
target->relaxTlsGdToIe(bufLoc, rel, targetVA);
target.relaxTlsGdToIe(bufLoc, rel, targetVA);
break;
case R_PPC64_CALL:
// If this is a call to __tls_get_addr, it may be part of a TLS
Expand All @@ -1098,10 +1101,10 @@ void InputSectionBase::relocateAlloc(uint8_t *buf, uint8_t *bufEnd) {
}
write32(bufLoc + 4, 0xe8410018); // ld %r2, 24(%r1)
}
target->relocate(bufLoc, rel, targetVA);
target.relocate(bufLoc, rel, targetVA);
break;
default:
target->relocate(bufLoc, rel, targetVA);
target.relocate(bufLoc, rel, targetVA);
break;
}
}
Expand All @@ -1114,7 +1117,7 @@ void InputSectionBase::relocateAlloc(uint8_t *buf, uint8_t *bufEnd) {
for (const JumpInstrMod &jumpMod : jumpInstrMods) {
uint64_t offset = jumpMod.offset;
uint8_t *bufLoc = buf + offset;
target->applyJumpInstrMod(bufLoc, jumpMod.original, jumpMod.size);
target.applyJumpInstrMod(bufLoc, jumpMod.original, jumpMod.size);
}
}
}
Expand Down

0 comments on commit 745420d

Please sign in to comment.