@@ -294,7 +294,8 @@ static void demoteSymbolsAndComputeIsPreemptible(Ctx &ctx) {
294
294
}
295
295
}
296
296
297
- static OutputSection *findSection (StringRef name, unsigned partition = 1 ) {
297
+ static OutputSection *findSection (Ctx &ctx, StringRef name,
298
+ unsigned partition = 1 ) {
298
299
for (SectionCommand *cmd : ctx.script ->sectionCommands )
299
300
if (auto *osd = dyn_cast<OutputDesc>(cmd))
300
301
if (osd->osec .name == name && osd->osec .partition == partition)
@@ -544,7 +545,7 @@ template <class ELFT> void Writer<ELFT>::addSectionSymbols() {
544
545
//
545
546
// This function returns true if a section needs to be put into a
546
547
// PT_GNU_RELRO segment.
547
- static bool isRelroSection (const OutputSection *sec) {
548
+ static bool isRelroSection (Ctx &ctx, const OutputSection *sec) {
548
549
if (!ctx.arg .zRelro )
549
550
return false ;
550
551
if (sec->relro )
@@ -648,7 +649,7 @@ enum RankFlags {
648
649
RF_BSS = 1 << 7 ,
649
650
};
650
651
651
- unsigned elf::getSectionRank (OutputSection &osec) {
652
+ unsigned elf::getSectionRank (Ctx &ctx, OutputSection &osec) {
652
653
unsigned rank = osec.partition * RF_PARTITION;
653
654
654
655
// We want to put section specified by -T option first, so we
@@ -713,7 +714,7 @@ unsigned elf::getSectionRank(OutputSection &osec) {
713
714
// TLS sections directly before the other RELRO sections.
714
715
if (!(osec.flags & SHF_TLS))
715
716
rank |= RF_NOT_TLS;
716
- if (isRelroSection (&osec))
717
+ if (isRelroSection (ctx, &osec))
717
718
osec.relro = true ;
718
719
else
719
720
rank |= RF_NOT_RELRO;
@@ -892,8 +893,8 @@ template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {
892
893
if (ctx.sym .bss ) {
893
894
// On RISC-V, set __bss_start to the start of .sbss if present.
894
895
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" );
897
898
}
898
899
899
900
// Setup MIPS _gp_disp/__gnu_local_gp symbols which should
@@ -946,7 +947,7 @@ static bool shouldSkip(SectionCommand *cmd) {
946
947
// characteristics with their neighbors as possible. For example, if
947
948
// both are rw, or both are tls.
948
949
static SmallVectorImpl<SectionCommand *>::iterator
949
- findOrphanPos (SmallVectorImpl<SectionCommand *>::iterator b,
950
+ findOrphanPos (Ctx &ctx, SmallVectorImpl<SectionCommand *>::iterator b,
950
951
SmallVectorImpl<SectionCommand *>::iterator e) {
951
952
// Place non-alloc orphan sections at the end. This matches how we assign file
952
953
// offsets to non-alloc sections.
@@ -1028,7 +1029,8 @@ findOrphanPos(SmallVectorImpl<SectionCommand *>::iterator b,
1028
1029
}
1029
1030
1030
1031
// 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) {
1032
1034
if (ctx.arg .shuffleSections .empty ())
1033
1035
return ;
1034
1036
@@ -1066,7 +1068,7 @@ static void maybeShuffle(DenseMap<const InputSectionBase *, int> &order) {
1066
1068
}
1067
1069
1068
1070
// Builds section order for handling --symbol-ordering-file.
1069
- static DenseMap<const InputSectionBase *, int > buildSectionOrder () {
1071
+ static DenseMap<const InputSectionBase *, int > buildSectionOrder (Ctx &ctx ) {
1070
1072
DenseMap<const InputSectionBase *, int > sectionOrder;
1071
1073
// Use the rarely used option --call-graph-ordering-file to sort sections.
1072
1074
if (!ctx.arg .callGraphProfile .empty ())
@@ -1125,7 +1127,7 @@ static DenseMap<const InputSectionBase *, int> buildSectionOrder() {
1125
1127
1126
1128
// Sorts the sections in ISD according to the provided section order.
1127
1129
static void
1128
- sortISDBySectionOrder (InputSectionDescription *isd,
1130
+ sortISDBySectionOrder (Ctx &ctx, InputSectionDescription *isd,
1129
1131
const DenseMap<const InputSectionBase *, int > &order,
1130
1132
bool executableOutputSection) {
1131
1133
SmallVector<InputSection *, 0 > unorderedSections;
@@ -1199,7 +1201,7 @@ sortISDBySectionOrder(InputSectionDescription *isd,
1199
1201
isd->sections .push_back (isec);
1200
1202
}
1201
1203
1202
- static void sortSection (OutputSection &osec,
1204
+ static void sortSection (Ctx &ctx, OutputSection &osec,
1203
1205
const DenseMap<const InputSectionBase *, int > &order) {
1204
1206
StringRef name = osec.name ;
1205
1207
@@ -1214,7 +1216,7 @@ static void sortSection(OutputSection &osec,
1214
1216
if (!order.empty ())
1215
1217
for (SectionCommand *b : osec.commands )
1216
1218
if (auto *isd = dyn_cast<InputSectionDescription>(b))
1217
- sortISDBySectionOrder (isd, order, osec.flags & SHF_EXECINSTR);
1219
+ sortISDBySectionOrder (ctx, isd, order, osec.flags & SHF_EXECINSTR);
1218
1220
1219
1221
if (ctx.script ->hasSectionsCommand )
1220
1222
return ;
@@ -1243,11 +1245,11 @@ static void sortSection(OutputSection &osec,
1243
1245
// sorting for special input sections. This also handles --symbol-ordering-file.
1244
1246
template <class ELFT > void Writer<ELFT>::sortInputSections() {
1245
1247
// 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);
1248
1250
for (SectionCommand *cmd : ctx.script ->sectionCommands )
1249
1251
if (auto *osd = dyn_cast<OutputDesc>(cmd))
1250
- sortSection (osd->osec , order);
1252
+ sortSection (ctx, osd->osec , order);
1251
1253
}
1252
1254
1253
1255
template <class ELFT > void Writer<ELFT>::sortSections() {
@@ -1264,7 +1266,7 @@ template <class ELFT> void Writer<ELFT>::sortSections() {
1264
1266
1265
1267
for (SectionCommand *cmd : ctx.script ->sectionCommands )
1266
1268
if (auto *osd = dyn_cast<OutputDesc>(cmd))
1267
- osd->osec .sortRank = getSectionRank (osd->osec );
1269
+ osd->osec .sortRank = getSectionRank (ctx, osd->osec );
1268
1270
if (!ctx.script ->hasSectionsCommand ) {
1269
1271
// OutputDescs are mostly contiguous, but may be interleaved with
1270
1272
// SymbolAssignments in the presence of INSERT commands.
@@ -1348,7 +1350,7 @@ template <class ELFT> void Writer<ELFT>::sortOrphanSections() {
1348
1350
i = firstSectionOrDotAssignment;
1349
1351
1350
1352
while (nonScriptI != e) {
1351
- auto pos = findOrphanPos (i, nonScriptI);
1353
+ auto pos = findOrphanPos (ctx, i, nonScriptI);
1352
1354
OutputSection *orphan = &cast<OutputDesc>(*nonScriptI)->osec ;
1353
1355
1354
1356
// As an optimization, find all sections with the same sort rank
@@ -1570,7 +1572,7 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
1570
1572
// update symbol values and sizes associated with these sections. With basic
1571
1573
// block sections, input sections can shrink when the jump instructions at
1572
1574
// the end of the section are relaxed.
1573
- static void fixSymbolsAfterShrinking () {
1575
+ static void fixSymbolsAfterShrinking (Ctx &ctx ) {
1574
1576
for (InputFile *File : ctx.objectFiles ) {
1575
1577
parallelForEach (File->getSymbols (), [&](Symbol *Sym) {
1576
1578
auto *def = dyn_cast<Defined>(Sym);
@@ -1644,7 +1646,7 @@ template <class ELFT> void Writer<ELFT>::optimizeBasicBlockJumps() {
1644
1646
}
1645
1647
}
1646
1648
1647
- fixSymbolsAfterShrinking ();
1649
+ fixSymbolsAfterShrinking (ctx );
1648
1650
1649
1651
for (OutputSection *osec : ctx.outputSections )
1650
1652
for (InputSection *is : getInputSections (*osec, storage))
@@ -1709,9 +1711,9 @@ static void removeUnusedSyntheticSections(Ctx &ctx) {
1709
1711
// Create output section objects and add them to OutputSections.
1710
1712
template <class ELFT > void Writer<ELFT>::finalizeSections() {
1711
1713
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" );
1715
1717
1716
1718
// The linker needs to define SECNAME_start, SECNAME_end and SECNAME_stop
1717
1719
// symbols for sections, so that the runtime can get the start and end
@@ -1741,7 +1743,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
1741
1743
// st_shndx arbitrarily to 1 (ctx.out.elfHeader).
1742
1744
if (ctx.arg .emachine == EM_RISCV) {
1743
1745
if (!ctx.arg .shared ) {
1744
- OutputSection *sec = findSection (" .sdata" );
1746
+ OutputSection *sec = findSection (ctx, " .sdata" );
1745
1747
addOptionalRegular (ctx, " __global_pointer$" ,
1746
1748
sec ? sec : ctx.out .elfHeader , 0x800 , STV_DEFAULT);
1747
1749
// Set riscvGlobalPointer to be used by the optional global pointer
@@ -2129,7 +2131,7 @@ template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
2129
2131
2130
2132
// As a special case, don't unnecessarily retain .ARM.exidx, which would
2131
2133
// create an empty PT_ARM_EXIDX.
2132
- if (OutputSection *sec = findSection (" .ARM.exidx" ))
2134
+ if (OutputSection *sec = findSection (ctx, " .ARM.exidx" ))
2133
2135
define (" __exidx_start" , " __exidx_end" , sec);
2134
2136
}
2135
2137
@@ -2201,7 +2203,7 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
2201
2203
addHdr (PT_PHDR, PF_R)->add (part.programHeaders ->getParent ());
2202
2204
2203
2205
// PT_INTERP must be the second entry if exists.
2204
- if (OutputSection *cmd = findSection (" .interp" , partNo))
2206
+ if (OutputSection *cmd = findSection (ctx, " .interp" , partNo))
2205
2207
addHdr (PT_INTERP, cmd->getPhdrFlags ())->add (cmd);
2206
2208
2207
2209
// Add the headers. We will remove them if they don't fit.
@@ -2224,7 +2226,7 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
2224
2226
for (OutputSection *sec : ctx.outputSections ) {
2225
2227
if (sec->partition != partNo || !needsPtLoad (sec))
2226
2228
continue ;
2227
- if (isRelroSection (sec)) {
2229
+ if (isRelroSection (ctx, sec)) {
2228
2230
inRelroPhdr = true ;
2229
2231
if (!relroEnd)
2230
2232
relRo->add (sec);
@@ -2318,17 +2320,17 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
2318
2320
if (ctx.arg .osabi == ELFOSABI_OPENBSD) {
2319
2321
// PT_OPENBSD_MUTABLE makes the dynamic linker fill the segment with
2320
2322
// 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))
2322
2324
addHdr (PT_OPENBSD_MUTABLE, cmd->getPhdrFlags ())->add (cmd);
2323
2325
2324
2326
// PT_OPENBSD_RANDOMIZE makes the dynamic linker fill the segment
2325
2327
// with random data.
2326
- if (OutputSection *cmd = findSection (" .openbsd.randomdata" , partNo))
2328
+ if (OutputSection *cmd = findSection (ctx, " .openbsd.randomdata" , partNo))
2327
2329
addHdr (PT_OPENBSD_RANDOMIZE, cmd->getPhdrFlags ())->add (cmd);
2328
2330
2329
2331
// PT_OPENBSD_SYSCALLS makes the kernel and dynamic linker register
2330
2332
// system call sites.
2331
- if (OutputSection *cmd = findSection (" .openbsd.syscalls" , partNo))
2333
+ if (OutputSection *cmd = findSection (ctx, " .openbsd.syscalls" , partNo))
2332
2334
addHdr (PT_OPENBSD_SYSCALLS, cmd->getPhdrFlags ())->add (cmd);
2333
2335
}
2334
2336
@@ -2350,7 +2352,7 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
2350
2352
if (ctx.arg .zWxneeded )
2351
2353
addHdr (PT_OPENBSD_WXNEEDED, PF_X);
2352
2354
2353
- if (OutputSection *cmd = findSection (" .note.gnu.property" , partNo))
2355
+ if (OutputSection *cmd = findSection (ctx, " .note.gnu.property" , partNo))
2354
2356
addHdr (PT_GNU_PROPERTY, PF_R)->add (cmd);
2355
2357
2356
2358
// 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() {
2456
2458
// Compute an in-file position for a given section. The file offset must be the
2457
2459
// same with its virtual address modulo the page size, so that the loader can
2458
2460
// 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) {
2460
2462
// The first section in a PT_LOAD has to have congruent offset and address
2461
2463
// modulo the maximum page size.
2462
2464
if (os->ptLoad && os->ptLoad ->firstSec == os)
@@ -2519,7 +2521,7 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
2519
2521
for (OutputSection *sec : ctx.outputSections ) {
2520
2522
if (!(sec->flags & SHF_ALLOC))
2521
2523
continue ;
2522
- off = computeFileOffset (sec, off);
2524
+ off = computeFileOffset (ctx, sec, off);
2523
2525
sec->offset = off;
2524
2526
if (sec->type != SHT_NOBITS)
2525
2527
off += sec->size ;
@@ -2702,7 +2704,7 @@ template <class ELFT> void Writer<ELFT>::checkSections() {
2702
2704
// 3. the value of the symbol _start, if present;
2703
2705
// 4. the number represented by the entry symbol, if it is a number;
2704
2706
// 5. the address 0.
2705
- static uint64_t getEntryAddr () {
2707
+ static uint64_t getEntryAddr (Ctx &ctx ) {
2706
2708
// Case 1, 2 or 3
2707
2709
if (Symbol *b = ctx.symtab ->find (ctx.arg .entry ))
2708
2710
return b->getVA ();
@@ -2719,7 +2721,7 @@ static uint64_t getEntryAddr() {
2719
2721
return 0 ;
2720
2722
}
2721
2723
2722
- static uint16_t getELFType () {
2724
+ static uint16_t getELFType (Ctx &ctx ) {
2723
2725
if (ctx.arg .isPic )
2724
2726
return ET_DYN;
2725
2727
if (ctx.arg .relocatable )
@@ -2732,8 +2734,8 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
2732
2734
writePhdrs<ELFT>(ctx.bufferStart + sizeof (Elf_Ehdr), *ctx.mainPart );
2733
2735
2734
2736
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 );
2737
2739
2738
2740
// If -z nosectionheader is specified, omit the section header table.
2739
2741
if (!ctx.in .shStrTab )
@@ -2807,9 +2809,10 @@ template <class ELFT> void Writer<ELFT>::writeSectionsBinary() {
2807
2809
sec->writeTo <ELFT>(ctx.bufferStart + sec->offset , tg);
2808
2810
}
2809
2811
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) {
2811
2814
for (; i + 4 <= end; i += 4 )
2812
- memcpy (i, &ctx. target -> trapInstr , 4 );
2815
+ memcpy (i, trapInstr. data () , 4 );
2813
2816
}
2814
2817
2815
2818
// Fill the last page of executable segments with trap instructions
@@ -2824,6 +2827,7 @@ template <class ELFT> void Writer<ELFT>::writeTrapInstr() {
2824
2827
for (PhdrEntry *p : part.phdrs )
2825
2828
if (p->p_type == PT_LOAD && (p->p_flags & PF_X))
2826
2829
fillTrap (
2830
+ ctx.target ->trapInstr ,
2827
2831
ctx.bufferStart + alignDown (p->firstSec ->offset + p->p_filesz , 4 ),
2828
2832
ctx.bufferStart + alignToPowerOf2 (p->firstSec ->offset + p->p_filesz ,
2829
2833
ctx.arg .maxPageSize ));
0 commit comments