1 //===- Relocations.cpp ----------------------------------------------------===//
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains platform-independent functions to process relocations.
11 // I'll describe the overview of this file here.
13 // Simple relocations are easy to handle for the linker. For example,
14 // for R_X86_64_PC64 relocs, the linker just has to fix up locations
15 // with the relative offsets to the target symbols. It would just be
16 // reading records from relocation sections and applying them to output.
18 // But not all relocations are that easy to handle. For example, for
19 // R_386_GOTOFF relocs, the linker has to create new GOT entries for
20 // symbols if they don't exist, and fix up locations with GOT entry
21 // offsets from the beginning of GOT section. So there is more than
22 // fixing addresses in relocation processing.
24 // ELF defines a large number of complex relocations.
26 // The functions in this file analyze relocations and do whatever needs
27 // to be done. It includes, but not limited to, the following.
29 // - create GOT/PLT entries
30 // - create new relocations in .dynsym to let the dynamic linker resolve
31 // them at runtime (since ELF supports dynamic linking, not all
32 // relocations can be resolved at link-time)
33 // - create COPY relocs and reserve space in .bss
34 // - replace expensive relocs (in terms of runtime cost) with cheap ones
35 // - error out infeasible combinations such as PIC and non-relative relocs
37 // Note that the functions in this file don't actually apply relocations
38 // because it doesn't know about the output file nor the output file buffer.
39 // It instead stores Relocation objects to InputSection's Relocations
40 // vector to let it apply later in InputSection::writeTo.
42 //===----------------------------------------------------------------------===//
44 #include "Relocations.h"
46 #include "LinkerScript.h"
48 #include "OutputSections.h"
50 #include "SymbolTable.h"
51 #include "SyntheticSections.h"
55 #include "llvm/Support/Endian.h"
56 #include "llvm/Support/raw_ostream.h"
60 using namespace llvm::ELF
;
61 using namespace llvm::object
;
62 using namespace llvm::support::endian
;
65 using namespace lld::elf
;
67 // Construct a message in the following format.
69 // >>> defined in /home/alice/src/foo.o
70 // >>> referenced by bar.c:12 (/home/alice/src/bar.c:12)
71 // >>> /home/alice/src/bar.o:(.text+0x1)
73 static std::string
getLocation(InputSectionBase
&S
, const SymbolBody
&Sym
,
76 "\n>>> defined in " + toString(Sym
.getFile()) + "\n>>> referenced by ";
77 std::string Src
= S
.getSrcMsg
<ELFT
>(Off
);
79 Msg
+= Src
+ "\n>>> ";
80 return Msg
+ S
.getObjMsg
<ELFT
>(Off
);
83 static bool isPreemptible(const SymbolBody
&Body
, uint32_t Type
) {
84 // In case of MIPS GP-relative relocations always resolve to a definition
85 // in a regular input file, ignoring the one-definition rule. So we,
86 // for example, should not attempt to create a dynamic relocation even
87 // if the target symbol is preemptible. There are two two MIPS GP-relative
88 // relocations R_MIPS_GPREL16 and R_MIPS_GPREL32. But only R_MIPS_GPREL16
89 // can be against a preemptible symbol.
90 // To get MIPS relocation type we apply 0xff mask. In case of O32 ABI all
91 // relocation types occupy eight bit. In case of N64 ABI we extract first
92 // relocation from 3-in-1 packet because only the first relocation can
93 // be against a real symbol.
94 if (Config
->EMachine
== EM_MIPS
&& (Type
& 0xff) == R_MIPS_GPREL16
)
96 return Body
.isPreemptible();
99 // This function is similar to the `handleTlsRelocation`. MIPS does not
100 // support any relaxations for TLS relocations so by factoring out MIPS
101 // handling in to the separate function we can simplify the code and do not
102 // pollute other `handleTlsRelocation` by MIPS `ifs` statements.
103 // Mips has a custom MipsGotSection that handles the writing of GOT entries
104 // without dynamic relocations.
105 template <class ELFT
>
106 static unsigned handleMipsTlsRelocation(uint32_t Type
, SymbolBody
&Body
,
107 InputSectionBase
&C
, uint64_t Offset
,
108 int64_t Addend
, RelExpr Expr
) {
109 if (Expr
== R_MIPS_TLSLD
) {
110 if (InX::MipsGot
->addTlsIndex() && Config
->Pic
)
111 In
<ELFT
>::RelaDyn
->addReloc({Target
->TlsModuleIndexRel
, InX::MipsGot
,
112 InX::MipsGot
->getTlsIndexOff(), false,
114 C
.Relocations
.push_back({Expr
, Type
, Offset
, Addend
, &Body
});
118 if (Expr
== R_MIPS_TLSGD
) {
119 if (InX::MipsGot
->addDynTlsEntry(Body
) && Body
.isPreemptible()) {
120 uint64_t Off
= InX::MipsGot
->getGlobalDynOffset(Body
);
121 In
<ELFT
>::RelaDyn
->addReloc(
122 {Target
->TlsModuleIndexRel
, InX::MipsGot
, Off
, false, &Body
, 0});
123 if (Body
.isPreemptible())
124 In
<ELFT
>::RelaDyn
->addReloc({Target
->TlsOffsetRel
, InX::MipsGot
,
125 Off
+ Config
->Wordsize
, false, &Body
, 0});
127 C
.Relocations
.push_back({Expr
, Type
, Offset
, Addend
, &Body
});
133 // This function is similar to the `handleMipsTlsRelocation`. ARM also does not
134 // support any relaxations for TLS relocations. ARM is logically similar to Mips
135 // in how it handles TLS, but Mips uses its own custom GOT which handles some
136 // of the cases that ARM uses GOT relocations for.
138 // We look for TLS global dynamic and local dynamic relocations, these may
139 // require the generation of a pair of GOT entries that have associated
140 // dynamic relocations. When the results of the dynamic relocations can be
141 // resolved at static link time we do so. This is necessary for static linking
142 // as there will be no dynamic loader to resolve them at load-time.
144 // The pair of GOT entries created are of the form
145 // GOT[e0] Module Index (Used to find pointer to TLS block at run-time)
146 // GOT[e1] Offset of symbol in TLS block
147 template <class ELFT
>
148 static unsigned handleARMTlsRelocation(uint32_t Type
, SymbolBody
&Body
,
149 InputSectionBase
&C
, uint64_t Offset
,
150 int64_t Addend
, RelExpr Expr
) {
151 // The Dynamic TLS Module Index Relocation for a symbol defined in an
152 // executable is always 1. If the target Symbol is not preemtible then
153 // we know the offset into the TLS block at static link time.
154 bool NeedDynId
= Body
.isPreemptible() || Config
->Shared
;
155 bool NeedDynOff
= Body
.isPreemptible();
157 auto AddTlsReloc
= [&](uint64_t Off
, uint32_t Type
, SymbolBody
*Dest
,
160 In
<ELFT
>::RelaDyn
->addReloc({Type
, InX::Got
, Off
, false, Dest
, 0});
162 InX::Got
->Relocations
.push_back({R_ABS
, Type
, Off
, 0, Dest
});
165 // Local Dynamic is for access to module local TLS variables, while still
166 // being suitable for being dynamically loaded via dlopen.
167 // GOT[e0] is the module index, with a special value of 0 for the current
168 // module. GOT[e1] is unused. There only needs to be one module index entry.
169 if (Expr
== R_TLSLD_PC
&& InX::Got
->addTlsIndex()) {
170 AddTlsReloc(InX::Got
->getTlsIndexOff(), Target
->TlsModuleIndexRel
,
171 NeedDynId
? nullptr : &Body
, NeedDynId
);
172 C
.Relocations
.push_back({Expr
, Type
, Offset
, Addend
, &Body
});
176 // Global Dynamic is the most general purpose access model. When we know
177 // the module index and offset of symbol in TLS block we can fill these in
178 // using static GOT relocations.
179 if (Expr
== R_TLSGD_PC
) {
180 if (InX::Got
->addDynTlsEntry(Body
)) {
181 uint64_t Off
= InX::Got
->getGlobalDynOffset(Body
);
182 AddTlsReloc(Off
, Target
->TlsModuleIndexRel
, &Body
, NeedDynId
);
183 AddTlsReloc(Off
+ Config
->Wordsize
, Target
->TlsOffsetRel
, &Body
,
186 C
.Relocations
.push_back({Expr
, Type
, Offset
, Addend
, &Body
});
192 // Returns the number of relocations processed.
193 template <class ELFT
>
195 handleTlsRelocation(uint32_t Type
, SymbolBody
&Body
, InputSectionBase
&C
,
196 typename
ELFT::uint Offset
, int64_t Addend
, RelExpr Expr
) {
197 if (!(C
.Flags
& SHF_ALLOC
))
203 if (Config
->EMachine
== EM_ARM
)
204 return handleARMTlsRelocation
<ELFT
>(Type
, Body
, C
, Offset
, Addend
, Expr
);
205 if (Config
->EMachine
== EM_MIPS
)
206 return handleMipsTlsRelocation
<ELFT
>(Type
, Body
, C
, Offset
, Addend
, Expr
);
208 bool IsPreemptible
= isPreemptible(Body
, Type
);
209 if (isRelExprOneOf
<R_TLSDESC
, R_TLSDESC_PAGE
, R_TLSDESC_CALL
>(Expr
) &&
211 if (InX::Got
->addDynTlsEntry(Body
)) {
212 uint64_t Off
= InX::Got
->getGlobalDynOffset(Body
);
213 In
<ELFT
>::RelaDyn
->addReloc(
214 {Target
->TlsDescRel
, InX::Got
, Off
, !IsPreemptible
, &Body
, 0});
216 if (Expr
!= R_TLSDESC_CALL
)
217 C
.Relocations
.push_back({Expr
, Type
, Offset
, Addend
, &Body
});
221 if (isRelExprOneOf
<R_TLSLD_PC
, R_TLSLD
>(Expr
)) {
222 // Local-Dynamic relocs can be relaxed to Local-Exec.
223 if (!Config
->Shared
) {
224 C
.Relocations
.push_back(
225 {R_RELAX_TLS_LD_TO_LE
, Type
, Offset
, Addend
, &Body
});
228 if (InX::Got
->addTlsIndex())
229 In
<ELFT
>::RelaDyn
->addReloc({Target
->TlsModuleIndexRel
, InX::Got
,
230 InX::Got
->getTlsIndexOff(), false, nullptr,
232 C
.Relocations
.push_back({Expr
, Type
, Offset
, Addend
, &Body
});
236 // Local-Dynamic relocs can be relaxed to Local-Exec.
237 if (isRelExprOneOf
<R_ABS
, R_TLSLD
, R_TLSLD_PC
>(Expr
) && !Config
->Shared
) {
238 C
.Relocations
.push_back(
239 {R_RELAX_TLS_LD_TO_LE
, Type
, Offset
, Addend
, &Body
});
243 if (isRelExprOneOf
<R_TLSDESC
, R_TLSDESC_PAGE
, R_TLSDESC_CALL
, R_TLSGD
,
245 if (Config
->Shared
) {
246 if (InX::Got
->addDynTlsEntry(Body
)) {
247 uint64_t Off
= InX::Got
->getGlobalDynOffset(Body
);
248 In
<ELFT
>::RelaDyn
->addReloc(
249 {Target
->TlsModuleIndexRel
, InX::Got
, Off
, false, &Body
, 0});
251 // If the symbol is preemptible we need the dynamic linker to write
253 uint64_t OffsetOff
= Off
+ Config
->Wordsize
;
255 In
<ELFT
>::RelaDyn
->addReloc(
256 {Target
->TlsOffsetRel
, InX::Got
, OffsetOff
, false, &Body
, 0});
258 InX::Got
->Relocations
.push_back(
259 {R_ABS
, Target
->TlsOffsetRel
, OffsetOff
, 0, &Body
});
261 C
.Relocations
.push_back({Expr
, Type
, Offset
, Addend
, &Body
});
265 // Global-Dynamic relocs can be relaxed to Initial-Exec or Local-Exec
266 // depending on the symbol being locally defined or not.
268 C
.Relocations
.push_back(
269 {Target
->adjustRelaxExpr(Type
, nullptr, R_RELAX_TLS_GD_TO_IE
), Type
,
270 Offset
, Addend
, &Body
});
271 if (!Body
.isInGot()) {
272 InX::Got
->addEntry(Body
);
273 In
<ELFT
>::RelaDyn
->addReloc({Target
->TlsGotRel
, InX::Got
,
274 Body
.getGotOffset(), false, &Body
, 0});
277 C
.Relocations
.push_back(
278 {Target
->adjustRelaxExpr(Type
, nullptr, R_RELAX_TLS_GD_TO_LE
), Type
,
279 Offset
, Addend
, &Body
});
281 return Target
->TlsGdRelaxSkip
;
284 // Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally
286 if (isRelExprOneOf
<R_GOT
, R_GOT_FROM_END
, R_GOT_PC
, R_GOT_PAGE_PC
>(Expr
) &&
287 !Config
->Shared
&& !IsPreemptible
) {
288 C
.Relocations
.push_back(
289 {R_RELAX_TLS_IE_TO_LE
, Type
, Offset
, Addend
, &Body
});
293 if (Expr
== R_TLSDESC_CALL
)
298 static uint32_t getMipsPairType(uint32_t Type
, const SymbolBody
&Sym
) {
303 return Sym
.isLocal() ? R_MIPS_LO16
: R_MIPS_NONE
;
305 return R_MIPS_PCLO16
;
306 case R_MICROMIPS_HI16
:
307 return R_MICROMIPS_LO16
;
313 // True if non-preemptable symbol always has the same value regardless of where
314 // the DSO is loaded.
315 static bool isAbsolute(const SymbolBody
&Body
) {
316 if (Body
.isUndefined())
317 return !Body
.isLocal() && Body
.symbol()->isWeak();
318 if (const auto *DR
= dyn_cast
<DefinedRegular
>(&Body
))
319 return DR
->Section
== nullptr; // Absolute symbol.
323 static bool isAbsoluteValue(const SymbolBody
&Body
) {
324 return isAbsolute(Body
) || Body
.isTls();
327 // Returns true if Expr refers a PLT entry.
328 static bool needsPlt(RelExpr Expr
) {
329 return isRelExprOneOf
<R_PLT_PC
, R_PPC_PLT_OPD
, R_PLT
, R_PLT_PAGE_PC
>(Expr
);
332 // Returns true if Expr refers a GOT entry. Note that this function
333 // returns false for TLS variables even though they need GOT, because
334 // TLS variables uses GOT differently than the regular variables.
335 static bool needsGot(RelExpr Expr
) {
336 return isRelExprOneOf
<R_GOT
, R_GOT_OFF
, R_MIPS_GOT_LOCAL_PAGE
, R_MIPS_GOT_OFF
,
337 R_MIPS_GOT_OFF32
, R_GOT_PAGE_PC
, R_GOT_PC
,
338 R_GOT_FROM_END
>(Expr
);
341 // True if this expression is of the form Sym - X, where X is a position in the
342 // file (PC, or GOT for example).
343 static bool isRelExpr(RelExpr Expr
) {
344 return isRelExprOneOf
<R_PC
, R_GOTREL
, R_GOTREL_FROM_END
, R_MIPS_GOTREL
,
345 R_PAGE_PC
, R_RELAX_GOT_PC
>(Expr
);
348 // Returns true if a given relocation can be computed at link-time.
350 // For instance, we know the offset from a relocation to its target at
351 // link-time if the relocation is PC-relative and refers a
352 // non-interposable function in the same executable. This function
353 // will return true for such relocation.
355 // If this function returns false, that means we need to emit a
356 // dynamic relocation so that the relocation will be fixed at load-time.
357 template <class ELFT
>
358 static bool isStaticLinkTimeConstant(RelExpr E
, uint32_t Type
,
359 const SymbolBody
&Body
,
360 InputSectionBase
&S
, uint64_t RelOff
) {
361 // These expressions always compute a constant
362 if (isRelExprOneOf
<R_SIZE
, R_GOT_FROM_END
, R_GOT_OFF
, R_MIPS_GOT_LOCAL_PAGE
,
363 R_MIPS_GOT_OFF
, R_MIPS_GOT_OFF32
, R_MIPS_GOT_GP_PC
,
364 R_MIPS_TLSGD
, R_GOT_PAGE_PC
, R_GOT_PC
, R_GOTONLY_PC
,
365 R_GOTONLY_PC_FROM_END
, R_PLT_PC
, R_TLSGD_PC
, R_TLSGD
,
366 R_PPC_PLT_OPD
, R_TLSDESC_CALL
, R_TLSDESC_PAGE
, R_HINT
>(E
))
369 // These never do, except if the entire file is position dependent or if
370 // only the low bits are used.
371 if (E
== R_GOT
|| E
== R_PLT
|| E
== R_TLSDESC
)
372 return Target
->usesOnlyLowPageBits(Type
) || !Config
->Pic
;
374 if (isPreemptible(Body
, Type
))
379 // For the target and the relocation, we want to know if they are
380 // absolute or relative.
381 bool AbsVal
= isAbsoluteValue(Body
);
382 bool RelE
= isRelExpr(E
);
387 if (!AbsVal
&& !RelE
)
388 return Target
->usesOnlyLowPageBits(Type
);
390 // Relative relocation to an absolute value. This is normally unrepresentable,
391 // but if the relocation refers to a weak undefined symbol, we allow it to
392 // resolve to the image base. This is a little strange, but it allows us to
393 // link function calls to such symbols. Normally such a call will be guarded
394 // with a comparison, which will load a zero from the GOT.
395 // Another special case is MIPS _gp_disp symbol which represents offset
396 // between start of a function and '_gp' value and defined as absolute just
397 // to simplify the code.
398 assert(AbsVal
&& RelE
);
399 if (Body
.isUndefined() && !Body
.isLocal() && Body
.symbol()->isWeak())
402 error("relocation " + toString(Type
) + " cannot refer to absolute symbol: " +
403 toString(Body
) + getLocation
<ELFT
>(S
, Body
, RelOff
));
407 static RelExpr
toPlt(RelExpr Expr
) {
408 if (Expr
== R_PPC_OPD
)
409 return R_PPC_PLT_OPD
;
412 if (Expr
== R_PAGE_PC
)
413 return R_PLT_PAGE_PC
;
419 static RelExpr
fromPlt(RelExpr Expr
) {
420 // We decided not to use a plt. Optimize a reference to the plt to a
421 // reference to the symbol itself.
422 if (Expr
== R_PLT_PC
)
424 if (Expr
== R_PPC_PLT_OPD
)
431 // Returns true if a given shared symbol is in a read-only segment in a DSO.
432 template <class ELFT
> static bool isReadOnly(SharedSymbol
*SS
) {
433 typedef typename
ELFT::Phdr Elf_Phdr
;
434 uint64_t Value
= SS
->getValue
<ELFT
>();
436 // Determine if the symbol is read-only by scanning the DSO's program headers.
437 const SharedFile
<ELFT
> *File
= SS
->getFile
<ELFT
>();
438 for (const Elf_Phdr
&Phdr
: check(File
->getObj().program_headers()))
439 if ((Phdr
.p_type
== ELF::PT_LOAD
|| Phdr
.p_type
== ELF::PT_GNU_RELRO
) &&
440 !(Phdr
.p_flags
& ELF::PF_W
) && Value
>= Phdr
.p_vaddr
&&
441 Value
< Phdr
.p_vaddr
+ Phdr
.p_memsz
)
446 // Returns symbols at the same offset as a given symbol, including SS itself.
448 // If two or more symbols are at the same offset, and at least one of
449 // them are copied by a copy relocation, all of them need to be copied.
450 // Otherwise, they would refer different places at runtime.
451 template <class ELFT
>
452 static std::vector
<SharedSymbol
*> getSymbolsAt(SharedSymbol
*SS
) {
453 typedef typename
ELFT::Sym Elf_Sym
;
455 SharedFile
<ELFT
> *File
= SS
->getFile
<ELFT
>();
456 uint64_t Shndx
= SS
->getShndx
<ELFT
>();
457 uint64_t Value
= SS
->getValue
<ELFT
>();
459 std::vector
<SharedSymbol
*> Ret
;
460 for (const Elf_Sym
&S
: File
->getGlobalELFSyms()) {
461 if (S
.st_shndx
!= Shndx
|| S
.st_value
!= Value
)
463 StringRef Name
= check(S
.getName(File
->getStringTable()));
464 SymbolBody
*Sym
= Symtab
->find(Name
);
465 if (auto *Alias
= dyn_cast_or_null
<SharedSymbol
>(Sym
))
466 Ret
.push_back(Alias
);
471 // Reserve space in .bss or .bss.rel.ro for copy relocation.
473 // The copy relocation is pretty much a hack. If you use a copy relocation
474 // in your program, not only the symbol name but the symbol's size, RW/RO
475 // bit and alignment become part of the ABI. In addition to that, if the
476 // symbol has aliases, the aliases become part of the ABI. That's subtle,
477 // but if you violate that implicit ABI, that can cause very counter-
478 // intuitive consequences.
480 // So, what is the copy relocation? It's for linking non-position
481 // independent code to DSOs. In an ideal world, all references to data
482 // exported by DSOs should go indirectly through GOT. But if object files
483 // are compiled as non-PIC, all data references are direct. There is no
484 // way for the linker to transform the code to use GOT, as machine
485 // instructions are already set in stone in object files. This is where
486 // the copy relocation takes a role.
488 // A copy relocation instructs the dynamic linker to copy data from a DSO
489 // to a specified address (which is usually in .bss) at load-time. If the
490 // static linker (that's us) finds a direct data reference to a DSO
491 // symbol, it creates a copy relocation, so that the symbol can be
492 // resolved as if it were in .bss rather than in a DSO.
494 // As you can see in this function, we create a copy relocation for the
495 // dynamic linker, and the relocation contains not only symbol name but
496 // various other informtion about the symbol. So, such attributes become a
499 // Note for application developers: I can give you a piece of advice if
500 // you are writing a shared library. You probably should export only
501 // functions from your library. You shouldn't export variables.
503 // As an example what can happen when you export variables without knowing
504 // the semantics of copy relocations, assume that you have an exported
505 // variable of type T. It is an ABI-breaking change to add new members at
506 // end of T even though doing that doesn't change the layout of the
507 // existing members. That's because the space for the new members are not
508 // reserved in .bss unless you recompile the main program. That means they
509 // are likely to overlap with other data that happens to be laid out next
510 // to the variable in .bss. This kind of issue is sometimes very hard to
511 // debug. What's a solution? Instead of exporting a varaible V from a DSO,
512 // define an accessor getV().
513 template <class ELFT
> static void addCopyRelSymbol(SharedSymbol
*SS
) {
514 // Copy relocation against zero-sized symbol doesn't make sense.
515 uint64_t SymSize
= SS
->template getSize
<ELFT
>();
517 fatal("cannot create a copy relocation for symbol " + toString(*SS
));
519 // See if this symbol is in a read-only segment. If so, preserve the symbol's
520 // memory protection by reserving space in the .bss.rel.ro section.
521 bool IsReadOnly
= isReadOnly
<ELFT
>(SS
);
522 BssSection
*Sec
= IsReadOnly
? InX::BssRelRo
: InX::Bss
;
523 uint64_t Off
= Sec
->reserveSpace(SymSize
, SS
->getAlignment
<ELFT
>());
525 // Look through the DSO's dynamic symbol table for aliases and create a
526 // dynamic symbol for each one. This causes the copy relocation to correctly
527 // interpose any aliases.
528 for (SharedSymbol
*Sym
: getSymbolsAt
<ELFT
>(SS
)) {
529 Sym
->CopyRelSec
= Sec
;
530 Sym
->CopyRelSecOff
= Off
;
531 Sym
->symbol()->IsUsedInRegularObj
= true;
534 In
<ELFT
>::RelaDyn
->addReloc({Target
->CopyRel
, Sec
, Off
, false, SS
, 0});
537 static void errorOrWarn(const Twine
&Msg
) {
538 if (!Config
->NoinhibitExec
)
544 template <class ELFT
>
545 static RelExpr
adjustExpr(SymbolBody
&Body
, RelExpr Expr
, uint32_t Type
,
546 const uint8_t *Data
, InputSectionBase
&S
,
547 typename
ELFT::uint RelOff
) {
548 if (Body
.isGnuIFunc()) {
550 } else if (!isPreemptible(Body
, Type
)) {
552 Expr
= fromPlt(Expr
);
553 if (Expr
== R_GOT_PC
&& !isAbsoluteValue(Body
))
554 Expr
= Target
->adjustRelaxExpr(Type
, Data
, Expr
);
557 bool IsWrite
= !Config
->ZText
|| (S
.Flags
& SHF_WRITE
);
558 if (IsWrite
|| isStaticLinkTimeConstant
<ELFT
>(Expr
, Type
, Body
, S
, RelOff
))
561 // This relocation would require the dynamic linker to write a value to read
562 // only memory. We can hack around it if we are producing an executable and
563 // the refered symbol can be preemepted to refer to the executable.
564 if (Config
->Shared
|| (Config
->Pic
&& !isRelExpr(Expr
))) {
565 error("can't create dynamic relocation " + toString(Type
) + " against " +
566 (Body
.getName().empty() ? "local symbol"
567 : "symbol: " + toString(Body
)) +
568 " in readonly segment" + getLocation
<ELFT
>(S
, Body
, RelOff
));
572 if (Body
.getVisibility() != STV_DEFAULT
) {
573 error("cannot preempt symbol: " + toString(Body
) +
574 getLocation
<ELFT
>(S
, Body
, RelOff
));
578 if (Body
.isObject()) {
579 // Produce a copy relocation.
580 auto *B
= cast
<SharedSymbol
>(&Body
);
581 if (!B
->CopyRelSec
) {
582 if (Config
->ZNocopyreloc
)
583 error("unresolvable relocation " + toString(Type
) +
584 " against symbol '" + toString(*B
) +
585 "'; recompile with -fPIC or remove '-z nocopyreloc'" +
586 getLocation
<ELFT
>(S
, Body
, RelOff
));
588 addCopyRelSymbol
<ELFT
>(B
);
594 // This handles a non PIC program call to function in a shared library. In
595 // an ideal world, we could just report an error saying the relocation can
596 // overflow at runtime. In the real world with glibc, crt1.o has a
597 // R_X86_64_PC32 pointing to libc.so.
599 // The general idea on how to handle such cases is to create a PLT entry and
600 // use that as the function value.
602 // For the static linking part, we just return a plt expr and everything
603 // else will use the the PLT entry as the address.
605 // The remaining problem is making sure pointer equality still works. We
606 // need the help of the dynamic linker for that. We let it know that we have
607 // a direct reference to a so symbol by creating an undefined symbol with a
608 // non zero st_value. Seeing that, the dynamic linker resolves the symbol to
609 // the value of the symbol we created. This is true even for got entries, so
610 // pointer equality is maintained. To avoid an infinite loop, the only entry
611 // that points to the real function is a dedicated got entry used by the
612 // plt. That is identified by special relocation types (R_X86_64_JUMP_SLOT,
613 // R_386_JMP_SLOT, etc).
614 Body
.NeedsPltAddr
= true;
618 errorOrWarn("symbol '" + toString(Body
) + "' defined in " +
619 toString(Body
.getFile()) + " has no type");
623 // Returns an addend of a given relocation. If it is RELA, an addend
624 // is in a relocation itself. If it is REL, we need to read it from an
626 template <class ELFT
, class RelTy
>
627 static int64_t computeAddend(const RelTy
&Rel
, const uint8_t *Buf
) {
628 uint32_t Type
= Rel
.getType(Config
->IsMips64EL
);
629 int64_t A
= RelTy::IsRela
630 ? getAddend
<ELFT
>(Rel
)
631 : Target
->getImplicitAddend(Buf
+ Rel
.r_offset
, Type
);
633 if (Config
->EMachine
== EM_PPC64
&& Config
->Pic
&& Type
== R_PPC64_TOC
)
634 A
+= getPPC64TocBase();
638 // MIPS has an odd notion of "paired" relocations to calculate addends.
639 // For example, if a relocation is of R_MIPS_HI16, there must be a
640 // R_MIPS_LO16 relocation after that, and an addend is calculated using
641 // the two relocations.
642 template <class ELFT
, class RelTy
>
643 static int64_t computeMipsAddend(const RelTy
&Rel
, InputSectionBase
&Sec
,
644 RelExpr Expr
, SymbolBody
&Body
,
646 if (Expr
== R_MIPS_GOTREL
&& Body
.isLocal())
647 return Sec
.getFile
<ELFT
>()->MipsGp0
;
649 // The ABI says that the paired relocation is used only for REL.
650 // See p. 4-17 at ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
654 uint32_t Type
= Rel
.getType(Config
->IsMips64EL
);
655 uint32_t PairTy
= getMipsPairType(Type
, Body
);
656 if (PairTy
== R_MIPS_NONE
)
659 const uint8_t *Buf
= Sec
.Data
.data();
660 uint32_t SymIndex
= Rel
.getSymbol(Config
->IsMips64EL
);
662 // To make things worse, paired relocations might not be contiguous in
663 // the relocation table, so we need to do linear search. *sigh*
664 for (const RelTy
*RI
= &Rel
; RI
!= End
; ++RI
) {
665 if (RI
->getType(Config
->IsMips64EL
) != PairTy
)
667 if (RI
->getSymbol(Config
->IsMips64EL
) != SymIndex
)
670 endianness E
= Config
->Endianness
;
671 int32_t Hi
= (read32(Buf
+ Rel
.r_offset
, E
) & 0xffff) << 16;
672 int32_t Lo
= SignExtend32
<16>(read32(Buf
+ RI
->r_offset
, E
));
676 warn("can't find matching " + toString(PairTy
) + " relocation for " +
681 template <class ELFT
>
682 static void reportUndefined(SymbolBody
&Sym
, InputSectionBase
&S
,
684 if (Config
->UnresolvedSymbols
== UnresolvedPolicy::IgnoreAll
)
687 bool CanBeExternal
= Sym
.symbol()->computeBinding() != STB_LOCAL
&&
688 Sym
.getVisibility() == STV_DEFAULT
;
689 if (Config
->UnresolvedSymbols
== UnresolvedPolicy::Ignore
&& CanBeExternal
)
693 "undefined symbol: " + toString(Sym
) + "\n>>> referenced by ";
695 std::string Src
= S
.getSrcMsg
<ELFT
>(Offset
);
697 Msg
+= Src
+ "\n>>> ";
698 Msg
+= S
.getObjMsg
<ELFT
>(Offset
);
700 if (Config
->UnresolvedSymbols
== UnresolvedPolicy::Warn
&& CanBeExternal
)
706 template <class RelTy
>
707 static std::pair
<uint32_t, uint32_t>
708 mergeMipsN32RelTypes(uint32_t Type
, uint32_t Offset
, RelTy
*I
, RelTy
*E
) {
709 // MIPS N32 ABI treats series of successive relocations with the same offset
710 // as a single relocation. The similar approach used by N64 ABI, but this ABI
711 // packs all relocations into the single relocation record. Here we emulate
712 // this for the N32 ABI. Iterate over relocation with the same offset and put
713 // theirs types into the single bit-set.
714 uint32_t Processed
= 0;
715 for (; I
!= E
&& Offset
== I
->r_offset
; ++I
) {
717 Type
|= I
->getType(Config
->IsMips64EL
) << (8 * Processed
);
719 return std::make_pair(Type
, Processed
);
722 // .eh_frame sections are mergeable input sections, so their input
723 // offsets are not linearly mapped to output section. For each input
724 // offset, we need to find a section piece containing the offset and
725 // add the piece's base address to the input offset to compute the
726 // output offset. That isn't cheap.
728 // This class is to speed up the offset computation. When we process
729 // relocations, we access offsets in the monotonically increasing
730 // order. So we can optimize for that access pattern.
732 // For sections other than .eh_frame, this class doesn't do anything.
736 explicit OffsetGetter(InputSectionBase
&Sec
) {
737 if (auto *Eh
= dyn_cast
<EhInputSection
>(&Sec
)) {
739 Size
= Eh
->Pieces
.size();
743 // Translates offsets in input sections to offsets in output sections.
744 // Given offset must increase monotonically. We assume that P is
745 // sorted by InputOff.
746 uint64_t get(uint64_t Off
) {
750 while (I
!= Size
&& P
[I
].InputOff
+ P
[I
].size() <= Off
)
755 // P must be contiguous, so there must be no holes in between.
756 assert(P
[I
].InputOff
<= Off
&& "Relocation not in any piece");
758 // Offset -1 means that the piece is dead (i.e. garbage collected).
759 if (P
[I
].OutputOff
== -1)
761 return P
[I
].OutputOff
+ Off
- P
[I
].InputOff
;
765 ArrayRef
<EhSectionPiece
> P
;
771 template <class ELFT
, class GotPltSection
>
772 static void addPltEntry(PltSection
*Plt
, GotPltSection
*GotPlt
,
773 RelocationSection
<ELFT
> *Rel
, uint32_t Type
,
774 SymbolBody
&Sym
, bool UseSymVA
) {
775 Plt
->addEntry
<ELFT
>(Sym
);
776 GotPlt
->addEntry(Sym
);
777 Rel
->addReloc({Type
, GotPlt
, Sym
.getGotPltOffset(), UseSymVA
, &Sym
, 0});
780 template <class ELFT
>
781 static void addGotEntry(SymbolBody
&Sym
, bool Preemptible
) {
782 InX::Got
->addEntry(Sym
);
784 uint64_t Off
= Sym
.getGotOffset();
786 RelExpr Expr
= R_ABS
;
789 DynType
= Target
->TlsGotRel
;
791 } else if (!Preemptible
&& Config
->Pic
&& !isAbsolute(Sym
)) {
792 DynType
= Target
->RelativeRel
;
794 DynType
= Target
->GotRel
;
797 bool Constant
= !Preemptible
&& !(Config
->Pic
&& !isAbsolute(Sym
));
799 In
<ELFT
>::RelaDyn
->addReloc(
800 {DynType
, InX::Got
, Off
, !Preemptible
, &Sym
, 0});
802 if (Constant
|| (!Config
->IsRela
&& !Preemptible
))
803 InX::Got
->Relocations
.push_back({Expr
, DynType
, Off
, 0, &Sym
});
806 // The reason we have to do this early scan is as follows
807 // * To mmap the output file, we need to know the size
808 // * For that, we need to know how many dynamic relocs we will have.
809 // It might be possible to avoid this by outputting the file with write:
810 // * Write the allocated output sections, computing addresses.
811 // * Apply relocations, recording which ones require a dynamic reloc.
812 // * Write the dynamic relocations.
813 // * Write the rest of the file.
814 // This would have some drawbacks. For example, we would only know if .rela.dyn
815 // is needed after applying relocations. If it is, it will go after rw and rx
816 // sections. Given that it is ro, we will need an extra PT_LOAD. This
817 // complicates things for the dynamic linker and means we would have to reserve
818 // space for the extra PT_LOAD even if we end up not using it.
819 template <class ELFT
, class RelTy
>
820 static void scanRelocs(InputSectionBase
&Sec
, ArrayRef
<RelTy
> Rels
) {
821 OffsetGetter
GetOffset(Sec
);
823 for (auto I
= Rels
.begin(), End
= Rels
.end(); I
!= End
; ++I
) {
824 const RelTy
&Rel
= *I
;
825 SymbolBody
&Body
= Sec
.getFile
<ELFT
>()->getRelocTargetSym(Rel
);
826 uint32_t Type
= Rel
.getType(Config
->IsMips64EL
);
828 if (Config
->MipsN32Abi
) {
830 std::tie(Type
, Processed
) =
831 mergeMipsN32RelTypes(Type
, Rel
.r_offset
, I
+ 1, End
);
835 // Compute the offset of this section in the output section.
836 uint64_t Offset
= GetOffset
.get(Rel
.r_offset
);
837 if (Offset
== uint64_t(-1))
840 // Report undefined symbols. The fact that we report undefined
841 // symbols here means that we report undefined symbols only when
842 // they have relocations pointing to them. We don't care about
843 // undefined symbols that are in dead-stripped sections.
844 if (!Body
.isLocal() && Body
.isUndefined() && !Body
.symbol()->isWeak())
845 reportUndefined
<ELFT
>(Body
, Sec
, Rel
.r_offset
);
847 RelExpr Expr
= Target
->getRelExpr(Type
, Body
, *Sec
.File
,
848 Sec
.Data
.begin() + Rel
.r_offset
);
850 // Ignore "hint" relocations because they are only markers for relaxation.
851 if (isRelExprOneOf
<R_HINT
, R_NONE
>(Expr
))
854 bool Preemptible
= isPreemptible(Body
, Type
);
855 Expr
= adjustExpr
<ELFT
>(Body
, Expr
, Type
, Sec
.Data
.data() + Rel
.r_offset
,
860 // This relocation does not require got entry, but it is relative to got and
861 // needs it to be created. Here we request for that.
862 if (isRelExprOneOf
<R_GOTONLY_PC
, R_GOTONLY_PC_FROM_END
, R_GOTREL
,
863 R_GOTREL_FROM_END
, R_PPC_TOC
>(Expr
))
864 InX::Got
->HasGotOffRel
= true;
867 int64_t Addend
= computeAddend
<ELFT
>(Rel
, Sec
.Data
.data());
868 if (Config
->EMachine
== EM_MIPS
)
869 Addend
+= computeMipsAddend
<ELFT
>(Rel
, Sec
, Expr
, Body
, End
);
871 // Process some TLS relocations, including relaxing TLS relocations.
872 // Note that this function does not handle all TLS relocations.
873 if (unsigned Processed
=
874 handleTlsRelocation
<ELFT
>(Type
, Body
, Sec
, Offset
, Addend
, Expr
)) {
875 I
+= (Processed
- 1);
879 // If a relocation needs PLT, we create PLT and GOTPLT slots for the symbol.
880 if (needsPlt(Expr
) && !Body
.isInPlt()) {
881 if (Body
.isGnuIFunc() && !Preemptible
)
882 addPltEntry(InX::Iplt
, InX::IgotPlt
, In
<ELFT
>::RelaIplt
,
883 Target
->IRelativeRel
, Body
, true);
885 addPltEntry(InX::Plt
, InX::GotPlt
, In
<ELFT
>::RelaPlt
, Target
->PltRel
,
889 // Create a GOT slot if a relocation needs GOT.
890 if (needsGot(Expr
)) {
891 if (Config
->EMachine
== EM_MIPS
) {
892 // MIPS ABI has special rules to process GOT entries and doesn't
893 // require relocation entries for them. A special case is TLS
894 // relocations. In that case dynamic loader applies dynamic
895 // relocations to initialize TLS GOT entries.
896 // See "Global Offset Table" in Chapter 5 in the following document
897 // for detailed description:
898 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
899 InX::MipsGot
->addEntry(Body
, Addend
, Expr
);
900 if (Body
.isTls() && Body
.isPreemptible())
901 In
<ELFT
>::RelaDyn
->addReloc({Target
->TlsGotRel
, InX::MipsGot
,
902 Body
.getGotOffset(), false, &Body
, 0});
903 } else if (!Body
.isInGot()) {
904 addGotEntry
<ELFT
>(Body
, Preemptible
);
908 if (!needsPlt(Expr
) && !needsGot(Expr
) && isPreemptible(Body
, Type
)) {
909 // We don't know anything about the finaly symbol. Just ask the dynamic
910 // linker to handle the relocation for us.
911 if (!Target
->isPicRel(Type
))
913 "relocation " + toString(Type
) +
914 " cannot be used against shared object; recompile with -fPIC" +
915 getLocation
<ELFT
>(Sec
, Body
, Offset
));
917 In
<ELFT
>::RelaDyn
->addReloc(
918 {Target
->getDynRel(Type
), &Sec
, Offset
, false, &Body
, Addend
});
920 // MIPS ABI turns using of GOT and dynamic relocations inside out.
921 // While regular ABI uses dynamic relocations to fill up GOT entries
922 // MIPS ABI requires dynamic linker to fills up GOT entries using
923 // specially sorted dynamic symbol table. This affects even dynamic
924 // relocations against symbols which do not require GOT entries
925 // creation explicitly, i.e. do not have any GOT-relocations. So if
926 // a preemptible symbol has a dynamic relocation we anyway have
927 // to create a GOT entry for it.
928 // If a non-preemptible symbol has a dynamic relocation against it,
929 // dynamic linker takes it st_value, adds offset and writes down
930 // result of the dynamic relocation. In case of preemptible symbol
931 // dynamic linker performs symbol resolution, writes the symbol value
932 // to the GOT entry and reads the GOT entry when it needs to perform
933 // a dynamic relocation.
934 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf p.4-19
935 if (Config
->EMachine
== EM_MIPS
)
936 InX::MipsGot
->addEntry(Body
, Addend
, Expr
);
940 // If the relocation points to something in the file, we can process it.
942 isStaticLinkTimeConstant
<ELFT
>(Expr
, Type
, Body
, Sec
, Rel
.r_offset
);
944 // The size is not going to change, so we fold it in here.
946 Addend
+= Body
.getSize
<ELFT
>();
948 // If the output being produced is position independent, the final value
949 // is still not known. In that case we still need some help from the
950 // dynamic linker. We can however do better than just copying the incoming
951 // relocation. We can process some of it and and just ask the dynamic
952 // linker to add the load address.
954 In
<ELFT
>::RelaDyn
->addReloc(
955 {Target
->RelativeRel
, &Sec
, Offset
, true, &Body
, Addend
});
957 // If the produced value is a constant, we just remember to write it
958 // when outputting this section. We also have to do it if the format
959 // uses Elf_Rel, since in that case the written value is the addend.
960 if (IsConstant
|| !RelTy::IsRela
)
961 Sec
.Relocations
.push_back({Expr
, Type
, Offset
, Addend
, &Body
});
965 template <class ELFT
> void elf::scanRelocations(InputSectionBase
&S
) {
967 scanRelocs
<ELFT
>(S
, S
.relas
<ELFT
>());
969 scanRelocs
<ELFT
>(S
, S
.rels
<ELFT
>());
972 // Insert the Thunks for OutputSection OS into their designated place
973 // in the Sections vector, and recalculate the InputSection output section
975 // This may invalidate any output section offsets stored outside of InputSection
976 void ThunkCreator::mergeThunks() {
977 for (auto &KV
: ThunkSections
) {
978 std::vector
<InputSection
*> *ISR
= KV
.first
;
979 std::vector
<ThunkSection
*> &Thunks
= KV
.second
;
981 // Order Thunks in ascending OutSecOff
982 auto ThunkCmp
= [](const ThunkSection
*A
, const ThunkSection
*B
) {
983 return A
->OutSecOff
< B
->OutSecOff
;
985 std::stable_sort(Thunks
.begin(), Thunks
.end(), ThunkCmp
);
987 // Merge sorted vectors of Thunks and InputSections by OutSecOff
988 std::vector
<InputSection
*> Tmp
;
989 Tmp
.reserve(ISR
->size() + Thunks
.size());
990 auto MergeCmp
= [](const InputSection
*A
, const InputSection
*B
) {
991 // std::merge requires a strict weak ordering.
992 if (A
->OutSecOff
< B
->OutSecOff
)
994 if (A
->OutSecOff
== B
->OutSecOff
)
995 // Check if Thunk is immediately before any specific Target InputSection
996 // for example Mips LA25 Thunks.
997 if (auto *TA
= dyn_cast
<ThunkSection
>(A
))
998 if (TA
&& TA
->getTargetInputSection() == B
)
1002 std::merge(ISR
->begin(), ISR
->end(), Thunks
.begin(), Thunks
.end(),
1003 std::back_inserter(Tmp
), MergeCmp
);
1004 *ISR
= std::move(Tmp
);
1008 static uint32_t findEndOfFirstNonExec(OutputSection
&Cmd
) {
1009 for (BaseCommand
*Base
: Cmd
.Commands
)
1010 if (auto *ISD
= dyn_cast
<InputSectionDescription
>(Base
))
1011 for (auto *IS
: ISD
->Sections
)
1012 if ((IS
->Flags
& SHF_EXECINSTR
) == 0)
1013 return IS
->OutSecOff
+ IS
->getSize();
1017 ThunkSection
*ThunkCreator::getOSThunkSec(OutputSection
*Cmd
,
1018 std::vector
<InputSection
*> *ISR
) {
1019 if (CurTS
== nullptr) {
1020 uint32_t Off
= findEndOfFirstNonExec(*Cmd
);
1021 CurTS
= addThunkSection(Cmd
, ISR
, Off
);
1026 ThunkSection
*ThunkCreator::getISThunkSec(InputSection
*IS
, OutputSection
*OS
) {
1027 ThunkSection
*TS
= ThunkedSections
.lookup(IS
);
1031 // Find InputSectionRange within TOS that IS is in
1032 OutputSection
*C
= IS
->getParent();
1033 std::vector
<InputSection
*> *Range
= nullptr;
1034 for (BaseCommand
*BC
: C
->Commands
)
1035 if (auto *ISD
= dyn_cast
<InputSectionDescription
>(BC
)) {
1036 InputSection
*first
= ISD
->Sections
.front();
1037 InputSection
*last
= ISD
->Sections
.back();
1038 if (IS
->OutSecOff
>= first
->OutSecOff
&&
1039 IS
->OutSecOff
<= last
->OutSecOff
) {
1040 Range
= &ISD
->Sections
;
1044 TS
= addThunkSection(C
, Range
, IS
->OutSecOff
);
1045 ThunkedSections
[IS
] = TS
;
1049 ThunkSection
*ThunkCreator::addThunkSection(OutputSection
*Cmd
,
1050 std::vector
<InputSection
*> *ISR
,
1052 auto *TS
= make
<ThunkSection
>(Cmd
, Off
);
1053 ThunkSections
[ISR
].push_back(TS
);
1057 std::pair
<Thunk
*, bool> ThunkCreator::getThunk(SymbolBody
&Body
,
1059 auto Res
= ThunkedSymbols
.insert({&Body
, std::vector
<Thunk
*>()});
1061 // Check existing Thunks for Body to see if they can be reused
1062 for (Thunk
*ET
: Res
.first
->second
)
1063 if (ET
->isCompatibleWith(Type
))
1064 return std::make_pair(ET
, false);
1066 // No existing compatible Thunk in range, create a new one
1067 Thunk
*T
= addThunk(Type
, Body
);
1068 Res
.first
->second
.push_back(T
);
1069 return std::make_pair(T
, true);
1072 // Call Fn on every executable InputSection accessed via the linker script
1073 // InputSectionDescription::Sections.
1074 void ThunkCreator::forEachExecInputSection(
1075 ArrayRef
<OutputSection
*> OutputSections
,
1076 std::function
<void(OutputSection
*, std::vector
<InputSection
*> *,
1079 for (OutputSection
*OS
: OutputSections
) {
1080 if (!(OS
->Flags
& SHF_ALLOC
) || !(OS
->Flags
& SHF_EXECINSTR
))
1082 for (BaseCommand
*BC
: OS
->Commands
)
1083 if (auto *ISD
= dyn_cast
<InputSectionDescription
>(BC
)) {
1085 for (InputSection
*IS
: ISD
->Sections
)
1086 Fn(OS
, &ISD
->Sections
, IS
);
1091 // Process all relocations from the InputSections that have been assigned
1092 // to OutputSections and redirect through Thunks if needed.
1094 // createThunks must be called after scanRelocs has created the Relocations for
1095 // each InputSection. It must be called before the static symbol table is
1096 // finalized. If any Thunks are added to an OutputSection the output section
1097 // offsets of the InputSections will change.
1099 // FIXME: All Thunks are assumed to be in range of the relocation. Range
1100 // extension Thunks are not yet supported.
1101 bool ThunkCreator::createThunks(ArrayRef
<OutputSection
*> OutputSections
) {
1103 ThunkSections
.clear();
1105 // Create all the Thunks and insert them into synthetic ThunkSections. The
1106 // ThunkSections are later inserted back into the OutputSection.
1108 // We separate the creation of ThunkSections from the insertion of the
1109 // ThunkSections back into the OutputSection as ThunkSections are not always
1110 // inserted into the same OutputSection as the caller.
1111 forEachExecInputSection(OutputSections
, [&](OutputSection
*Cmd
,
1112 std::vector
<InputSection
*> *ISR
,
1114 for (Relocation
&Rel
: IS
->Relocations
) {
1115 SymbolBody
&Body
= *Rel
.Sym
;
1116 if (Thunks
.find(&Body
) != Thunks
.end() ||
1117 !Target
->needsThunk(Rel
.Expr
, Rel
.Type
, IS
->File
, Body
))
1121 std::tie(T
, IsNew
) = getThunk(Body
, Rel
.Type
);
1123 // Find or create a ThunkSection for the new Thunk
1125 if (auto *TIS
= T
->getTargetInputSection())
1126 TS
= getISThunkSec(TIS
, Cmd
);
1128 TS
= getOSThunkSec(Cmd
, ISR
);
1130 Thunks
[T
->ThunkSym
] = T
;
1132 // Redirect relocation to Thunk, we never go via the PLT to a Thunk
1133 Rel
.Sym
= T
->ThunkSym
;
1134 Rel
.Expr
= fromPlt(Rel
.Expr
);
1137 // Merge all created synthetic ThunkSections back into OutputSection
1140 return !ThunkSections
.empty();
1143 template void elf::scanRelocations
<ELF32LE
>(InputSectionBase
&);
1144 template void elf::scanRelocations
<ELF32BE
>(InputSectionBase
&);
1145 template void elf::scanRelocations
<ELF64LE
>(InputSectionBase
&);
1146 template void elf::scanRelocations
<ELF64BE
>(InputSectionBase
&);