[ELF] Add InputSectionBase::{addRelocs,relocs} and GotSection::addConstant to add/access relocations

to prepare for changing `relocations` from a SmallVector to a pointer.

Also change the `isec` parameter in `addAddendOnlyRelocIfNonPreemptible` to `GotSection &`.
This commit is contained in:
Fangrui Song
2022-11-21 04:12:03 +00:00
parent e2f8b801cb
commit c3c9e45312
14 changed files with 83 additions and 88 deletions

View File

@@ -544,10 +544,10 @@ static void implementPatch(uint64_t adrpAddr, uint64_t patcheeOffset,
// and replace the relocation with a R_AARCH_JUMP26 branch relocation.
// Case 4: No relocation. We must create a new R_AARCH64_JUMP26 branch
// relocation at the offset.
auto relIt = llvm::find_if(isec->relocations, [=](const Relocation &r) {
auto relIt = llvm::find_if(isec->relocs(), [=](const Relocation &r) {
return r.offset == patcheeOffset;
});
if (relIt != isec->relocations.end() &&
if (relIt != isec->relocs().end() &&
(relIt->type == R_AARCH64_JUMP26 || relIt->expr == R_RELAX_TLS_IE_TO_LE))
return;
@@ -561,12 +561,11 @@ static void implementPatch(uint64_t adrpAddr, uint64_t patcheeOffset,
return Relocation{R_PC, R_AARCH64_JUMP26, offset, 0, patchSym};
};
if (relIt != isec->relocations.end()) {
ps->relocations.push_back(
{relIt->expr, relIt->type, 0, relIt->addend, relIt->sym});
if (relIt != isec->relocs().end()) {
ps->addReloc({relIt->expr, relIt->type, 0, relIt->addend, relIt->sym});
*relIt = makeRelToPatch(patcheeOffset, ps->patchSym);
} else
isec->relocations.push_back(makeRelToPatch(patcheeOffset, ps->patchSym));
isec->addReloc(makeRelToPatch(patcheeOffset, ps->patchSym));
}
// Scan all the instructions in InputSectionDescription, for each instance of

View File

@@ -181,7 +181,7 @@ void Patch657417Section::writeTo(uint8_t *buf) {
else
write32le(buf, 0x9000f000);
// If we have a relocation then apply it.
if (!relocations.empty()) {
if (!relocs().empty()) {
target->relocateAlloc(*this, buf);
return;
}
@@ -281,12 +281,12 @@ static ScanResult scanCortexA8Errata657417(InputSection *isec, uint64_t &off,
// Find a relocation for the branch if it exists. This will be used
// to determine the target.
uint64_t branchOff = off + 4;
auto relIt = llvm::find_if(isec->relocations, [=](const Relocation &r) {
auto relIt = llvm::find_if(isec->relocs(), [=](const Relocation &r) {
return r.offset == branchOff &&
(r.type == R_ARM_THM_JUMP19 || r.type == R_ARM_THM_JUMP24 ||
r.type == R_ARM_THM_CALL);
});
if (relIt != isec->relocations.end())
if (relIt != isec->relocs().end())
scanRes.rel = &(*relIt);
if (branchDestInFirstRegion(isec, branchOff, instr2, scanRes.rel)) {
if (patchInRange(isec, branchOff, instr2)) {
@@ -451,7 +451,7 @@ static void implementPatch(ScanResult sr, InputSection *isec,
patchRelType = R_ARM_JUMP24;
patchRelAddend -= 4;
}
psec->relocations.push_back(
psec->addReloc(
Relocation{sr.rel->expr, patchRelType, 0, patchRelAddend, sr.rel->sym});
// Redirect the existing branch relocation to the patch.
sr.rel->expr = R_PC;
@@ -470,8 +470,7 @@ static void implementPatch(ScanResult sr, InputSection *isec,
type = R_ARM_THM_JUMP24;
else
type = R_ARM_THM_CALL;
isec->relocations.push_back(
Relocation{R_PC, type, sr.off, -4, psec->patchSym});
isec->addReloc(Relocation{R_PC, type, sr.off, -4, psec->patchSym});
}
patches.push_back(psec);
}

View File

@@ -747,9 +747,9 @@ void AArch64::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
uint64_t secAddr = sec.getOutputSection()->addr;
if (auto *s = dyn_cast<InputSection>(&sec))
secAddr += s->outSecOff;
AArch64Relaxer relaxer(sec.relocations);
for (size_t i = 0, size = sec.relocations.size(); i != size; ++i) {
const Relocation &rel = sec.relocations[i];
AArch64Relaxer relaxer(sec.relocs());
for (size_t i = 0, size = sec.relocs().size(); i != size; ++i) {
const Relocation &rel = sec.relocs()[i];
uint8_t *loc = buf + rel.offset;
const uint64_t val =
sec.getRelocTargetVA(sec.file, rel.type, rel.addend,
@@ -757,14 +757,14 @@ void AArch64::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
switch (rel.expr) {
case R_AARCH64_GOT_PAGE_PC:
if (i + 1 < size &&
relaxer.tryRelaxAdrpLdr(rel, sec.relocations[i + 1], secAddr, buf)) {
relaxer.tryRelaxAdrpLdr(rel, sec.relocs()[i + 1], secAddr, buf)) {
++i;
continue;
}
break;
case R_AARCH64_PAGE_PC:
if (i + 1 < size &&
relaxer.tryRelaxAdrpAdd(rel, sec.relocations[i + 1], secAddr, buf)) {
relaxer.tryRelaxAdrpAdd(rel, sec.relocs()[i + 1], secAddr, buf)) {
++i;
continue;
}

View File

@@ -486,7 +486,7 @@ void PPC::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
uint64_t secAddr = sec.getOutputSection()->addr;
if (auto *s = dyn_cast<InputSection>(&sec))
secAddr += s->outSecOff;
for (const Relocation &rel : sec.relocations) {
for (const Relocation &rel : sec.relocs()) {
uint8_t *loc = buf + rel.offset;
const uint64_t val = SignExtend64(
sec.getRelocTargetVA(sec.file, rel.type, rel.addend,

View File

@@ -1518,7 +1518,7 @@ void PPC64::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
if (auto *s = dyn_cast<InputSection>(&sec))
secAddr += s->outSecOff;
uint64_t lastPPCRelaxedRelocOff = -1;
for (const Relocation &rel : sec.relocations) {
for (const Relocation &rel : sec.relocs()) {
uint8_t *loc = buf + rel.offset;
const uint64_t val =
sec.getRelocTargetVA(sec.file, rel.type, rel.addend,

View File

@@ -513,11 +513,11 @@ static void initSymbolAnchors() {
continue;
for (InputSection *sec : getInputSections(*osec, storage)) {
sec->relaxAux = make<RISCVRelaxAux>();
if (sec->relocations.size()) {
if (sec->relocs().size()) {
sec->relaxAux->relocDeltas =
std::make_unique<uint32_t[]>(sec->relocations.size());
std::make_unique<uint32_t[]>(sec->relocs().size());
sec->relaxAux->relocTypes =
std::make_unique<RelType[]>(sec->relocations.size());
std::make_unique<RelType[]>(sec->relocs().size());
}
}
}
@@ -617,7 +617,7 @@ static bool relax(InputSection &sec) {
DenseMap<const Defined *, uint64_t> valueDelta;
ArrayRef<SymbolAnchor> sa = makeArrayRef(aux.anchors);
uint32_t delta = 0;
for (auto [i, r] : llvm::enumerate(sec.relocations)) {
for (auto [i, r] : llvm::enumerate(sec.relocs())) {
for (; sa.size() && sa[0].offset <= r.offset; sa = sa.slice(1))
if (!sa[0].end)
valueDelta[sa[0].d] = delta;
@@ -629,9 +629,9 @@ static bool relax(InputSection &sec) {
sa = makeArrayRef(aux.anchors);
delta = 0;
std::fill_n(aux.relocTypes.get(), sec.relocations.size(), R_RISCV_NONE);
std::fill_n(aux.relocTypes.get(), sec.relocs().size(), R_RISCV_NONE);
aux.writes.clear();
for (auto [i, r] : llvm::enumerate(sec.relocations)) {
for (auto [i, r] : llvm::enumerate(sec.relocs())) {
const uint64_t loc = secAddr + r.offset - delta;
uint32_t &cur = aux.relocDeltas[i], remove = 0;
switch (r.type) {
@@ -646,16 +646,16 @@ static bool relax(InputSection &sec) {
}
case R_RISCV_CALL:
case R_RISCV_CALL_PLT:
if (i + 1 != sec.relocations.size() &&
sec.relocations[i + 1].type == R_RISCV_RELAX)
if (i + 1 != sec.relocs().size() &&
sec.relocs()[i + 1].type == R_RISCV_RELAX)
relaxCall(sec, i, loc, r, remove);
break;
case R_RISCV_TPREL_HI20:
case R_RISCV_TPREL_ADD:
case R_RISCV_TPREL_LO12_I:
case R_RISCV_TPREL_LO12_S:
if (i + 1 != sec.relocations.size() &&
sec.relocations[i + 1].type == R_RISCV_RELAX)
if (i + 1 != sec.relocs().size() &&
sec.relocs()[i + 1].type == R_RISCV_RELAX)
relaxTlsLe(sec, i, loc, r, remove);
break;
}
@@ -727,10 +727,9 @@ void elf::riscvFinalizeRelax(int passes) {
if (!aux.relocDeltas)
continue;
auto &rels = sec->relocations;
MutableArrayRef<Relocation> rels = sec->relocs();
ArrayRef<uint8_t> old = sec->content();
size_t newSize =
old.size() - aux.relocDeltas[sec->relocations.size() - 1];
size_t newSize = old.size() - aux.relocDeltas[rels.size() - 1];
size_t writesIdx = 0;
uint8_t *p = context().bAlloc.Allocate<uint8_t>(newSize);
uint64_t offset = 0;

View File

@@ -472,7 +472,7 @@ void X86::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
uint64_t secAddr = sec.getOutputSection()->addr;
if (auto *s = dyn_cast<InputSection>(&sec))
secAddr += s->outSecOff;
for (const Relocation &rel : sec.relocations) {
for (const Relocation &rel : sec.relocs()) {
uint8_t *loc = buf + rel.offset;
const uint64_t val = SignExtend64(
sec.getRelocTargetVA(sec.file, rel.type, rel.addend,

View File

@@ -151,9 +151,9 @@ static JmpInsnOpcode getJmpInsnType(const uint8_t *first,
// Returns the maximum size of the vector if no such relocation is found.
static unsigned getRelocationWithOffset(const InputSection &is,
uint64_t offset) {
unsigned size = is.relocations.size();
unsigned size = is.relocs().size();
for (unsigned i = size - 1; i + 1 > 0; --i) {
if (is.relocations[i].offset == offset && is.relocations[i].expr != R_NONE)
if (is.relocs()[i].offset == offset && is.relocs()[i].expr != R_NONE)
return i;
}
return size;
@@ -247,10 +247,10 @@ bool X86_64::deleteFallThruJmpInsn(InputSection &is, InputFile *file,
// If this jmp insn can be removed, it is the last insn and the
// relocation is 4 bytes before the end.
unsigned rIndex = getRelocationWithOffset(is, is.getSize() - 4);
if (rIndex == is.relocations.size())
if (rIndex == is.relocs().size())
return false;
Relocation &r = is.relocations[rIndex];
Relocation &r = is.relocs()[rIndex];
// Check if the relocation corresponds to a direct jmp.
const uint8_t *secContents = is.content().data();
@@ -275,10 +275,10 @@ bool X86_64::deleteFallThruJmpInsn(InputSection &is, InputFile *file,
unsigned rbIndex =
getRelocationWithOffset(is, (is.getSize() - sizeOfDirectJmpInsn - 4));
if (rbIndex == is.relocations.size())
if (rbIndex == is.relocs().size())
return false;
Relocation &rB = is.relocations[rbIndex];
Relocation &rB = is.relocs()[rbIndex];
const uint8_t *jmpInsnB = secContents + rB.offset - 1;
JmpInsnOpcode jmpOpcodeB = getJmpInsnType(jmpInsnB - 1, jmpInsnB);
@@ -989,7 +989,7 @@ void X86_64::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
uint64_t secAddr = sec.getOutputSection()->addr;
if (auto *s = dyn_cast<InputSection>(&sec))
secAddr += s->outSecOff;
for (const Relocation &rel : sec.relocations) {
for (const Relocation &rel : sec.relocs()) {
if (rel.expr == R_NONE) // See deleteFallThruJmpInsn
continue;
uint8_t *loc = buf + rel.offset;

View File

@@ -432,7 +432,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)
sec->relocations.push_back({R_ABS, type, rel.r_offset, addend, &sym});
sec->addReloc({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) {
// Similar to R_MIPS_GPREL{16,32}. If the addend of R_PPC_PLTREL24
@@ -561,7 +561,7 @@ static Relocation *getRISCVPCRelHi20(const Symbol *sym, uint64_t addend) {
Relocation r;
r.offset = d->value;
auto range =
std::equal_range(isec->relocations.begin(), isec->relocations.end(), r,
std::equal_range(isec->relocs().begin(), isec->relocs().end(), r,
[](const Relocation &lhs, const Relocation &rhs) {
return lhs.offset < rhs.offset;
});
@@ -950,7 +950,7 @@ void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) {
static void relocateNonAllocForRelocatable(InputSection *sec, uint8_t *buf) {
const unsigned bits = config->is64 ? 64 : 32;
for (const Relocation &rel : sec->relocations) {
for (const Relocation &rel : sec->relocs()) {
// InputSection::copyRelocations() adds only R_ABS relocations.
assert(rel.expr == R_ABS);
uint8_t *bufLoc = buf + rel.offset;
@@ -1037,7 +1037,7 @@ void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *buf,
DenseSet<Defined *> prologues;
SmallVector<Relocation *, 0> morestackCalls;
for (Relocation &rel : relocations) {
for (Relocation &rel : relocs()) {
// Ignore calls into the split-stack api.
if (rel.sym->getName().startswith("__morestack")) {
if (rel.sym->getName().equals("__morestack"))

View File

@@ -210,6 +210,10 @@ public:
// This vector contains such "cooked" relocations.
SmallVector<Relocation, 0> relocations;
void addReloc(const Relocation &r) { relocations.push_back(r); }
MutableArrayRef<Relocation> relocs() { return relocations; }
ArrayRef<Relocation> relocs() const { return relocations; }
union {
// These are modifiers to jump instructions that are necessary when basic
// block sections are enabled. Basic block sections creates opportunities

View File

@@ -856,7 +856,7 @@ static void addRelativeReloc(InputSectionBase &isec, uint64_t offsetInSec,
// don't store the addend values, so we must write it to the relocated
// address.
if (part.relrDyn && isec.alignment >= 2 && offsetInSec % 2 == 0) {
isec.relocations.push_back({expr, type, offsetInSec, addend, &sym});
isec.addReloc({expr, type, offsetInSec, addend, &sym});
if (shard)
part.relrDyn->relocsVec[parallel::getThreadIndex()].push_back(
{&isec, offsetInSec});
@@ -893,7 +893,7 @@ static void addGotEntry(Symbol &sym) {
// Otherwise, the value is either a link-time constant or the load base
// plus a constant.
if (!config->isPic || isAbsolute(sym))
in.got->relocations.push_back({R_ABS, target->symbolicRel, off, 0, &sym});
in.got->addConstant({R_ABS, target->symbolicRel, off, 0, &sym});
else
addRelativeReloc(*in.got, off, sym, 0, R_ABS, target->symbolicRel);
}
@@ -902,7 +902,7 @@ static void addTpOffsetGotEntry(Symbol &sym) {
in.got->addEntry(sym);
uint64_t off = sym.getGotOffset();
if (!sym.isPreemptible && !config->isPic) {
in.got->relocations.push_back({R_TPREL, target->symbolicRel, off, 0, &sym});
in.got->addConstant({R_TPREL, target->symbolicRel, off, 0, &sym});
return;
}
mainPart->relaDyn->addAddendOnlyRelocIfNonPreemptible(
@@ -1075,8 +1075,8 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
// handling of GOT-generating relocations.
if (isStaticLinkTimeConstant(expr, type, sym, offset) ||
(!config->isPic && sym.isUndefWeak())) {
sec->relocations.push_back({expr, type, offset, addend, &sym});
return;
sec->addReloc({expr, type, offset, addend, &sym});
return;
}
bool canWrite = (sec->flags & SHF_WRITE) || !config->zText;
@@ -1132,7 +1132,7 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
getLocation(*sec, sym, offset));
sym.setFlags(NEEDS_COPY);
}
sec->relocations.push_back({expr, type, offset, addend, &sym});
sec->addReloc({expr, type, offset, addend, &sym});
return;
}
@@ -1169,7 +1169,7 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
"' cannot be preempted; recompile with -fPIE" +
getLocation(*sec, sym, offset));
sym.setFlags(NEEDS_COPY | NEEDS_PLT);
sec->relocations.push_back({expr, type, offset, addend, &sym});
sec->addReloc({expr, type, offset, addend, &sym});
return;
}
}
@@ -1191,12 +1191,12 @@ static unsigned handleMipsTlsRelocation(RelType type, Symbol &sym,
int64_t addend, RelExpr expr) {
if (expr == R_MIPS_TLSLD) {
in.mipsGot->addTlsIndex(*c.file);
c.relocations.push_back({expr, type, offset, addend, &sym});
c.addReloc({expr, type, offset, addend, &sym});
return 1;
}
if (expr == R_MIPS_TLSGD) {
in.mipsGot->addDynTlsEntry(*c.file, sym);
c.relocations.push_back({expr, type, offset, addend, &sym});
c.addReloc({expr, type, offset, addend, &sym});
return 1;
}
return 0;
@@ -1229,7 +1229,7 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
config->shared) {
if (expr != R_TLSDESC_CALL) {
sym.setFlags(NEEDS_TLSDESC);
c.relocations.push_back({expr, type, offset, addend, &sym});
c.addReloc({expr, type, offset, addend, &sym});
}
return 1;
}
@@ -1259,15 +1259,14 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
expr)) {
// Local-Dynamic relocs can be relaxed to Local-Exec.
if (toExecRelax) {
c.relocations.push_back(
{target->adjustTlsExpr(type, R_RELAX_TLS_LD_TO_LE), type, offset,
addend, &sym});
c.addReloc({target->adjustTlsExpr(type, R_RELAX_TLS_LD_TO_LE), type,
offset, addend, &sym});
return target->getTlsGdRelaxSkip(type);
}
if (expr == R_TLSLD_HINT)
return 1;
ctx.needsTlsLd.store(true, std::memory_order_relaxed);
c.relocations.push_back({expr, type, offset, addend, &sym});
c.addReloc({expr, type, offset, addend, &sym});
return 1;
}
@@ -1275,7 +1274,7 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
if (expr == R_DTPREL) {
if (toExecRelax)
expr = target->adjustTlsExpr(type, R_RELAX_TLS_LD_TO_LE);
c.relocations.push_back({expr, type, offset, addend, &sym});
c.addReloc({expr, type, offset, addend, &sym});
return 1;
}
@@ -1283,7 +1282,7 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
// thread pointer is stored in the got. This cannot be relaxed to Local-Exec.
if (expr == R_TLSLD_GOT_OFF) {
sym.setFlags(NEEDS_GOT_DTPREL);
c.relocations.push_back({expr, type, offset, addend, &sym});
c.addReloc({expr, type, offset, addend, &sym});
return 1;
}
@@ -1291,7 +1290,7 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
R_TLSDESC_GOTPLT, R_TLSGD_GOT, R_TLSGD_GOTPLT, R_TLSGD_PC>(expr)) {
if (!toExecRelax) {
sym.setFlags(NEEDS_TLSGD);
c.relocations.push_back({expr, type, offset, addend, &sym});
c.addReloc({expr, type, offset, addend, &sym});
return 1;
}
@@ -1299,13 +1298,11 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
// depending on the symbol being locally defined or not.
if (sym.isPreemptible) {
sym.setFlags(NEEDS_TLSGD_TO_IE);
c.relocations.push_back(
{target->adjustTlsExpr(type, R_RELAX_TLS_GD_TO_IE), type, offset,
addend, &sym});
c.addReloc({target->adjustTlsExpr(type, R_RELAX_TLS_GD_TO_IE), type,
offset, addend, &sym});
} else {
c.relocations.push_back(
{target->adjustTlsExpr(type, R_RELAX_TLS_GD_TO_LE), type, offset,
addend, &sym});
c.addReloc({target->adjustTlsExpr(type, R_RELAX_TLS_GD_TO_LE), type,
offset, addend, &sym});
}
return target->getTlsGdRelaxSkip(type);
}
@@ -1316,15 +1313,14 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
// Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally
// defined.
if (toExecRelax && isLocalInExecutable) {
c.relocations.push_back(
{R_RELAX_TLS_IE_TO_LE, type, offset, addend, &sym});
c.addReloc({R_RELAX_TLS_IE_TO_LE, type, offset, addend, &sym});
} else if (expr != R_TLSIE_HINT) {
sym.setFlags(NEEDS_TLSIE);
// R_GOT needs a relative relocation for PIC on i386 and Hexagon.
if (expr == R_GOT && config->isPic && !target->usesOnlyLowPageBits(type))
addRelativeReloc<true>(c, offset, sym, addend, expr, type);
else
c.relocations.push_back({expr, type, offset, addend, &sym});
c.addReloc({expr, type, offset, addend, &sym});
}
return 1;
}
@@ -1487,7 +1483,7 @@ void RelocationScanner::scan(ArrayRef<RelTy> rels) {
// R_RISCV_PCREL_HI20 and R_PPC64_ADDR64.
if (config->emachine == EM_RISCV ||
(config->emachine == EM_PPC64 && sec->name == ".toc"))
llvm::stable_sort(sec->relocations,
llvm::stable_sort(sec->relocs(),
[](const Relocation &lhs, const Relocation &rhs) {
return lhs.offset < rhs.offset;
});
@@ -1677,8 +1673,7 @@ void elf::postScanRelocations() {
uint64_t off = in.got->getGlobalDynOffset(sym);
if (isLocalInExecutable)
// Write one to the GOT slot.
in.got->relocations.push_back(
{R_ADDEND, target->symbolicRel, off, 1, &sym});
in.got->addConstant({R_ADDEND, target->symbolicRel, off, 1, &sym});
else
mainPart->relaDyn->addSymbolReloc(target->tlsModuleIndexRel, *in.got,
off, sym);
@@ -1690,8 +1685,7 @@ void elf::postScanRelocations() {
mainPart->relaDyn->addSymbolReloc(target->tlsOffsetRel, *in.got,
offsetOff, sym);
else
in.got->relocations.push_back(
{R_ABS, target->tlsOffsetRel, offsetOff, 0, &sym});
in.got->addConstant({R_ABS, target->tlsOffsetRel, offsetOff, 0, &sym});
}
if (flags & NEEDS_TLSGD_TO_IE) {
in.got->addEntry(sym);
@@ -1700,7 +1694,7 @@ void elf::postScanRelocations() {
}
if (flags & NEEDS_GOT_DTPREL) {
in.got->addEntry(sym);
in.got->relocations.push_back(
in.got->addConstant(
{R_ABS, target->tlsOffsetRel, sym.getGotOffset(), 0, &sym});
}
@@ -1714,7 +1708,7 @@ void elf::postScanRelocations() {
mainPart->relaDyn->addReloc(
{target->tlsModuleIndexRel, in.got.get(), in.got->getTlsIndexOff()});
else
in.got->relocations.push_back(
in.got->addConstant(
{R_ADDEND, target->symbolicRel, in.got->getTlsIndexOff(), 1, &dummy});
}
@@ -2164,7 +2158,7 @@ bool ThunkCreator::createThunks(uint32_t pass,
forEachInputSectionDescription(
outputSections, [&](OutputSection *os, InputSectionDescription *isd) {
for (InputSection *isec : isd->sections)
for (Relocation &rel : isec->relocations) {
for (Relocation &rel : isec->relocs()) {
uint64_t src = isec->getVA(rel.offset);
// If we are a relocation to an existing Thunk, check if it is
@@ -2224,7 +2218,7 @@ bool elf::hexagonNeedsTLSSymbol(ArrayRef<OutputSection *> outputSections) {
forEachInputSectionDescription(
outputSections, [&](OutputSection *os, InputSectionDescription *isd) {
for (InputSection *isec : isd->sections)
for (Relocation &rel : isec->relocations)
for (Relocation &rel : isec->relocs())
if (rel.sym->type == llvm::ELF::STT_TLS && rel.expr == R_PLT_PC) {
needTlsSymbol = true;
return;
@@ -2241,7 +2235,7 @@ void elf::hexagonTLSSymbolUpdate(ArrayRef<OutputSection *> outputSections) {
forEachInputSectionDescription(
outputSections, [&](OutputSection *os, InputSectionDescription *isd) {
for (InputSection *isec : isd->sections)
for (Relocation &rel : isec->relocations)
for (Relocation &rel : isec->relocs())
if (rel.sym->type == llvm::ELF::STT_TLS && rel.expr == R_PLT_PC) {
if (needEntry) {
sym->allocateAux();

View File

@@ -618,6 +618,7 @@ GotSection::GotSection()
numEntries = target->gotHeaderEntriesNum;
}
void GotSection::addConstant(const Relocation &r) { relocations.push_back(r); }
void GotSection::addEntry(Symbol &sym) {
assert(sym.auxIdx == symAux.size() - 1);
symAux.back().gotIdx = numEntries++;
@@ -1589,14 +1590,14 @@ void RelocationBaseSection::addSymbolReloc(RelType dynType,
}
void RelocationBaseSection::addAddendOnlyRelocIfNonPreemptible(
RelType dynType, InputSectionBase &isec, uint64_t offsetInSec, Symbol &sym,
RelType dynType, GotSection &sec, uint64_t offsetInSec, Symbol &sym,
RelType addendRelType) {
// No need to write an addend to the section for preemptible symbols.
if (sym.isPreemptible)
addReloc({dynType, &isec, offsetInSec, DynamicReloc::AgainstSymbol, sym, 0,
addReloc({dynType, &sec, offsetInSec, DynamicReloc::AgainstSymbol, sym, 0,
R_ABS});
else
addReloc(DynamicReloc::AddendOnlyWithTargetVA, dynType, isec, offsetInSec,
addReloc(DynamicReloc::AddendOnlyWithTargetVA, dynType, sec, offsetInSec,
sym, 0, R_ABS, addendRelType);
}

View File

@@ -103,6 +103,7 @@ public:
bool isNeeded() const override;
void writeTo(uint8_t *buf) override;
void addConstant(const Relocation &r);
void addEntry(Symbol &sym);
bool addTlsDescEntry(Symbol &sym);
bool addDynTlsEntry(Symbol &sym);
@@ -515,8 +516,7 @@ public:
}
/// Add a dynamic relocation using the target address of \p sym as the addend
/// if \p sym is non-preemptible. Otherwise add a relocation against \p sym.
void addAddendOnlyRelocIfNonPreemptible(RelType dynType,
InputSectionBase &isec,
void addAddendOnlyRelocIfNonPreemptible(RelType dynType, GotSection &sec,
uint64_t offsetInSec, Symbol &sym,
RelType addendRelType);
template <bool shard = false>
@@ -526,8 +526,7 @@ public:
// Write the addends to the relocated address if required. We skip
// it if the written value would be zero.
if (config->writeAddends && (expr != R_ADDEND || addend != 0))
sec.relocations.push_back(
{expr, addendRelType, offsetInSec, addend, &sym});
sec.addReloc({expr, addendRelType, offsetInSec, addend, &sym});
addReloc<shard>({dynType, &sec, offsetInSec, kind, sym, addend, expr});
}
bool isNeeded() const override {

View File

@@ -157,7 +157,7 @@ void TargetInfo::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
uint64_t secAddr = sec.getOutputSection()->addr;
if (auto *s = dyn_cast<InputSection>(&sec))
secAddr += s->outSecOff;
for (const Relocation &rel : sec.relocations) {
for (const Relocation &rel : sec.relocs()) {
uint8_t *loc = buf + rel.offset;
const uint64_t val = SignExtend64(
sec.getRelocTargetVA(sec.file, rel.type, rel.addend,