Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lld/ELF/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,8 @@ struct Ctx : CommonLinkerContext {
std::unique_ptr<llvm::TarWriter> tar;
// InputFile for linker created symbols with no source location.
InputFile *internalFile = nullptr;
// Dummy Undefined for relocations without a symbol.
Undefined *dummySym = nullptr;
// True if symbols can be exported (isExported) or preemptible.
bool hasDynsym = false;
// True if SHT_LLVM_SYMPART is used.
Expand Down
1 change: 1 addition & 0 deletions lld/ELF/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3138,6 +3138,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
ctx.symtab->insert(arg->getValue())->traced = true;

ctx.internalFile = createInternalFile(ctx, "<internal>");
ctx.dummySym = make<Undefined>(ctx.internalFile, "", STB_LOCAL, 0, 0);

// Handle -u/--undefined before input files. If both a.a and b.so define foo,
// -u foo a.a b.so will extract a.a.
Expand Down
13 changes: 6 additions & 7 deletions lld/ELF/Relocations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -887,7 +887,7 @@ static void addPltEntry(Ctx &ctx, PltSection &plt, GotPltSection &gotPlt,
gotPlt.addEntry(sym);
rel.addReloc({type, &gotPlt, sym.getGotPltOffset(ctx),
sym.isPreemptible ? DynamicReloc::AgainstSymbol
: DynamicReloc::AddendOnlyWithTargetVA,
: DynamicReloc::AddendOnly,
sym, 0, R_ABS});
}

Expand Down Expand Up @@ -927,8 +927,8 @@ static void addGotAuthEntry(Ctx &ctx, Symbol &sym) {

// Signed GOT requires dynamic relocation.
ctx.in.got->getPartition(ctx).relaDyn->addReloc(
{R_AARCH64_AUTH_RELATIVE, ctx.in.got.get(), off,
DynamicReloc::AddendOnlyWithTargetVA, sym, 0, R_ABS});
{R_AARCH64_AUTH_RELATIVE, ctx.in.got.get(), off, DynamicReloc::AddendOnly,
sym, 0, R_ABS});
}

static void addTpOffsetGotEntry(Ctx &ctx, Symbol &sym) {
Expand Down Expand Up @@ -1160,8 +1160,8 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
part.relrAuthDyn->relocs.push_back({sec, sec->relocs().size() - 1});
} else {
part.relaDyn->addReloc({R_AARCH64_AUTH_RELATIVE, sec, offset,
DynamicReloc::AddendOnlyWithTargetVA, sym,
addend, R_ABS});
DynamicReloc::AddendOnly, sym, addend,
R_ABS});
}
return;
}
Expand Down Expand Up @@ -1948,13 +1948,12 @@ void elf::postScanRelocations(Ctx &ctx) {

GotSection *got = ctx.in.got.get();
if (ctx.needsTlsLd.load(std::memory_order_relaxed) && got->addTlsIndex()) {
static Undefined dummy(ctx.internalFile, "", STB_LOCAL, 0, 0);
if (ctx.arg.shared)
ctx.mainPart->relaDyn->addReloc(
{ctx.target->tlsModuleIndexRel, got, got->getTlsIndexOff()});
else
got->addConstant({R_ADDEND, ctx.target->symbolicRel,
got->getTlsIndexOff(), 1, &dummy});
got->getTlsIndexOff(), 1, ctx.dummySym});
}

