@@ -65,19 +65,20 @@ using namespace llvm::support::endian;
6565using namespace lld ;
6666using namespace lld ::elf;
6767
68- static std::optional<std::string> getLinkerScriptLocation (const Symbol &sym) {
68+ static std::optional<std::string> getLinkerScriptLocation (Ctx &ctx,
69+ const Symbol &sym) {
6970 for (SectionCommand *cmd : ctx.script ->sectionCommands )
7071 if (auto *assign = dyn_cast<SymbolAssignment>(cmd))
7172 if (assign->sym == &sym)
7273 return assign->location ;
7374 return std::nullopt ;
7475}
7576
76- static std::string getDefinedLocation (const Symbol &sym) {
77+ static std::string getDefinedLocation (Ctx &ctx, const Symbol &sym) {
7778 const char msg[] = " \n >>> defined in " ;
7879 if (sym.file )
7980 return msg + toString (sym.file );
80- if (std::optional<std::string> loc = getLinkerScriptLocation (sym))
81+ if (std::optional<std::string> loc = getLinkerScriptLocation (ctx, sym))
8182 return msg + *loc;
8283 return " " ;
8384}
@@ -87,9 +88,9 @@ static std::string getDefinedLocation(const Symbol &sym) {
8788// >>> defined in /home/alice/src/foo.o
8889// >>> referenced by bar.c:12 (/home/alice/src/bar.c:12)
8990// >>> /home/alice/src/bar.o:(.text+0x1)
90- static std::string getLocation (InputSectionBase &s, const Symbol &sym,
91+ static std::string getLocation (Ctx &ctx, InputSectionBase &s, const Symbol &sym,
9192 uint64_t off) {
92- std::string msg = getDefinedLocation (sym) + " \n >>> referenced by " ;
93+ std::string msg = getDefinedLocation (ctx, sym) + " \n >>> referenced by " ;
9394 std::string src = s.getSrcMsg (sym, off);
9495 if (!src.empty ())
9596 msg += src + " \n >>> " ;
@@ -116,7 +117,7 @@ void elf::reportRangeError(uint8_t *loc, const Relocation &rel, const Twine &v,
116117 if (!errPlace.srcLoc .empty ())
117118 hint += " \n >>> referenced by " + errPlace.srcLoc ;
118119 if (rel.sym && !rel.sym ->isSection ())
119- hint += getDefinedLocation (*rel.sym );
120+ hint += getDefinedLocation (ctx, *rel.sym );
120121
121122 if (errPlace.isec && errPlace.isec ->name .starts_with (" .debug" ))
122123 hint += " ; consider recompiling with -fdebug-types-section to reduce size "
@@ -127,13 +128,13 @@ void elf::reportRangeError(uint8_t *loc, const Relocation &rel, const Twine &v,
127128 " , " + Twine (max).str () + " ]" + hint);
128129}
129130
130- void elf::reportRangeError (uint8_t *loc, int64_t v, int n, const Symbol &sym ,
131- const Twine &msg) {
131+ void elf::reportRangeError (Ctx &ctx, uint8_t *loc, int64_t v, int n,
132+ const Symbol &sym, const Twine &msg) {
132133 ErrorPlace errPlace = getErrorPlace (loc);
133134 std::string hint;
134135 if (!sym.getName ().empty ())
135- hint =
136- " ; references ' " + lld::toString (sym) + ' \' ' + getDefinedLocation (sym);
136+ hint = " ; references ' " + lld::toString (sym) + ' \' ' +
137+ getDefinedLocation (ctx, sym);
137138 errorOrWarn (errPlace.loc + msg + " is out of range: " + Twine (v) +
138139 " is not in [" + Twine (llvm::minIntN (n)) + " , " +
139140 Twine (llvm::maxIntN (n)) + " ]" + hint);
@@ -926,7 +927,7 @@ static void addPltEntry(PltSection &plt, GotPltSection &gotPlt,
926927 sym, 0 , R_ABS});
927928}
928929
929- void elf::addGotEntry (Symbol &sym) {
930+ void elf::addGotEntry (Ctx &ctx, Symbol &sym) {
930931 ctx.in .got ->addEntry (sym);
931932 uint64_t off = sym.getGotOffset ();
932933
@@ -960,7 +961,7 @@ static void addTpOffsetGotEntry(Symbol &sym) {
960961// Return true if we can define a symbol in the executable that
961962// contains the value/function of a symbol defined in a shared
962963// library.
963- static bool canDefineSymbolInExecutable (Symbol &sym) {
964+ static bool canDefineSymbolInExecutable (Ctx &ctx, Symbol &sym) {
964965 // If the symbol has default visibility the symbol defined in the
965966 // executable will preempt it.
966967 // Note that we want the visibility of the shared symbol itself, not
@@ -1041,7 +1042,7 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,
10411042 return true ;
10421043
10431044 error (" relocation " + toString (type) + " cannot refer to absolute symbol: " +
1044- toString (sym) + getLocation (*sec, sym, relOff));
1045+ toString (sym) + getLocation (ctx, *sec, sym, relOff));
10451046 return true ;
10461047}
10471048
@@ -1206,9 +1207,9 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
12061207 // R_AARCH64_AUTH_ABS64.
12071208 if (!ctx.arg .shared && sym.isShared () &&
12081209 !(ctx.arg .emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64)) {
1209- if (!canDefineSymbolInExecutable (sym)) {
1210+ if (!canDefineSymbolInExecutable (ctx, sym)) {
12101211 errorOrWarn (" cannot preempt symbol: " + toString (sym) +
1211- getLocation (*sec, sym, offset));
1212+ getLocation (ctx, *sec, sym, offset));
12121213 return ;
12131214 }
12141215
@@ -1219,7 +1220,7 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
12191220 error (" unresolvable relocation " + toString (type) +
12201221 " against symbol '" + toString (*ss) +
12211222 " '; recompile with -fPIC or remove '-z nocopyreloc'" +
1222- getLocation (*sec, sym, offset));
1223+ getLocation (ctx, *sec, sym, offset));
12231224 sym.setFlags (NEEDS_COPY);
12241225 }
12251226 sec->addReloc ({expr, type, offset, addend, &sym});
@@ -1257,7 +1258,7 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
12571258 if (ctx.arg .pie && ctx.arg .emachine == EM_386)
12581259 errorOrWarn (" symbol '" + toString (sym) +
12591260 " ' cannot be preempted; recompile with -fPIE" +
1260- getLocation (*sec, sym, offset));
1261+ getLocation (ctx, *sec, sym, offset));
12611262 sym.setFlags (NEEDS_COPY | NEEDS_PLT);
12621263 sec->addReloc ({expr, type, offset, addend, &sym});
12631264 return ;
@@ -1267,7 +1268,7 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
12671268 errorOrWarn (" relocation " + toString (type) + " cannot be used against " +
12681269 (sym.getName ().empty () ? " local symbol"
12691270 : " symbol '" + toString (sym) + " '" ) +
1270- " ; recompile with -fPIC" + getLocation (*sec, sym, offset));
1271+ " ; recompile with -fPIC" + getLocation (ctx, *sec, sym, offset));
12711272}
12721273
12731274// This function is similar to the `handleTlsRelocation`. MIPS does not
@@ -1306,7 +1307,7 @@ unsigned RelocationScanner::handleTlsRelocation(RelExpr expr, RelType type,
13061307 if (ctx.arg .shared ) {
13071308 errorOrWarn (" relocation " + toString (type) + " against " + toString (sym) +
13081309 " cannot be used with -shared" +
1309- getLocation (*sec, sym, offset));
1310+ getLocation (ctx, *sec, sym, offset));
13101311 return 1 ;
13111312 }
13121313 return 0 ;
@@ -1515,7 +1516,7 @@ void RelocationScanner::scanOne(typename Relocs<RelTy>::const_iterator &i) {
15151516 if (i == end) {
15161517 errorOrWarn (" R_PPC64_TLSGD/R_PPC64_TLSLD may not be the last "
15171518 " relocation" +
1518- getLocation (*sec, sym, offset));
1519+ getLocation (ctx, *sec, sym, offset));
15191520 return ;
15201521 }
15211522 }
@@ -1694,7 +1695,7 @@ template <class ELFT> void elf::scanRelocations(Ctx &ctx) {
16941695 outerFn ();
16951696}
16961697
1697- static bool handleNonPreemptibleIfunc (Symbol &sym, uint16_t flags) {
1698+ static bool handleNonPreemptibleIfunc (Ctx &ctx, Symbol &sym, uint16_t flags) {
16981699 // Handle a reference to a non-preemptible ifunc. These are special in a
16991700 // few ways:
17001701 //
@@ -1770,7 +1771,7 @@ static bool handleNonPreemptibleIfunc(Symbol &sym, uint16_t flags) {
17701771 d.type = STT_FUNC;
17711772
17721773 if (flags & NEEDS_GOT)
1773- addGotEntry (sym);
1774+ addGotEntry (ctx, sym);
17741775 } else if (flags & NEEDS_GOT) {
17751776 // Redirect GOT accesses to point to the Igot.
17761777 sym.gotInIgot = true ;
@@ -1781,7 +1782,7 @@ static bool handleNonPreemptibleIfunc(Symbol &sym, uint16_t flags) {
17811782void elf::postScanRelocations (Ctx &ctx) {
17821783 auto fn = [&](Symbol &sym) {
17831784 auto flags = sym.flags .load (std::memory_order_relaxed);
1784- if (handleNonPreemptibleIfunc (sym, flags))
1785+ if (handleNonPreemptibleIfunc (ctx, sym, flags))
17851786 return ;
17861787
17871788 if (sym.isTagged () && sym.isDefined ())
@@ -1792,7 +1793,7 @@ void elf::postScanRelocations(Ctx &ctx) {
17921793 sym.allocateAux ();
17931794
17941795 if (flags & NEEDS_GOT)
1795- addGotEntry (sym);
1796+ addGotEntry (ctx, sym);
17961797 if (flags & NEEDS_PLT)
17971798 addPltEntry (*ctx.in .plt , *ctx.in .gotPlt , *ctx.in .relaPlt ,
17981799 ctx.target ->pltRel , sym);
@@ -2052,7 +2053,7 @@ void ThunkCreator::mergeThunks(ArrayRef<OutputSection *> outputSections) {
20522053 });
20532054}
20542055
2055- static int64_t getPCBias (RelType type) {
2056+ static int64_t getPCBias (Ctx &ctx, RelType type) {
20562057 if (ctx.arg .emachine != EM_ARM)
20572058 return 0 ;
20582059 switch (type) {
@@ -2074,7 +2075,7 @@ ThunkSection *ThunkCreator::getISDThunkSec(OutputSection *os,
20742075 const Relocation &rel,
20752076 uint64_t src) {
20762077 // See the comment in getThunk for -pcBias below.
2077- const int64_t pcBias = getPCBias (rel.type );
2078+ const int64_t pcBias = getPCBias (ctx, rel.type );
20782079 for (std::pair<ThunkSection *, uint32_t > tp : isd->thunkSections ) {
20792080 ThunkSection *ts = tp.first ;
20802081 uint64_t tsBase = os->addr + ts->outSecOff - pcBias;
@@ -2235,7 +2236,7 @@ std::pair<Thunk *, bool> ThunkCreator::getThunk(InputSection *isec,
22352236 // out in the relocation addend. We compensate for the PC bias so that
22362237 // an Arm and Thumb relocation to the same destination get the same keyAddend,
22372238 // which is usually 0.
2238- const int64_t pcBias = getPCBias (rel.type );
2239+ const int64_t pcBias = getPCBias (ctx, rel.type );
22392240 const int64_t keyAddend = rel.addend + pcBias;
22402241
22412242 // We use a ((section, offset), addend) pair to find the thunk position if
@@ -2357,7 +2358,7 @@ bool ThunkCreator::createThunks(uint32_t pass,
23572358 // STT_SECTION + non-zero addend, clear the addend after
23582359 // redirection.
23592360 if (ctx.arg .emachine != EM_MIPS)
2360- rel.addend = -getPCBias (rel.type );
2361+ rel.addend = -getPCBias (ctx, rel.type );
23612362 }
23622363
23632364 for (auto &p : isd->thunkSections )
@@ -2390,13 +2391,13 @@ bool elf::hexagonNeedsTLSSymbol(ArrayRef<OutputSection *> outputSections) {
23902391 return needTlsSymbol;
23912392}
23922393
2393- void elf::hexagonTLSSymbolUpdate (ArrayRef<OutputSection *> outputSections ) {
2394+ void elf::hexagonTLSSymbolUpdate (Ctx &ctx ) {
23942395 Symbol *sym = ctx.symtab ->find (" __tls_get_addr" );
23952396 if (!sym)
23962397 return ;
23972398 bool needEntry = true ;
23982399 forEachInputSectionDescription (
2399- outputSections, [&](OutputSection *os, InputSectionDescription *isd) {
2400+ ctx. outputSections , [&](OutputSection *os, InputSectionDescription *isd) {
24002401 for (InputSection *isec : isd->sections )
24012402 for (Relocation &rel : isec->relocs ())
24022403 if (rel.sym ->type == llvm::ELF::STT_TLS && rel.expr == R_PLT_PC) {
@@ -2418,8 +2419,8 @@ static bool matchesRefTo(const NoCrossRefCommand &cmd, StringRef osec) {
24182419}
24192420
24202421template <class ELFT , class Rels >
2421- static void scanCrossRefs (const NoCrossRefCommand &cmd, OutputSection *osec ,
2422- InputSection *sec, Rels rels) {
2422+ static void scanCrossRefs (Ctx &ctx, const NoCrossRefCommand &cmd,
2423+ OutputSection *osec, InputSection *sec, Rels rels) {
24232424 for (const auto &r : rels) {
24242425 Symbol &sym = sec->file ->getSymbol (r.getSymbol (ctx.arg .isMips64EL ));
24252426 // A legal cross-reference is when the destination output section is
@@ -2442,7 +2443,7 @@ static void scanCrossRefs(const NoCrossRefCommand &cmd, OutputSection *osec,
24422443
24432444// For each output section described by at least one NOCROSSREFS(_TO) command,
24442445// scan relocations from its input sections for prohibited cross references.
2445- template <class ELFT > void elf::checkNoCrossRefs () {
2446+ template <class ELFT > void elf::checkNoCrossRefs (Ctx &ctx ) {
24462447 for (OutputSection *osec : ctx.outputSections ) {
24472448 for (const NoCrossRefCommand &noxref : ctx.script ->noCrossRefs ) {
24482449 if (!llvm::is_contained (noxref.outputSections , osec->name ) ||
@@ -2453,7 +2454,7 @@ template <class ELFT> void elf::checkNoCrossRefs() {
24532454 if (!isd)
24542455 continue ;
24552456 parallelForEach (isd->sections , [&](InputSection *sec) {
2456- invokeOnRelocs (*sec, scanCrossRefs<ELFT>, noxref, osec, sec);
2457+ invokeOnRelocs (*sec, scanCrossRefs<ELFT>, ctx, noxref, osec, sec);
24572458 });
24582459 }
24592460 }
@@ -2465,7 +2466,7 @@ template void elf::scanRelocations<ELF32BE>(Ctx &);
24652466template void elf::scanRelocations<ELF64LE>(Ctx &);
24662467template void elf::scanRelocations<ELF64BE>(Ctx &);
24672468
2468- template void elf::checkNoCrossRefs<ELF32LE>();
2469- template void elf::checkNoCrossRefs<ELF32BE>();
2470- template void elf::checkNoCrossRefs<ELF64LE>();
2471- template void elf::checkNoCrossRefs<ELF64BE>();
2469+ template void elf::checkNoCrossRefs<ELF32LE>(Ctx & );
2470+ template void elf::checkNoCrossRefs<ELF32BE>(Ctx & );
2471+ template void elf::checkNoCrossRefs<ELF64LE>(Ctx & );
2472+ template void elf::checkNoCrossRefs<ELF64BE>(Ctx & );
0 commit comments