// 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) {
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
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) {
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");
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;
}
// 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
// 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)));
}
}
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) {
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
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:
// 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
}
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;
}
}
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);
}
}
}