assert(ctx.symAux.size() == 1);
Expand Down
21 changes: 10 additions & 11 deletions lld/ELF/SyntheticSections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1122,8 +1122,8 @@ void MipsGotSection::build() {
for (const std::pair<GotEntry, size_t> &p : got.local16) {
uint64_t offset = p.second * ctx.arg.wordsize;
ctx.mainPart->relaDyn->addReloc({ctx.target->relativeRel, this, offset,
DynamicReloc::AddendOnlyWithTargetVA,
*p.first.first, p.first.second, R_ABS});
DynamicReloc::AddendOnly, *p.first.first,
p.first.second, R_ABS});
}
}
}
Expand Down Expand Up @@ -1647,18 +1647,17 @@ uint64_t DynamicReloc::getOffset() const {

int64_t DynamicReloc::computeAddend(Ctx &ctx) const {
switch (kind) {
case Computed:
llvm_unreachable("addend already computed");
case AddendOnly:
assert(sym == nullptr);
return addend;
case AgainstSymbol:
assert(sym != nullptr);
return addend;
case AddendOnlyWithTargetVA:
case AgainstSymbolWithTargetVA: {
uint64_t ca = inputSec->getRelocTargetVA(
ctx, Relocation{expr, type, 0, addend, sym}, getOffset());
return ctx.arg.is64 ? ca : SignExtend64<32>(ca);
}
case AgainstSymbol:
assert(sym != nullptr);
return addend;
case MipsMultiGotPage:
assert(sym == nullptr);
return getMipsPageAddr(outputSec->addr) + addend;
Expand Down Expand Up @@ -1703,8 +1702,8 @@ void RelocationBaseSection::addAddendOnlyRelocIfNonPreemptible(
addReloc({dynType, &isec, offsetInSec, DynamicReloc::AgainstSymbol, sym, 0,
R_ABS});
else
addReloc(DynamicReloc::AddendOnlyWithTargetVA, dynType, isec, offsetInSec,
sym, 0, R_ABS, addendRelType);
addReloc(DynamicReloc::AddendOnly, dynType, isec, offsetInSec, sym, 0,
R_ABS, addendRelType);
}

void RelocationBaseSection::mergeRels() {
Expand Down Expand Up @@ -1748,7 +1747,7 @@ void DynamicReloc::computeRaw(Ctx &ctx, SymbolTableBaseSection *symt) {
r_offset = getOffset();
r_sym = getSymIndex(symt);
addend = computeAddend(ctx);
kind = AddendOnly; // Catch errors
kind = Computed; // Catch errors
}

void RelocationBaseSection::computeRels() {
Expand Down
20 changes: 11 additions & 9 deletions lld/ELF/SyntheticSections.h
Original file line number Diff line number Diff line change
Expand Up @@ -419,13 +419,13 @@ class StringTableSection final : public SyntheticSection {
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(ctx).
AddendOnly,
/// The resulting dynamic relocation has already had its addend computed.
/// Calling computeAddend() is an error. Only for internal use.
Computed,
/// 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,
AddendOnly,
/// The resulting dynamic relocation references symbol #sym from the dynamic
/// symbol table and uses #addend as the value of computeAddend(ctx).
AgainstSymbol,
Expand All @@ -438,7 +438,7 @@ class DynamicReloc {
/// addresses of 64kb pages that lie inside the output section.
MipsMultiGotPage,
};
/// This constructor records a relocation against a symbol.
/// This constructor records a normal relocation.
DynamicReloc(RelType type, const InputSectionBase *inputSec,
uint64_t offsetInSec, Kind kind, Symbol &sym, int64_t addend,
RelExpr expr)
Expand All @@ -447,8 +447,9 @@ class DynamicReloc {
/// This constructor records a relative relocation with no symbol.
DynamicReloc(RelType type, const InputSectionBase *inputSec,
uint64_t offsetInSec, int64_t addend = 0)
: sym(nullptr), inputSec(inputSec), offsetInSec(offsetInSec), type(type),
addend(addend), kind(AddendOnly), expr(R_ADDEND) {}
: sym(inputSec->getCtx().dummySym), inputSec(inputSec),
offsetInSec(offsetInSec), type(type), addend(addend), kind(AddendOnly),
expr(R_ADDEND) {}
/// This constructor records dynamic relocation settings used by the MIPS
/// multi-GOT implementation.
DynamicReloc(RelType type, const InputSectionBase *inputSec,
Expand All @@ -461,6 +462,7 @@ class DynamicReloc {
uint64_t getOffset() const;
uint32_t getSymIndex(SymbolTableBaseSection *symTab) const;
bool needsDynSymIndex() const {
assert(kind != Computed && "cannot check kind after computeRaw");
return kind == AgainstSymbol || kind == AgainstSymbolWithTargetVA;
}

Expand Down Expand Up @@ -528,8 +530,8 @@ class RelocationBaseSection : public SyntheticSection {
uint64_t offsetInSec, Symbol &sym, int64_t addend,
RelType addendRelType, RelExpr expr) {
assert(expr != R_ADDEND && "expected non-addend relocation expression");
addReloc<shard>(DynamicReloc::AddendOnlyWithTargetVA, dynType, isec,
offsetInSec, sym, addend, expr, addendRelType);
addReloc<shard>(DynamicReloc::AddendOnly, dynType, isec, offsetInSec, sym,
addend, expr, addendRelType);
}
/// 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.
Expand Down
3 changes: 1 addition & 2 deletions lld/ELF/Target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,9 @@ ErrorPlace elf::getErrorPlace(Ctx &ctx, const uint8_t *loc) {
if (isecLoc <= loc && loc < isecLoc + isec->getSize()) {
std::string objLoc = isec->getLocation(loc - isecLoc);
// Return object file location and source file location.
Undefined dummy(ctx.internalFile, "", STB_LOCAL, 0, 0);
ELFSyncStream msg(ctx, DiagLevel::None);
if (isec->file)
msg << isec->getSrcMsg(dummy, loc - isecLoc);
msg << isec->getSrcMsg(*ctx.dummySym, loc - isecLoc);
return {isec, objLoc + ": ", std::string(msg.str())};
}
}
Expand Down
3 changes: 1 addition & 2 deletions lld/ELF/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1573,8 +1573,7 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
if (isInt<32>(reloc.sym->getVA(ctx, reloc.addend)))
return false;
part.relaDyn->addReloc({R_AARCH64_AUTH_RELATIVE, elem.inputSec,
reloc.offset,
DynamicReloc::AddendOnlyWithTargetVA,
reloc.offset, DynamicReloc::AddendOnly,
*reloc.sym, reloc.addend, R_ABS});
return true;
});
Expand Down
Loading