@@ -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.
948949static 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.
11271129static 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.
12441246template <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
12531255template <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.
17101712template <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 ));
0 commit comments