Skip to content

Commit cc6c059

Browse files
committed
[ELF] Pass Ctx & to Writer
1 parent 1747318 commit cc6c059

File tree

3 files changed

+44
-40
lines changed

3 files changed

+44
-40
lines changed

lld/ELF/LinkerScript.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1343,7 +1343,7 @@ void LinkerScript::adjustOutputSections() {
13431343
if (isEmpty) {
13441344
sec->flags =
13451345
flags & ((sec->nonAlloc ? 0 : (uint64_t)SHF_ALLOC) | SHF_WRITE);
1346-
sec->sortRank = getSectionRank(*sec);
1346+
sec->sortRank = getSectionRank(ctx, *sec);
13471347
}
13481348

13491349
// The code below may remove empty output sections. We should save the

lld/ELF/Writer.cpp

+42-38
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,8 @@ static void demoteSymbolsAndComputeIsPreemptible(Ctx &ctx) {
294294
}
295295
}
296296

297-
static OutputSection *findSection(StringRef name, unsigned partition = 1) {
297+
static OutputSection *findSection(Ctx &ctx, StringRef name,
298+
unsigned partition = 1) {
298299
for (SectionCommand *cmd : ctx.script->sectionCommands)
299300
if (auto *osd = dyn_cast<OutputDesc>(cmd))
300301
if (osd->osec.name == name && osd->osec.partition == partition)
@@ -544,7 +545,7 @@ template <class ELFT> void Writer<ELFT>::addSectionSymbols() {
544545
//
545546
// This function returns true if a section needs to be put into a
546547
// PT_GNU_RELRO segment.
547-
static bool isRelroSection(const OutputSection *sec) {
548+
static bool isRelroSection(Ctx &ctx, const OutputSection *sec) {
548549
if (!ctx.arg.zRelro)
549550
return false;
550551
if (sec->relro)
@@ -648,7 +649,7 @@ enum RankFlags {
648649
RF_BSS = 1 << 7,
649650
};
650651

651-
unsigned elf::getSectionRank(OutputSection &osec) {
652+
unsigned elf::getSectionRank(Ctx &ctx, OutputSection &osec) {
652653
unsigned rank = osec.partition * RF_PARTITION;
653654

654655
// We want to put section specified by -T option first, so we
@@ -713,7 +714,7 @@ unsigned elf::getSectionRank(OutputSection &osec) {
713714
// TLS sections directly before the other RELRO sections.
714715
if (!(osec.flags & SHF_TLS))
715716
rank |= RF_NOT_TLS;
716-
if (isRelroSection(&osec))
717+
if (isRelroSection(ctx, &osec))
717718
osec.relro = true;
718719
else
719720
rank |= RF_NOT_RELRO;
@@ -892,8 +893,8 @@ template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {
892893
if (ctx.sym.bss) {
893894
// On RISC-V, set __bss_start to the start of .sbss if present.
894895
OutputSection *sbss =
895-
ctx.arg.emachine == EM_RISCV ? findSection(".sbss") : nullptr;
896-
ctx.sym.bss->section = sbss ? sbss : findSection(".bss");
896+
ctx.arg.emachine == EM_RISCV ? findSection(ctx, ".sbss") : nullptr;
897+
ctx.sym.bss->section = sbss ? sbss : findSection(ctx, ".bss");
897898
}
898899

899900
// Setup MIPS _gp_disp/__gnu_local_gp symbols which should
@@ -946,7 +947,7 @@ static bool shouldSkip(SectionCommand *cmd) {
946947
// characteristics with their neighbors as possible. For example, if
947948
// both are rw, or both are tls.
948949
static SmallVectorImpl<SectionCommand *>::iterator
949-
findOrphanPos(SmallVectorImpl<SectionCommand *>::iterator b,
950+
findOrphanPos(Ctx &ctx, SmallVectorImpl<SectionCommand *>::iterator b,
950951
SmallVectorImpl<SectionCommand *>::iterator e) {
951952
// Place non-alloc orphan sections at the end. This matches how we assign file
952953
// offsets to non-alloc sections.
@@ -1028,7 +1029,8 @@ findOrphanPos(SmallVectorImpl<SectionCommand *>::iterator b,
10281029
}
10291030

10301031
// Adds random priorities to sections not already in the map.
1031-
static void maybeShuffle(DenseMap<const InputSectionBase *, int> &order) {
1032+
static void maybeShuffle(Ctx &ctx,
1033+
DenseMap<const InputSectionBase *, int> &order) {
10321034
if (ctx.arg.shuffleSections.empty())
10331035
return;
10341036

@@ -1066,7 +1068,7 @@ static void maybeShuffle(DenseMap<const InputSectionBase *, int> &order) {
10661068
}
10671069

10681070
// Builds section order for handling --symbol-ordering-file.
1069-
static DenseMap<const InputSectionBase *, int> buildSectionOrder() {
1071+
static DenseMap<const InputSectionBase *, int> buildSectionOrder(Ctx &ctx) {
10701072
DenseMap<const InputSectionBase *, int> sectionOrder;
10711073
// Use the rarely used option --call-graph-ordering-file to sort sections.
10721074
if (!ctx.arg.callGraphProfile.empty())
@@ -1125,7 +1127,7 @@ static DenseMap<const InputSectionBase *, int> buildSectionOrder() {
11251127

11261128
// Sorts the sections in ISD according to the provided section order.
11271129
static void
1128-
sortISDBySectionOrder(InputSectionDescription *isd,
1130+
sortISDBySectionOrder(Ctx &ctx, InputSectionDescription *isd,
11291131
const DenseMap<const InputSectionBase *, int> &order,
11301132
bool executableOutputSection) {
11311133
SmallVector<InputSection *, 0> unorderedSections;
@@ -1199,7 +1201,7 @@ sortISDBySectionOrder(InputSectionDescription *isd,
11991201
isd->sections.push_back(isec);
12001202
}
12011203

1202-
static void sortSection(OutputSection &osec,
1204+
static void sortSection(Ctx &ctx, OutputSection &osec,
12031205
const DenseMap<const InputSectionBase *, int> &order) {
12041206
StringRef name = osec.name;
12051207

@@ -1214,7 +1216,7 @@ static void sortSection(OutputSection &osec,
12141216
if (!order.empty())
12151217
for (SectionCommand *b : osec.commands)
12161218
if (auto *isd = dyn_cast<InputSectionDescription>(b))
1217-
sortISDBySectionOrder(isd, order, osec.flags & SHF_EXECINSTR);
1219+
sortISDBySectionOrder(ctx, isd, order, osec.flags & SHF_EXECINSTR);
12181220

12191221
if (ctx.script->hasSectionsCommand)
12201222
return;
@@ -1243,11 +1245,11 @@ static void sortSection(OutputSection &osec,
12431245
// sorting for special input sections. This also handles --symbol-ordering-file.
12441246
template <class ELFT> void Writer<ELFT>::sortInputSections() {
12451247
// Build the order once since it is expensive.
1246-
DenseMap<const InputSectionBase *, int> order = buildSectionOrder();
1247-
maybeShuffle(order);
1248+
DenseMap<const InputSectionBase *, int> order = buildSectionOrder(ctx);
1249+
maybeShuffle(ctx, order);
12481250
for (SectionCommand *cmd : ctx.script->sectionCommands)
12491251
if (auto *osd = dyn_cast<OutputDesc>(cmd))
1250-
sortSection(osd->osec, order);
1252+
sortSection(ctx, osd->osec, order);
12511253
}
12521254

12531255
template <class ELFT> void Writer<ELFT>::sortSections() {
@@ -1264,7 +1266,7 @@ template <class ELFT> void Writer<ELFT>::sortSections() {
12641266

12651267
for (SectionCommand *cmd : ctx.script->sectionCommands)
12661268
if (auto *osd = dyn_cast<OutputDesc>(cmd))
1267-
osd->osec.sortRank = getSectionRank(osd->osec);
1269+
osd->osec.sortRank = getSectionRank(ctx, osd->osec);
12681270
if (!ctx.script->hasSectionsCommand) {
12691271
// OutputDescs are mostly contiguous, but may be interleaved with
12701272
// SymbolAssignments in the presence of INSERT commands.
@@ -1348,7 +1350,7 @@ template <class ELFT> void Writer<ELFT>::sortOrphanSections() {
13481350
i = firstSectionOrDotAssignment;
13491351

13501352
while (nonScriptI != e) {
1351-
auto pos = findOrphanPos(i, nonScriptI);
1353+
auto pos = findOrphanPos(ctx, i, nonScriptI);
13521354
OutputSection *orphan = &cast<OutputDesc>(*nonScriptI)->osec;
13531355

13541356
// As an optimization, find all sections with the same sort rank
@@ -1570,7 +1572,7 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
15701572
// update symbol values and sizes associated with these sections. With basic
15711573
// block sections, input sections can shrink when the jump instructions at
15721574
// the end of the section are relaxed.
1573-
static void fixSymbolsAfterShrinking() {
1575+
static void fixSymbolsAfterShrinking(Ctx &ctx) {
15741576
for (InputFile *File : ctx.objectFiles) {
15751577
parallelForEach(File->getSymbols(), [&](Symbol *Sym) {
15761578
auto *def = dyn_cast<Defined>(Sym);
@@ -1644,7 +1646,7 @@ template <class ELFT> void Writer<ELFT>::optimizeBasicBlockJumps() {
16441646
}
16451647
}
16461648

1647-
fixSymbolsAfterShrinking();
1649+
fixSymbolsAfterShrinking(ctx);
16481650

16491651
for (OutputSection *osec : ctx.outputSections)
16501652
for (InputSection *is : getInputSections(*osec, storage))
@@ -1709,9 +1711,9 @@ static void removeUnusedSyntheticSections(Ctx &ctx) {
17091711
// Create output section objects and add them to OutputSections.
17101712
template <class ELFT> void Writer<ELFT>::finalizeSections() {
17111713
if (!ctx.arg.relocatable) {
1712-
ctx.out.preinitArray = findSection(".preinit_array");
1713-
ctx.out.initArray = findSection(".init_array");
1714-
ctx.out.finiArray = findSection(".fini_array");
1714+
ctx.out.preinitArray = findSection(ctx, ".preinit_array");
1715+
ctx.out.initArray = findSection(ctx, ".init_array");
1716+
ctx.out.finiArray = findSection(ctx, ".fini_array");
17151717

17161718
// The linker needs to define SECNAME_start, SECNAME_end and SECNAME_stop
17171719
// symbols for sections, so that the runtime can get the start and end
@@ -1741,7 +1743,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
17411743
// st_shndx arbitrarily to 1 (ctx.out.elfHeader).
17421744
if (ctx.arg.emachine == EM_RISCV) {
17431745
if (!ctx.arg.shared) {
1744-
OutputSection *sec = findSection(".sdata");
1746+
OutputSection *sec = findSection(ctx, ".sdata");
17451747
addOptionalRegular(ctx, "__global_pointer$",
17461748
sec ? sec : ctx.out.elfHeader, 0x800, STV_DEFAULT);
17471749
// Set riscvGlobalPointer to be used by the optional global pointer
@@ -2129,7 +2131,7 @@ template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
21292131

21302132
// As a special case, don't unnecessarily retain .ARM.exidx, which would
21312133
// create an empty PT_ARM_EXIDX.
2132-
if (OutputSection *sec = findSection(".ARM.exidx"))
2134+
if (OutputSection *sec = findSection(ctx, ".ARM.exidx"))
21332135
define("__exidx_start", "__exidx_end", sec);
21342136
}
21352137

@@ -2201,7 +2203,7 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
22012203
addHdr(PT_PHDR, PF_R)->add(part.programHeaders->getParent());
22022204

22032205
// PT_INTERP must be the second entry if exists.
2204-
if (OutputSection *cmd = findSection(".interp", partNo))
2206+
if (OutputSection *cmd = findSection(ctx, ".interp", partNo))
22052207
addHdr(PT_INTERP, cmd->getPhdrFlags())->add(cmd);
22062208

22072209
// Add the headers. We will remove them if they don't fit.
@@ -2224,7 +2226,7 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
22242226
for (OutputSection *sec : ctx.outputSections) {
22252227
if (sec->partition != partNo || !needsPtLoad(sec))
22262228
continue;
2227-
if (isRelroSection(sec)) {
2229+
if (isRelroSection(ctx, sec)) {
22282230
inRelroPhdr = true;
22292231
if (!relroEnd)
22302232
relRo->add(sec);
@@ -2318,17 +2320,17 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
23182320
if (ctx.arg.osabi == ELFOSABI_OPENBSD) {
23192321
// PT_OPENBSD_MUTABLE makes the dynamic linker fill the segment with
23202322
// zero data, like bss, but it can be treated differently.
2321-
if (OutputSection *cmd = findSection(".openbsd.mutable", partNo))
2323+
if (OutputSection *cmd = findSection(ctx, ".openbsd.mutable", partNo))
23222324
addHdr(PT_OPENBSD_MUTABLE, cmd->getPhdrFlags())->add(cmd);
23232325

23242326
// PT_OPENBSD_RANDOMIZE makes the dynamic linker fill the segment
23252327
// with random data.
2326-
if (OutputSection *cmd = findSection(".openbsd.randomdata", partNo))
2328+
if (OutputSection *cmd = findSection(ctx, ".openbsd.randomdata", partNo))
23272329
addHdr(PT_OPENBSD_RANDOMIZE, cmd->getPhdrFlags())->add(cmd);
23282330

23292331
// PT_OPENBSD_SYSCALLS makes the kernel and dynamic linker register
23302332
// system call sites.
2331-
if (OutputSection *cmd = findSection(".openbsd.syscalls", partNo))
2333+
if (OutputSection *cmd = findSection(ctx, ".openbsd.syscalls", partNo))
23322334
addHdr(PT_OPENBSD_SYSCALLS, cmd->getPhdrFlags())->add(cmd);
23332335
}
23342336

@@ -2350,7 +2352,7 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
23502352
if (ctx.arg.zWxneeded)
23512353
addHdr(PT_OPENBSD_WXNEEDED, PF_X);
23522354

2353-
if (OutputSection *cmd = findSection(".note.gnu.property", partNo))
2355+
if (OutputSection *cmd = findSection(ctx, ".note.gnu.property", partNo))
23542356
addHdr(PT_GNU_PROPERTY, PF_R)->add(cmd);
23552357

23562358
// Create one PT_NOTE per a group of contiguous SHT_NOTE sections with the
@@ -2456,7 +2458,7 @@ template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {
24562458
// Compute an in-file position for a given section. The file offset must be the
24572459
// same with its virtual address modulo the page size, so that the loader can
24582460
// load executables without any address adjustment.
2459-
static uint64_t computeFileOffset(OutputSection *os, uint64_t off) {
2461+
static uint64_t computeFileOffset(Ctx &ctx, OutputSection *os, uint64_t off) {
24602462
// The first section in a PT_LOAD has to have congruent offset and address
24612463
// modulo the maximum page size.
24622464
if (os->ptLoad && os->ptLoad->firstSec == os)
@@ -2519,7 +2521,7 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
25192521
for (OutputSection *sec : ctx.outputSections) {
25202522
if (!(sec->flags & SHF_ALLOC))
25212523
continue;
2522-
off = computeFileOffset(sec, off);
2524+
off = computeFileOffset(ctx, sec, off);
25232525
sec->offset = off;
25242526
if (sec->type != SHT_NOBITS)
25252527
off += sec->size;
@@ -2702,7 +2704,7 @@ template <class ELFT> void Writer<ELFT>::checkSections() {
27022704
// 3. the value of the symbol _start, if present;
27032705
// 4. the number represented by the entry symbol, if it is a number;
27042706
// 5. the address 0.
2705-
static uint64_t getEntryAddr() {
2707+
static uint64_t getEntryAddr(Ctx &ctx) {
27062708
// Case 1, 2 or 3
27072709
if (Symbol *b = ctx.symtab->find(ctx.arg.entry))
27082710
return b->getVA();
@@ -2719,7 +2721,7 @@ static uint64_t getEntryAddr() {
27192721
return 0;
27202722
}
27212723

2722-
static uint16_t getELFType() {
2724+
static uint16_t getELFType(Ctx &ctx) {
27232725
if (ctx.arg.isPic)
27242726
return ET_DYN;
27252727
if (ctx.arg.relocatable)
@@ -2732,8 +2734,8 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
27322734
writePhdrs<ELFT>(ctx.bufferStart + sizeof(Elf_Ehdr), *ctx.mainPart);
27332735

27342736
auto *eHdr = reinterpret_cast<Elf_Ehdr *>(ctx.bufferStart);
2735-
eHdr->e_type = getELFType();
2736-
eHdr->e_entry = getEntryAddr();
2737+
eHdr->e_type = getELFType(ctx);
2738+
eHdr->e_entry = getEntryAddr(ctx);
27372739

27382740
// If -z nosectionheader is specified, omit the section header table.
27392741
if (!ctx.in.shStrTab)
@@ -2807,9 +2809,10 @@ template <class ELFT> void Writer<ELFT>::writeSectionsBinary() {
28072809
sec->writeTo<ELFT>(ctx.bufferStart + sec->offset, tg);
28082810
}
28092811

2810-
static void fillTrap(uint8_t *i, uint8_t *end) {
2812+
static void fillTrap(std::array<uint8_t, 4> trapInstr, uint8_t *i,
2813+
uint8_t *end) {
28112814
for (; i + 4 <= end; i += 4)
2812-
memcpy(i, &ctx.target->trapInstr, 4);
2815+
memcpy(i, trapInstr.data(), 4);
28132816
}
28142817

28152818
// Fill the last page of executable segments with trap instructions
@@ -2824,6 +2827,7 @@ template <class ELFT> void Writer<ELFT>::writeTrapInstr() {
28242827
for (PhdrEntry *p : part.phdrs)
28252828
if (p->p_type == PT_LOAD && (p->p_flags & PF_X))
28262829
fillTrap(
2830+
ctx.target->trapInstr,
28272831
ctx.bufferStart + alignDown(p->firstSec->offset + p->p_filesz, 4),
28282832
ctx.bufferStart + alignToPowerOf2(p->firstSec->offset + p->p_filesz,
28292833
ctx.arg.maxPageSize));

lld/ELF/Writer.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ struct PhdrEntry {
4646

4747
void addReservedSymbols(Ctx &ctx);
4848
bool includeInSymtab(const Symbol &b);
49-
unsigned getSectionRank(OutputSection &osec);
49+
unsigned getSectionRank(Ctx &, OutputSection &osec);
5050

5151
template <class ELFT> uint32_t calcMipsEFlags();
5252

0 commit comments

Comments
 (0)