Skip to content

Commit

Permalink
[ELF] Pass Ctx &
Browse files Browse the repository at this point in the history
  • Loading branch information
MaskRay committed Oct 12, 2024
1 parent 51a2f50 commit a3bad9a
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 38 deletions.
16 changes: 8 additions & 8 deletions lld/ELF/LinkerScript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,17 +196,17 @@ void LinkerScript::setDot(Expr e, const Twine &loc, bool inSec) {
// Used for handling linker symbol assignments, for both finalizing
// their values and doing early declarations. Returns true if symbol
// should be defined from linker script.
static bool shouldDefineSym(SymbolAssignment *cmd) {
static bool shouldDefineSym(Ctx &ctx, SymbolAssignment *cmd) {
if (cmd->name == ".")
return false;

return !cmd->provide || LinkerScript::shouldAddProvideSym(cmd->name);
return !cmd->provide || LinkerScript::shouldAddProvideSym(ctx, cmd->name);
}

// Called by processSymbolAssignments() to assign definitions to
// linker-script-defined symbols.
void LinkerScript::addSymbol(SymbolAssignment *cmd) {
if (!shouldDefineSym(cmd))
if (!shouldDefineSym(ctx, cmd))
return;

// Define a symbol.
Expand Down Expand Up @@ -240,7 +240,7 @@ void LinkerScript::addSymbol(SymbolAssignment *cmd) {
// This function is called from LinkerScript::declareSymbols.
// It creates a placeholder symbol if needed.
void LinkerScript::declareSymbol(SymbolAssignment *cmd) {
if (!shouldDefineSym(cmd))
if (!shouldDefineSym(ctx, cmd))
return;

uint8_t visibility = cmd->hidden ? STV_HIDDEN : STV_DEFAULT;
Expand Down Expand Up @@ -1798,30 +1798,30 @@ void LinkerScript::addScriptReferencedSymbolsToSymTable() {
DenseSet<StringRef> added;
SmallVector<const SmallVector<StringRef, 0> *, 0> symRefsVec;
for (const auto &[name, symRefs] : provideMap)
if (LinkerScript::shouldAddProvideSym(name) && added.insert(name).second)
if (shouldAddProvideSym(ctx, name) && added.insert(name).second)
symRefsVec.push_back(&symRefs);
while (symRefsVec.size()) {
for (StringRef name : *symRefsVec.pop_back_val()) {
reference(name);
// Prevent the symbol from being discarded by --gc-sections.
referencedSymbols.push_back(name);
auto it = provideMap.find(name);
if (it != provideMap.end() && shouldAddProvideSym(name) &&
if (it != provideMap.end() && shouldAddProvideSym(ctx, name) &&
added.insert(name).second) {
symRefsVec.push_back(&it->second);
}
}
}
}

bool LinkerScript::shouldAddProvideSym(StringRef symName) {
bool LinkerScript::shouldAddProvideSym(Ctx &ctx, StringRef symName) {
// This function is called before and after garbage collection. To prevent
// undefined references from the RHS, the result of this function for a
// symbol must be the same for each call. We use isUsedInRegularObj to not
// change the return value of a demoted symbol. The exportDynamic condition,
// while not so accurate, allows PROVIDE to define a symbol referenced by a
// DSO.
Symbol *sym = elf::ctx.symtab->find(symName);
Symbol *sym = ctx.symtab->find(symName);
return sym && !sym->isDefined() && !sym->isCommon() &&
(sym->isUsedInRegularObj || sym->exportDynamic);
}
2 changes: 1 addition & 1 deletion lld/ELF/LinkerScript.h
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ class LinkerScript final {
// Returns true if the PROVIDE symbol should be added to the link.
// A PROVIDE symbol is added to the link only if it satisfies an
// undefined reference.
static bool shouldAddProvideSym(StringRef symName);
static bool shouldAddProvideSym(Ctx &, StringRef symName);

// SECTIONS command list.
SmallVector<SectionCommand *, 0> sectionCommands;
Expand Down
8 changes: 4 additions & 4 deletions lld/ELF/Relocations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,7 @@ static void addRelativeReloc(Ctx &ctx, InputSectionBase &isec,
}

template <class PltSection, class GotPltSection>
static void addPltEntry(PltSection &plt, GotPltSection &gotPlt,
static void addPltEntry(Ctx &ctx, PltSection &plt, GotPltSection &gotPlt,
RelocationBaseSection &rel, RelType type, Symbol &sym) {
plt.addEntry(sym);
gotPlt.addEntry(sym);
Expand Down Expand Up @@ -1756,7 +1756,7 @@ static bool handleNonPreemptibleIfunc(Ctx &ctx, Symbol &sym, uint16_t flags) {
directSym->allocateAux(ctx);
auto &dyn =
ctx.arg.androidPackDynRelocs ? *ctx.in.relaPlt : *ctx.mainPart->relaDyn;
addPltEntry(*ctx.in.iplt, *ctx.in.igotPlt, dyn, ctx.target->iRelativeRel,
addPltEntry(ctx, *ctx.in.iplt, *ctx.in.igotPlt, dyn, ctx.target->iRelativeRel,
*directSym);
sym.allocateAux(ctx);
ctx.symAux.back().pltIdx = ctx.symAux[directSym->auxIdx].pltIdx;
Expand Down Expand Up @@ -1796,7 +1796,7 @@ void elf::postScanRelocations(Ctx &ctx) {
if (flags & NEEDS_GOT)
addGotEntry(ctx, sym);
if (flags & NEEDS_PLT)
addPltEntry(*ctx.in.plt, *ctx.in.gotPlt, *ctx.in.relaPlt,
addPltEntry(ctx, *ctx.in.plt, *ctx.in.gotPlt, *ctx.in.relaPlt,
ctx.target->pltRel, sym);
if (flags & NEEDS_COPY) {
if (sym.isObject()) {
Expand Down Expand Up @@ -2427,7 +2427,7 @@ void elf::hexagonTLSSymbolUpdate(Ctx &ctx) {
if (rel.sym->type == llvm::ELF::STT_TLS && rel.expr == R_PLT_PC) {
if (needEntry) {
sym->allocateAux(ctx);
addPltEntry(*ctx.in.plt, *ctx.in.gotPlt, *ctx.in.relaPlt,
addPltEntry(ctx, *ctx.in.plt, *ctx.in.gotPlt, *ctx.in.relaPlt,
ctx.target->pltRel, *sym);
needEntry = false;
}
Expand Down
41 changes: 22 additions & 19 deletions lld/ELF/SyntheticSections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ Defined *elf::addSyntheticLocal(Ctx &ctx, StringRef name, uint8_t type,
return s;
}

static size_t getHashSize() {
static size_t getHashSize(Ctx &ctx) {
switch (ctx.arg.buildId) {
case BuildIdKind::Fast:
return 8;
Expand Down Expand Up @@ -362,7 +362,7 @@ size_t GnuPropertySection::getSize() const {

BuildIdSection::BuildIdSection(Ctx &ctx)
: SyntheticSection(ctx, SHF_ALLOC, SHT_NOTE, 4, ".note.gnu.build-id"),
hashSize(getHashSize()) {}
hashSize(getHashSize(ctx)) {}

void BuildIdSection::writeTo(uint8_t *buf) {
write32(buf, 4); // Name size
Expand Down Expand Up @@ -1208,7 +1208,7 @@ bool GotPltSection::isNeeded() const {
return !entries.empty() || hasGotPltOffRel;
}

static StringRef getIgotPltName() {
static StringRef getIgotPltName(Ctx &ctx) {
// On ARM the IgotPltSection is part of the GotSection.
if (ctx.arg.emachine == EM_ARM)
return ".got";
Expand All @@ -1226,7 +1226,7 @@ static StringRef getIgotPltName() {
IgotPltSection::IgotPltSection(Ctx &ctx)
: SyntheticSection(ctx, SHF_ALLOC | SHF_WRITE,
ctx.arg.emachine == EM_PPC64 ? SHT_NOBITS : SHT_PROGBITS,
ctx.target->gotEntrySize, getIgotPltName()) {}
ctx.target->gotEntrySize, getIgotPltName(ctx)) {}

void IgotPltSection::addEntry(Symbol &sym) {
assert(ctx.symAux.back().pltIdx == entries.size());
Expand Down Expand Up @@ -1605,7 +1605,7 @@ uint64_t DynamicReloc::getOffset() const {
return inputSec->getVA(offsetInSec);
}

int64_t DynamicReloc::computeAddend() const {
int64_t DynamicReloc::computeAddend(Ctx &ctx) const {
switch (kind) {
case AddendOnly:
assert(sym == nullptr);
Expand Down Expand Up @@ -1704,17 +1704,18 @@ void RelocationBaseSection::finalizeContents() {
}
}

void DynamicReloc::computeRaw(SymbolTableBaseSection *symt) {
void DynamicReloc::computeRaw(Ctx &ctx, SymbolTableBaseSection *symt) {
r_offset = getOffset();
r_sym = getSymIndex(symt);
addend = computeAddend();
addend = computeAddend(ctx);
kind = AddendOnly; // Catch errors
}

void RelocationBaseSection::computeRels() {
SymbolTableBaseSection *symTab = getPartition().dynSymTab.get();
parallelForEach(relocs,
[symTab](DynamicReloc &rel) { rel.computeRaw(symTab); });
parallelForEach(relocs, [&ctx = ctx, symTab](DynamicReloc &rel) {
rel.computeRaw(ctx, symTab);
});

auto irelative = std::stable_partition(
relocs.begin() + numRelativeRelocs, relocs.end(),
Expand Down Expand Up @@ -1853,7 +1854,7 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize(Ctx &ctx) {
r.r_offset = rel.getOffset();
r.setSymbolAndType(rel.getSymIndex(getPartition().dynSymTab.get()),
rel.type, false);
r.r_addend = ctx.arg.isRela ? rel.computeAddend() : 0;
r.r_addend = ctx.arg.isRela ? rel.computeAddend(ctx) : 0;

if (r.getType(ctx.arg.isMips64EL) == ctx.target->relativeRel)
relatives.push_back(r);
Expand Down Expand Up @@ -3438,6 +3439,7 @@ readPubNamesAndTypes(const LLDDwarfObj<ELFT> &obj,
// by uniquifying them by name.
static std::pair<SmallVector<GdbIndexSection::GdbSymbol, 0>, size_t>
createSymbols(
Ctx &ctx,
ArrayRef<SmallVector<GdbIndexSection::NameAttrEntry, 0>> nameAttrs,
const SmallVector<GdbIndexSection::GdbChunk, 0> &chunks) {
using GdbSymbol = GdbIndexSection::GdbSymbol;
Expand Down Expand Up @@ -3563,7 +3565,8 @@ std::unique_ptr<GdbIndexSection> GdbIndexSection::create(Ctx &ctx) {

auto ret = std::make_unique<GdbIndexSection>(ctx);
ret->chunks = std::move(chunks);
std::tie(ret->symbols, ret->size) = createSymbols(nameAttrs, ret->chunks);
std::tie(ret->symbols, ret->size) =
createSymbols(ctx, nameAttrs, ret->chunks);

// Count the areas other than the constant pool.
ret->size += sizeof(GdbIndexHeader) + ret->computeSymtabSize() * 8;
Expand Down Expand Up @@ -3784,9 +3787,9 @@ bool VersionTableSection::isNeeded() const {
(getPartition().verDef || getPartition().verNeed->isNeeded());
}

void elf::addVerneed(Symbol *ss) {
auto &file = cast<SharedFile>(*ss->file);
if (ss->versionId == VER_NDX_GLOBAL)
void elf::addVerneed(Ctx &ctx, Symbol &ss) {
auto &file = cast<SharedFile>(*ss.file);
if (ss.versionId == VER_NDX_GLOBAL)
return;

if (file.vernauxs.empty())
Expand All @@ -3796,10 +3799,10 @@ void elf::addVerneed(Symbol *ss) {
// already allocated one. The verdef identifiers cover the range
// [1..getVerDefNum(ctx)]; this causes the vernaux identifiers to start from
// getVerDefNum(ctx)+1.
if (file.vernauxs[ss->versionId] == 0)
file.vernauxs[ss->versionId] = ++SharedFile::vernauxNum + getVerDefNum(ctx);
if (file.vernauxs[ss.versionId] == 0)
file.vernauxs[ss.versionId] = ++SharedFile::vernauxNum + getVerDefNum(ctx);

ss->versionId = file.vernauxs[ss->versionId];
ss.versionId = file.vernauxs[ss.versionId];
}

template <class ELFT>
Expand Down Expand Up @@ -4659,7 +4662,7 @@ size_t MemtagGlobalDescriptors::getSize() const {
return createMemtagGlobalDescriptors(ctx, symbols);
}

static OutputSection *findSection(StringRef name) {
static OutputSection *findSection(Ctx &ctx, StringRef name) {
for (SectionCommand *cmd : ctx.script->sectionCommands)
if (auto *osd = dyn_cast<OutputDesc>(cmd))
if (osd->osec.name == name)
Expand Down Expand Up @@ -4715,7 +4718,7 @@ template <class ELFT> void elf::createSyntheticSections(Ctx &ctx) {
// .data.rel.ro.bss so that we match in the .data.rel.ro output section.
// This makes sure our relro is contiguous.
bool hasDataRelRo =
ctx.script->hasSectionsCommand && findSection(".data.rel.ro");
ctx.script->hasSectionsCommand && findSection(ctx, ".data.rel.ro");
ctx.in.bssRelRo = std::make_unique<BssSection>(
ctx, hasDataRelRo ? ".data.rel.ro.bss" : ".bss.rel.ro", 0, 1);
add(*ctx.in.bssRelRo);
Expand Down
10 changes: 5 additions & 5 deletions lld/ELF/SyntheticSections.h
Original file line number Diff line number Diff line change
Expand Up @@ -411,14 +411,14 @@ class DynamicReloc {
public:
enum Kind {
/// The resulting dynamic relocation does not reference a symbol (#sym must
/// be nullptr) and uses #addend as the result of computeAddend().
/// be nullptr) and uses #addend as the result of computeAddend(ctx).
AddendOnly,
/// The resulting dynamic relocation will not reference a symbol: #sym is
/// only used to compute the addend with InputSection::getRelocTargetVA().
/// Useful for various relative and TLS relocations (e.g. R_X86_64_TPOFF64).
AddendOnlyWithTargetVA,
/// The resulting dynamic relocation references symbol #sym from the dynamic
/// symbol table and uses #addend as the value of computeAddend().
/// symbol table and uses #addend as the value of computeAddend(ctx).
AgainstSymbol,
/// The resulting dynamic relocation references symbol #sym from the dynamic
/// symbol table and uses InputSection::getRelocTargetVA() + #addend for the
Expand Down Expand Up @@ -458,9 +458,9 @@ class DynamicReloc {
/// Computes the addend of the dynamic relocation. Note that this is not the
/// same as the #addend member variable as it may also include the symbol
/// address/the address of the corresponding GOT entry/etc.
int64_t computeAddend() const;
int64_t computeAddend(Ctx &) const;

void computeRaw(SymbolTableBaseSection *symt);
void computeRaw(Ctx &, SymbolTableBaseSection *symt);

Symbol *sym;
const OutputSection *outputSec = nullptr;
Expand Down Expand Up @@ -1443,7 +1443,7 @@ Defined *addSyntheticLocal(Ctx &ctx, StringRef name, uint8_t type,
uint64_t value, uint64_t size,
InputSectionBase &section);

void addVerneed(Symbol *ss);
void addVerneed(Ctx &, Symbol &ss);

// Linker generated per-partition sections.
struct Partition {
Expand Down
2 changes: 1 addition & 1 deletion lld/ELF/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1879,7 +1879,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
ctx.partitions[sym->partition - 1].dynSymTab->addSymbol(sym);
if (auto *file = dyn_cast_or_null<SharedFile>(sym->file))
if (file->isNeeded && !sym->isUndefined())
addVerneed(sym);
addVerneed(ctx, *sym);
}
}

Expand Down

0 comments on commit a3bad9a

Please sign in to comment.