Skip to content

Commit 03be619

Browse files
committed
[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.
1 parent 09dd0fe commit 03be619

File tree

9 files changed

+89
-102
lines changed

9 files changed

+89
-102
lines changed

lld/ELF/Arch/Mips.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,9 @@ RelExpr MIPS<ELFT>::getRelExpr(RelType type, const Symbol &s,
121121
// offset between start of function and 'gp' value which by default
122122
// equal to the start of .got section. In that case we consider these
123123
// relocations as relative.
124-
if (&s == ElfSym::mipsGpDisp)
124+
if (&s == ctx.sym.mipsGpDisp)
125125
return R_MIPS_GOT_GP_PC;
126-
if (&s == ElfSym::mipsLocalGp)
126+
if (&s == ctx.sym.mipsLocalGp)
127127
return R_MIPS_GOT_GP;
128128
[[fallthrough]];
129129
case R_MIPS_32:

lld/ELF/Arch/RISCV.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
466466

467467
case INTERNAL_R_RISCV_GPREL_I:
468468
case INTERNAL_R_RISCV_GPREL_S: {
469-
Defined *gp = ElfSym::riscvGlobalPointer;
469+
Defined *gp = ctx.sym.riscvGlobalPointer;
470470
int64_t displace = SignExtend64(val - gp->getVA(), bits);
471471
checkInt(loc, displace, 12, rel);
472472
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,
789789

790790
static void relaxHi20Lo12(const InputSection &sec, size_t i, uint64_t loc,
791791
Relocation &r, uint32_t &remove) {
792-
const Defined *gp = ElfSym::riscvGlobalPointer;
792+
const Defined *gp = ctx.sym.riscvGlobalPointer;
793793
if (!gp)
794794
return;
795795

lld/ELF/Config.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class ELFFileBase;
4242
class SharedFile;
4343
class InputSectionBase;
4444
class EhInputSection;
45+
class Defined;
4546
class Symbol;
4647
class BitcodeCompiler;
4748
class OutputSection;
@@ -494,6 +495,46 @@ struct Ctx {
494495
};
495496
OutSections out;
496497

498+
// Some linker-generated symbols need to be created as
499+
// Defined symbols.
500+
struct ElfSym {
501+
// __bss_start
502+
Defined *bss;
503+
504+
// etext and _etext
505+
Defined *etext1;
506+
Defined *etext2;
507+
508+
// edata and _edata
509+
Defined *edata1;
510+
Defined *edata2;
511+
512+
// end and _end
513+
Defined *end1;
514+
Defined *end2;
515+
516+
// The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
517+
// be at some offset from the base of the .got section, usually 0 or
518+
// the end of the .got.
519+
Defined *globalOffsetTable;
520+
521+
// _gp, _gp_disp and __gnu_local_gp symbols. Only for MIPS.
522+
Defined *mipsGp;
523+
Defined *mipsGpDisp;
524+
Defined *mipsLocalGp;
525+
526+
// __global_pointer$ for RISC-V.
527+
Defined *riscvGlobalPointer;
528+
529+
// __rel{,a}_iplt_{start,end} symbols.
530+
Defined *relaIpltStart;
531+
Defined *relaIpltEnd;
532+
533+
// _TLS_MODULE_BASE_ on targets that support TLSDESC.
534+
Defined *tlsModuleBase;
535+
};
536+
ElfSym sym;
537+
497538
SmallVector<std::unique_ptr<MemoryBuffer>> memoryBuffers;
498539
SmallVector<ELFFileBase *, 0> objectFiles;
499540
SmallVector<SharedFile *, 0> sharedFiles;

lld/ELF/Driver.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ void Ctx::reset() {
9898
tlsPhdr = nullptr;
9999
out = OutSections{};
100100

101+
sym = ElfSym{};
102+
101103
memoryBuffers.clear();
102104
objectFiles.clear();
103105
sharedFiles.clear();

lld/ELF/InputSection.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,7 @@ static Relocation *getRISCVPCRelHi20(const Symbol *sym, uint64_t addend) {
665665
// target-specific adjustment to produce a thread-pointer-relative offset.
666666
static int64_t getTlsTpOffset(const Symbol &s) {
667667
// On targets that support TLSDESC, _TLS_MODULE_BASE_@tpoff = 0.
668-
if (&s == ElfSym::tlsModuleBase)
668+
if (&s == ctx.sym.tlsModuleBase)
669669
return 0;
670670

671671
// There are 2 TLS layouts. Among targets we support, x86 uses TLS Variant 2

lld/ELF/Symbols.cpp

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -58,22 +58,6 @@ std::string lld::toString(const elf::Symbol &sym) {
5858
return ret;
5959
}
6060

61-
Defined *ElfSym::bss;
62-
Defined *ElfSym::etext1;
63-
Defined *ElfSym::etext2;
64-
Defined *ElfSym::edata1;
65-
Defined *ElfSym::edata2;
66-
Defined *ElfSym::end1;
67-
Defined *ElfSym::end2;
68-
Defined *ElfSym::globalOffsetTable;
69-
Defined *ElfSym::mipsGp;
70-
Defined *ElfSym::mipsGpDisp;
71-
Defined *ElfSym::mipsLocalGp;
72-
Defined *ElfSym::riscvGlobalPointer;
73-
Defined *ElfSym::relaIpltStart;
74-
Defined *ElfSym::relaIpltEnd;
75-
Defined *ElfSym::tlsModuleBase;
76-
7761
static uint64_t getSymVA(const Symbol &sym, int64_t addend) {
7862
switch (sym.kind()) {
7963
case Symbol::DefinedKind: {

lld/ELF/Symbols.h

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -501,45 +501,6 @@ class LazySymbol : public Symbol {
501501
static bool classof(const Symbol *s) { return s->kind() == LazyKind; }
502502
};
503503

504-
// Some linker-generated symbols need to be created as
505-
// Defined symbols.
506-
struct ElfSym {
507-
// __bss_start
508-
static Defined *bss;
509-
510-
// etext and _etext
511-
static Defined *etext1;
512-
static Defined *etext2;
513-
514-
// edata and _edata
515-
static Defined *edata1;
516-
static Defined *edata2;
517-
518-
// end and _end
519-
static Defined *end1;
520-
static Defined *end2;
521-
522-
// The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
523-
// be at some offset from the base of the .got section, usually 0 or
524-
// the end of the .got.
525-
static Defined *globalOffsetTable;
526-
527-
// _gp, _gp_disp and __gnu_local_gp symbols. Only for MIPS.
528-
static Defined *mipsGp;
529-
static Defined *mipsGpDisp;
530-
static Defined *mipsLocalGp;
531-
532-
// __global_pointer$ for RISC-V.
533-
static Defined *riscvGlobalPointer;
534-
535-
// __rel{,a}_iplt_{start,end} symbols.
536-
static Defined *relaIpltStart;
537-
static Defined *relaIpltEnd;
538-
539-
// _TLS_MODULE_BASE_ on targets that support TLSDESC.
540-
static Defined *tlsModuleBase;
541-
};
542-
543504
// A buffer class that is large enough to hold any Symbol-derived
544505
// object. We allocate memory using this class and instantiate a symbol
545506
// using the placement new.

lld/ELF/SyntheticSections.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,7 @@ uint64_t GotSection::getGlobalDynOffset(const Symbol &b) const {
702702

703703
void GotSection::finalizeContents() {
704704
if (config->emachine == EM_PPC64 &&
705-
numEntries <= target->gotHeaderEntriesNum && !ElfSym::globalOffsetTable)
705+
numEntries <= target->gotHeaderEntriesNum && !ctx.sym.globalOffsetTable)
706706
size = 0;
707707
else
708708
size = numEntries * config->wordsize;
@@ -1090,7 +1090,7 @@ uint64_t MipsGotSection::getGp(const InputFile *f) const {
10901090
// returns "common" _gp value. For secondary GOTs calculate
10911091
// individual _gp values.
10921092
if (!f || f->mipsGotIndex == uint32_t(-1) || f->mipsGotIndex == 0)
1093-
return ElfSym::mipsGp->getVA(0);
1093+
return ctx.sym.mipsGp->getVA(0);
10941094
return getVA() + gots[f->mipsGotIndex].startIndex * config->wordsize + 0x7ff0;
10951095
}
10961096

@@ -4860,7 +4860,7 @@ template <class ELFT> void elf::createSyntheticSections() {
48604860

48614861
// _GLOBAL_OFFSET_TABLE_ is defined relative to either .got.plt or .got. Treat
48624862
// it as a relocation and ensure the referenced section is created.
4863-
if (ElfSym::globalOffsetTable && config->emachine != EM_MIPS) {
4863+
if (ctx.sym.globalOffsetTable && config->emachine != EM_MIPS) {
48644864
if (target->gotBaseSymInGotPlt)
48654865
in.gotPlt->hasGotPltOffRel = true;
48664866
else

lld/ELF/Writer.cpp

Lines changed: 38 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -167,19 +167,19 @@ void elf::addReservedSymbols() {
167167
// to GOT. Default offset is 0x7ff0.
168168
// See "Global Data Symbols" in Chapter 6 in the following document:
169169
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
170-
ElfSym::mipsGp = addAbsolute("_gp");
170+
ctx.sym.mipsGp = addAbsolute("_gp");
171171

172172
// On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between
173173
// start of function and 'gp' pointer into GOT.
174174
if (symtab.find("_gp_disp"))
175-
ElfSym::mipsGpDisp = addAbsolute("_gp_disp");
175+
ctx.sym.mipsGpDisp = addAbsolute("_gp_disp");
176176

177177
// The __gnu_local_gp is a magic symbol equal to the current value of 'gp'
178178
// pointer. This symbol is used in the code generated by .cpload pseudo-op
179179
// in case of using -mno-shared option.
180180
// https://sourceware.org/ml/binutils/2004-12/msg00094.html
181181
if (symtab.find("__gnu_local_gp"))
182-
ElfSym::mipsLocalGp = addAbsolute("__gnu_local_gp");
182+
ctx.sym.mipsLocalGp = addAbsolute("__gnu_local_gp");
183183
} else if (config->emachine == EM_PPC) {
184184
// glibc *crt1.o has a undefined reference to _SDA_BASE_. Since we don't
185185
// support Small Data Area, define it arbitrarily as 0.
@@ -212,7 +212,7 @@ void elf::addReservedSymbols() {
212212

213213
s->resolve(Defined{ctx.internalFile, StringRef(), STB_GLOBAL, STV_HIDDEN,
214214
STT_NOTYPE, gotOff, /*size=*/0, ctx.out.elfHeader});
215-
ElfSym::globalOffsetTable = cast<Defined>(s);
215+
ctx.sym.globalOffsetTable = cast<Defined>(s);
216216
}
217217

218218
// __ehdr_start is the location of ELF file headers. Note that we define
@@ -238,13 +238,13 @@ void elf::addReservedSymbols() {
238238
return addOptionalRegular(s, ctx.out.elfHeader, pos, STV_DEFAULT);
239239
};
240240

241-
ElfSym::bss = add("__bss_start", 0);
242-
ElfSym::end1 = add("end", -1);
243-
ElfSym::end2 = add("_end", -1);
244-
ElfSym::etext1 = add("etext", -1);
245-
ElfSym::etext2 = add("_etext", -1);
246-
ElfSym::edata1 = add("edata", -1);
247-
ElfSym::edata2 = add("_edata", -1);
241+
ctx.sym.bss = add("__bss_start", 0);
242+
ctx.sym.end1 = add("end", -1);
243+
ctx.sym.end2 = add("_end", -1);
244+
ctx.sym.etext1 = add("etext", -1);
245+
ctx.sym.etext2 = add("_etext", -1);
246+
ctx.sym.edata1 = add("edata", -1);
247+
ctx.sym.edata2 = add("_edata", -1);
248248
}
249249

250250
static void demoteDefined(Defined &sym, DenseMap<SectionBase *, size_t> &map) {
@@ -799,10 +799,10 @@ template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() {
799799
// We'll override ctx.out.elfHeader with relaDyn later when we are sure that
800800
// .rela.dyn will be present in the output.
801801
std::string name = config->isRela ? "__rela_iplt_start" : "__rel_iplt_start";
802-
ElfSym::relaIpltStart =
802+
ctx.sym.relaIpltStart =
803803
addOptionalRegular(name, ctx.out.elfHeader, 0, STV_HIDDEN);
804804
name.replace(name.size() - 5, 5, "end");
805-
ElfSym::relaIpltEnd =
805+
ctx.sym.relaIpltEnd =
806806
addOptionalRegular(name, ctx.out.elfHeader, 0, STV_HIDDEN);
807807
}
808808

@@ -812,21 +812,21 @@ template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() {
812812
// time any references to these symbols are processed and is equivalent to
813813
// defining these symbols explicitly in the linker script.
814814
template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {
815-
if (ElfSym::globalOffsetTable) {
815+
if (ctx.sym.globalOffsetTable) {
816816
// The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention usually
817817
// to the start of the .got or .got.plt section.
818818
InputSection *sec = in.gotPlt.get();
819819
if (!target->gotBaseSymInGotPlt)
820820
sec = in.mipsGot ? cast<InputSection>(in.mipsGot.get())
821821
: cast<InputSection>(in.got.get());
822-
ElfSym::globalOffsetTable->section = sec;
822+
ctx.sym.globalOffsetTable->section = sec;
823823
}
824824

825825
// .rela_iplt_{start,end} mark the start and the end of .rel[a].dyn.
826-
if (ElfSym::relaIpltStart && mainPart->relaDyn->isNeeded()) {
827-
ElfSym::relaIpltStart->section = mainPart->relaDyn.get();
828-
ElfSym::relaIpltEnd->section = mainPart->relaDyn.get();
829-
ElfSym::relaIpltEnd->value = mainPart->relaDyn->getSize();
826+
if (ctx.sym.relaIpltStart && mainPart->relaDyn->isNeeded()) {
827+
ctx.sym.relaIpltStart->section = mainPart->relaDyn.get();
828+
ctx.sym.relaIpltEnd->section = mainPart->relaDyn.get();
829+
ctx.sym.relaIpltEnd->value = mainPart->relaDyn->getSize();
830830
}
831831

832832
PhdrEntry *last = nullptr;
@@ -847,10 +847,10 @@ template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {
847847
if (lastRO) {
848848
// _etext is the first location after the last read-only loadable segment
849849
// that does not contain large sections.
850-
if (ElfSym::etext1)
851-
ElfSym::etext1->section = lastRO;
852-
if (ElfSym::etext2)
853-
ElfSym::etext2->section = lastRO;
850+
if (ctx.sym.etext1)
851+
ctx.sym.etext1->section = lastRO;
852+
if (ctx.sym.etext2)
853+
ctx.sym.etext2->section = lastRO;
854854
}
855855

856856
if (last) {
@@ -864,34 +864,34 @@ template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {
864864
break;
865865
}
866866

867-
if (ElfSym::edata1)
868-
ElfSym::edata1->section = edata;
869-
if (ElfSym::edata2)
870-
ElfSym::edata2->section = edata;
867+
if (ctx.sym.edata1)
868+
ctx.sym.edata1->section = edata;
869+
if (ctx.sym.edata2)
870+
ctx.sym.edata2->section = edata;
871871

872872
// _end is the first location after the uninitialized data region.
873-
if (ElfSym::end1)
874-
ElfSym::end1->section = last->lastSec;
875-
if (ElfSym::end2)
876-
ElfSym::end2->section = last->lastSec;
873+
if (ctx.sym.end1)
874+
ctx.sym.end1->section = last->lastSec;
875+
if (ctx.sym.end2)
876+
ctx.sym.end2->section = last->lastSec;
877877
}
878878

879-
if (ElfSym::bss) {
879+
if (ctx.sym.bss) {
880880
// On RISC-V, set __bss_start to the start of .sbss if present.
881881
OutputSection *sbss =
882882
config->emachine == EM_RISCV ? findSection(".sbss") : nullptr;
883-
ElfSym::bss->section = sbss ? sbss : findSection(".bss");
883+
ctx.sym.bss->section = sbss ? sbss : findSection(".bss");
884884
}
885885

886886
// Setup MIPS _gp_disp/__gnu_local_gp symbols which should
887887
// be equal to the _gp symbol's value.
888-
if (ElfSym::mipsGp) {
888+
if (ctx.sym.mipsGp) {
889889
// Find GP-relative section with the lowest address
890890
// and use this address to calculate default _gp value.
891891
for (OutputSection *os : outputSections) {
892892
if (os->flags & SHF_MIPS_GPREL) {
893-
ElfSym::mipsGp->section = os;
894-
ElfSym::mipsGp->value = 0x7ff0;
893+
ctx.sym.mipsGp->section = os;
894+
ctx.sym.mipsGp->value = 0x7ff0;
895895
break;
896896
}
897897
}
@@ -1725,7 +1725,6 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
17251725
// value/section does not matter but it has to be relative, so set its
17261726
// st_shndx arbitrarily to 1 (ctx.out.elfHeader).
17271727
if (config->emachine == EM_RISCV) {
1728-
ElfSym::riscvGlobalPointer = nullptr;
17291728
if (!config->shared) {
17301729
OutputSection *sec = findSection(".sdata");
17311730
addOptionalRegular("__global_pointer$", sec ? sec : ctx.out.elfHeader,
@@ -1735,7 +1734,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
17351734
if (config->relaxGP) {
17361735
Symbol *s = symtab.find("__global_pointer$");
17371736
if (s && s->isDefined())
1738-
ElfSym::riscvGlobalPointer = cast<Defined>(s);
1737+
ctx.sym.riscvGlobalPointer = cast<Defined>(s);
17391738
}
17401739
}
17411740
}
@@ -1757,7 +1756,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
17571756
s->resolve(Defined{ctx.internalFile, StringRef(), STB_GLOBAL,
17581757
STV_HIDDEN, STT_TLS, /*value=*/0, 0,
17591758
/*section=*/nullptr});
1760-
ElfSym::tlsModuleBase = cast<Defined>(s);
1759+
ctx.sym.tlsModuleBase = cast<Defined>(s);
17611760
}
17621761
}
17631762

0 commit comments

Comments
 (0)