[lld] 03be619 - [ELF] Move ElfSym into Ctx. NFC
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 3 11:20:37 PDT 2024
Author: Fangrui Song
Date: 2024-08-03T11:20:32-07:00
New Revision: 03be619d9434de0a9616660a2119675635239a5b
URL: https://github.com/llvm/llvm-project/commit/03be619d9434de0a9616660a2119675635239a5b
DIFF: https://github.com/llvm/llvm-project/commit/03be619d9434de0a9616660a2119675635239a5b.diff
LOG: [ELF] Move ElfSym into Ctx. NFC
Ctx was introduced in March 2022 as a more suitable place for such
singletons. ctx's hidden visibility optimizes generated instructions.
This change fixes a pitfall: certain ElfSym members (e.g.
globalOffsetTable, tlsModuleBase) were not zeroed and might be stale
when lld::elf::link was invoked the second time.
Added:
Modified:
lld/ELF/Arch/Mips.cpp
lld/ELF/Arch/RISCV.cpp
lld/ELF/Config.h
lld/ELF/Driver.cpp
lld/ELF/InputSection.cpp
lld/ELF/Symbols.cpp
lld/ELF/Symbols.h
lld/ELF/SyntheticSections.cpp
lld/ELF/Writer.cpp
Removed:
################################################################################
diff --git a/lld/ELF/Arch/Mips.cpp b/lld/ELF/Arch/Mips.cpp
index e36e9d59a7401..7c7137117d78e 100644
--- a/lld/ELF/Arch/Mips.cpp
+++ b/lld/ELF/Arch/Mips.cpp
@@ -121,9 +121,9 @@ RelExpr MIPS<ELFT>::getRelExpr(RelType type, const Symbol &s,
// offset between start of function and 'gp' value which by default
// equal to the start of .got section. In that case we consider these
// relocations as relative.
- if (&s == ElfSym::mipsGpDisp)
+ if (&s == ctx.sym.mipsGpDisp)
return R_MIPS_GOT_GP_PC;
- if (&s == ElfSym::mipsLocalGp)
+ if (&s == ctx.sym.mipsLocalGp)
return R_MIPS_GOT_GP;
[[fallthrough]];
case R_MIPS_32:
diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index 56759c28dcf41..8c2db2145f305 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -466,7 +466,7 @@ void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
case INTERNAL_R_RISCV_GPREL_I:
case INTERNAL_R_RISCV_GPREL_S: {
- Defined *gp = ElfSym::riscvGlobalPointer;
+ Defined *gp = ctx.sym.riscvGlobalPointer;
int64_t displace = SignExtend64(val - gp->getVA(), bits);
checkInt(loc, displace, 12, rel);
uint32_t insn = (read32le(loc) & ~(31 << 15)) | (X_GP << 15);
@@ -789,7 +789,7 @@ static void relaxTlsLe(const InputSection &sec, size_t i, uint64_t loc,
static void relaxHi20Lo12(const InputSection &sec, size_t i, uint64_t loc,
Relocation &r, uint32_t &remove) {
- const Defined *gp = ElfSym::riscvGlobalPointer;
+ const Defined *gp = ctx.sym.riscvGlobalPointer;
if (!gp)
return;
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 162631aaba42a..78bfea561445f 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -42,6 +42,7 @@ class ELFFileBase;
class SharedFile;
class InputSectionBase;
class EhInputSection;
+class Defined;
class Symbol;
class BitcodeCompiler;
class OutputSection;
@@ -494,6 +495,46 @@ struct Ctx {
};
OutSections out;
+ // Some linker-generated symbols need to be created as
+ // Defined symbols.
+ struct ElfSym {
+ // __bss_start
+ Defined *bss;
+
+ // etext and _etext
+ Defined *etext1;
+ Defined *etext2;
+
+ // edata and _edata
+ Defined *edata1;
+ Defined *edata2;
+
+ // end and _end
+ Defined *end1;
+ Defined *end2;
+
+ // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
+ // be at some offset from the base of the .got section, usually 0 or
+ // the end of the .got.
+ Defined *globalOffsetTable;
+
+ // _gp, _gp_disp and __gnu_local_gp symbols. Only for MIPS.
+ Defined *mipsGp;
+ Defined *mipsGpDisp;
+ Defined *mipsLocalGp;
+
+ // __global_pointer$ for RISC-V.
+ Defined *riscvGlobalPointer;
+
+ // __rel{,a}_iplt_{start,end} symbols.
+ Defined *relaIpltStart;
+ Defined *relaIpltEnd;
+
+ // _TLS_MODULE_BASE_ on targets that support TLSDESC.
+ Defined *tlsModuleBase;
+ };
+ ElfSym sym;
+
SmallVector<std::unique_ptr<MemoryBuffer>> memoryBuffers;
SmallVector<ELFFileBase *, 0> objectFiles;
SmallVector<SharedFile *, 0> sharedFiles;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 7b5b86363ac9c..9f03aaec864ca 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -98,6 +98,8 @@ void Ctx::reset() {
tlsPhdr = nullptr;
out = OutSections{};
+ sym = ElfSym{};
+
memoryBuffers.clear();
objectFiles.clear();
sharedFiles.clear();
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 7f8dded51fdab..da4c90516ec30 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -665,7 +665,7 @@ static Relocation *getRISCVPCRelHi20(const Symbol *sym, uint64_t addend) {
// target-specific adjustment to produce a thread-pointer-relative offset.
static int64_t getTlsTpOffset(const Symbol &s) {
// On targets that support TLSDESC, _TLS_MODULE_BASE_ at tpoff = 0.
- if (&s == ElfSym::tlsModuleBase)
+ if (&s == ctx.sym.tlsModuleBase)
return 0;
// There are 2 TLS layouts. Among targets we support, x86 uses TLS Variant 2
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index 9cab824c37c3c..4e1ae819b86fa 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -58,22 +58,6 @@ std::string lld::toString(const elf::Symbol &sym) {
return ret;
}
-Defined *ElfSym::bss;
-Defined *ElfSym::etext1;
-Defined *ElfSym::etext2;
-Defined *ElfSym::edata1;
-Defined *ElfSym::edata2;
-Defined *ElfSym::end1;
-Defined *ElfSym::end2;
-Defined *ElfSym::globalOffsetTable;
-Defined *ElfSym::mipsGp;
-Defined *ElfSym::mipsGpDisp;
-Defined *ElfSym::mipsLocalGp;
-Defined *ElfSym::riscvGlobalPointer;
-Defined *ElfSym::relaIpltStart;
-Defined *ElfSym::relaIpltEnd;
-Defined *ElfSym::tlsModuleBase;
-
static uint64_t getSymVA(const Symbol &sym, int64_t addend) {
switch (sym.kind()) {
case Symbol::DefinedKind: {
diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h
index ff825615658eb..05aed16bfb0dc 100644
--- a/lld/ELF/Symbols.h
+++ b/lld/ELF/Symbols.h
@@ -501,45 +501,6 @@ class LazySymbol : public Symbol {
static bool classof(const Symbol *s) { return s->kind() == LazyKind; }
};
-// Some linker-generated symbols need to be created as
-// Defined symbols.
-struct ElfSym {
- // __bss_start
- static Defined *bss;
-
- // etext and _etext
- static Defined *etext1;
- static Defined *etext2;
-
- // edata and _edata
- static Defined *edata1;
- static Defined *edata2;
-
- // end and _end
- static Defined *end1;
- static Defined *end2;
-
- // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
- // be at some offset from the base of the .got section, usually 0 or
- // the end of the .got.
- static Defined *globalOffsetTable;
-
- // _gp, _gp_disp and __gnu_local_gp symbols. Only for MIPS.
- static Defined *mipsGp;
- static Defined *mipsGpDisp;
- static Defined *mipsLocalGp;
-
- // __global_pointer$ for RISC-V.
- static Defined *riscvGlobalPointer;
-
- // __rel{,a}_iplt_{start,end} symbols.
- static Defined *relaIpltStart;
- static Defined *relaIpltEnd;
-
- // _TLS_MODULE_BASE_ on targets that support TLSDESC.
- static Defined *tlsModuleBase;
-};
-
// A buffer class that is large enough to hold any Symbol-derived
// object. We allocate memory using this class and instantiate a symbol
// using the placement new.
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 81068e65bcfea..c27ab2b67dc2b 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -702,7 +702,7 @@ uint64_t GotSection::getGlobalDynOffset(const Symbol &b) const {
void GotSection::finalizeContents() {
if (config->emachine == EM_PPC64 &&
- numEntries <= target->gotHeaderEntriesNum && !ElfSym::globalOffsetTable)
+ numEntries <= target->gotHeaderEntriesNum && !ctx.sym.globalOffsetTable)
size = 0;
else
size = numEntries * config->wordsize;
@@ -1090,7 +1090,7 @@ uint64_t MipsGotSection::getGp(const InputFile *f) const {
// returns "common" _gp value. For secondary GOTs calculate
// individual _gp values.
if (!f || f->mipsGotIndex == uint32_t(-1) || f->mipsGotIndex == 0)
- return ElfSym::mipsGp->getVA(0);
+ return ctx.sym.mipsGp->getVA(0);
return getVA() + gots[f->mipsGotIndex].startIndex * config->wordsize + 0x7ff0;
}
@@ -4860,7 +4860,7 @@ template <class ELFT> void elf::createSyntheticSections() {
// _GLOBAL_OFFSET_TABLE_ is defined relative to either .got.plt or .got. Treat
// it as a relocation and ensure the referenced section is created.
- if (ElfSym::globalOffsetTable && config->emachine != EM_MIPS) {
+ if (ctx.sym.globalOffsetTable && config->emachine != EM_MIPS) {
if (target->gotBaseSymInGotPlt)
in.gotPlt->hasGotPltOffRel = true;
else
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index bb4b958d87c42..648828e459824 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -167,19 +167,19 @@ void elf::addReservedSymbols() {
// to GOT. Default offset is 0x7ff0.
// See "Global Data Symbols" in Chapter 6 in the following document:
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
- ElfSym::mipsGp = addAbsolute("_gp");
+ ctx.sym.mipsGp = addAbsolute("_gp");
// On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between
// start of function and 'gp' pointer into GOT.
if (symtab.find("_gp_disp"))
- ElfSym::mipsGpDisp = addAbsolute("_gp_disp");
+ ctx.sym.mipsGpDisp = addAbsolute("_gp_disp");
// The __gnu_local_gp is a magic symbol equal to the current value of 'gp'
// pointer. This symbol is used in the code generated by .cpload pseudo-op
// in case of using -mno-shared option.
// https://sourceware.org/ml/binutils/2004-12/msg00094.html
if (symtab.find("__gnu_local_gp"))
- ElfSym::mipsLocalGp = addAbsolute("__gnu_local_gp");
+ ctx.sym.mipsLocalGp = addAbsolute("__gnu_local_gp");
} else if (config->emachine == EM_PPC) {
// glibc *crt1.o has a undefined reference to _SDA_BASE_. Since we don't
// support Small Data Area, define it arbitrarily as 0.
@@ -212,7 +212,7 @@ void elf::addReservedSymbols() {
s->resolve(Defined{ctx.internalFile, StringRef(), STB_GLOBAL, STV_HIDDEN,
STT_NOTYPE, gotOff, /*size=*/0, ctx.out.elfHeader});
- ElfSym::globalOffsetTable = cast<Defined>(s);
+ ctx.sym.globalOffsetTable = cast<Defined>(s);
}
// __ehdr_start is the location of ELF file headers. Note that we define
@@ -238,13 +238,13 @@ void elf::addReservedSymbols() {
return addOptionalRegular(s, ctx.out.elfHeader, pos, STV_DEFAULT);
};
- ElfSym::bss = add("__bss_start", 0);
- ElfSym::end1 = add("end", -1);
- ElfSym::end2 = add("_end", -1);
- ElfSym::etext1 = add("etext", -1);
- ElfSym::etext2 = add("_etext", -1);
- ElfSym::edata1 = add("edata", -1);
- ElfSym::edata2 = add("_edata", -1);
+ ctx.sym.bss = add("__bss_start", 0);
+ ctx.sym.end1 = add("end", -1);
+ ctx.sym.end2 = add("_end", -1);
+ ctx.sym.etext1 = add("etext", -1);
+ ctx.sym.etext2 = add("_etext", -1);
+ ctx.sym.edata1 = add("edata", -1);
+ ctx.sym.edata2 = add("_edata", -1);
}
static void demoteDefined(Defined &sym, DenseMap<SectionBase *, size_t> &map) {
@@ -799,10 +799,10 @@ template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() {
// We'll override ctx.out.elfHeader with relaDyn later when we are sure that
// .rela.dyn will be present in the output.
std::string name = config->isRela ? "__rela_iplt_start" : "__rel_iplt_start";
- ElfSym::relaIpltStart =
+ ctx.sym.relaIpltStart =
addOptionalRegular(name, ctx.out.elfHeader, 0, STV_HIDDEN);
name.replace(name.size() - 5, 5, "end");
- ElfSym::relaIpltEnd =
+ ctx.sym.relaIpltEnd =
addOptionalRegular(name, ctx.out.elfHeader, 0, STV_HIDDEN);
}
@@ -812,21 +812,21 @@ template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() {
// time any references to these symbols are processed and is equivalent to
// defining these symbols explicitly in the linker script.
template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {
- if (ElfSym::globalOffsetTable) {
+ if (ctx.sym.globalOffsetTable) {
// The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention usually
// to the start of the .got or .got.plt section.
InputSection *sec = in.gotPlt.get();
if (!target->gotBaseSymInGotPlt)
sec = in.mipsGot ? cast<InputSection>(in.mipsGot.get())
: cast<InputSection>(in.got.get());
- ElfSym::globalOffsetTable->section = sec;
+ ctx.sym.globalOffsetTable->section = sec;
}
// .rela_iplt_{start,end} mark the start and the end of .rel[a].dyn.
- if (ElfSym::relaIpltStart && mainPart->relaDyn->isNeeded()) {
- ElfSym::relaIpltStart->section = mainPart->relaDyn.get();
- ElfSym::relaIpltEnd->section = mainPart->relaDyn.get();
- ElfSym::relaIpltEnd->value = mainPart->relaDyn->getSize();
+ if (ctx.sym.relaIpltStart && mainPart->relaDyn->isNeeded()) {
+ ctx.sym.relaIpltStart->section = mainPart->relaDyn.get();
+ ctx.sym.relaIpltEnd->section = mainPart->relaDyn.get();
+ ctx.sym.relaIpltEnd->value = mainPart->relaDyn->getSize();
}
PhdrEntry *last = nullptr;
@@ -847,10 +847,10 @@ template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {
if (lastRO) {
// _etext is the first location after the last read-only loadable segment
// that does not contain large sections.
- if (ElfSym::etext1)
- ElfSym::etext1->section = lastRO;
- if (ElfSym::etext2)
- ElfSym::etext2->section = lastRO;
+ if (ctx.sym.etext1)
+ ctx.sym.etext1->section = lastRO;
+ if (ctx.sym.etext2)
+ ctx.sym.etext2->section = lastRO;
}
if (last) {
@@ -864,34 +864,34 @@ template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {
break;
}
- if (ElfSym::edata1)
- ElfSym::edata1->section = edata;
- if (ElfSym::edata2)
- ElfSym::edata2->section = edata;
+ if (ctx.sym.edata1)
+ ctx.sym.edata1->section = edata;
+ if (ctx.sym.edata2)
+ ctx.sym.edata2->section = edata;
// _end is the first location after the uninitialized data region.
- if (ElfSym::end1)
- ElfSym::end1->section = last->lastSec;
- if (ElfSym::end2)
- ElfSym::end2->section = last->lastSec;
+ if (ctx.sym.end1)
+ ctx.sym.end1->section = last->lastSec;
+ if (ctx.sym.end2)
+ ctx.sym.end2->section = last->lastSec;
}
- if (ElfSym::bss) {
+ if (ctx.sym.bss) {
// On RISC-V, set __bss_start to the start of .sbss if present.
OutputSection *sbss =
config->emachine == EM_RISCV ? findSection(".sbss") : nullptr;
- ElfSym::bss->section = sbss ? sbss : findSection(".bss");
+ ctx.sym.bss->section = sbss ? sbss : findSection(".bss");
}
// Setup MIPS _gp_disp/__gnu_local_gp symbols which should
// be equal to the _gp symbol's value.
- if (ElfSym::mipsGp) {
+ if (ctx.sym.mipsGp) {
// Find GP-relative section with the lowest address
// and use this address to calculate default _gp value.
for (OutputSection *os : outputSections) {
if (os->flags & SHF_MIPS_GPREL) {
- ElfSym::mipsGp->section = os;
- ElfSym::mipsGp->value = 0x7ff0;
+ ctx.sym.mipsGp->section = os;
+ ctx.sym.mipsGp->value = 0x7ff0;
break;
}
}
@@ -1725,7 +1725,6 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// value/section does not matter but it has to be relative, so set its
// st_shndx arbitrarily to 1 (ctx.out.elfHeader).
if (config->emachine == EM_RISCV) {
- ElfSym::riscvGlobalPointer = nullptr;
if (!config->shared) {
OutputSection *sec = findSection(".sdata");
addOptionalRegular("__global_pointer$", sec ? sec : ctx.out.elfHeader,
@@ -1735,7 +1734,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
if (config->relaxGP) {
Symbol *s = symtab.find("__global_pointer$");
if (s && s->isDefined())
- ElfSym::riscvGlobalPointer = cast<Defined>(s);
+ ctx.sym.riscvGlobalPointer = cast<Defined>(s);
}
}
}
@@ -1757,7 +1756,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
s->resolve(Defined{ctx.internalFile, StringRef(), STB_GLOBAL,
STV_HIDDEN, STT_TLS, /*value=*/0, 0,
/*section=*/nullptr});
- ElfSym::tlsModuleBase = cast<Defined>(s);
+ ctx.sym.tlsModuleBase = cast<Defined>(s);
}
}
More information about the llvm-commits
mailing list