1 | //===- Config.h -------------------------------------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LLD_ELF_CONFIG_H |
10 | #define LLD_ELF_CONFIG_H |
11 | |
12 | #include "lld/Common/ErrorHandler.h" |
13 | #include "llvm/ADT/CachedHashString.h" |
14 | #include "llvm/ADT/DenseSet.h" |
15 | #include "llvm/ADT/MapVector.h" |
16 | #include "llvm/ADT/SetVector.h" |
17 | #include "llvm/ADT/SmallSet.h" |
18 | #include "llvm/ADT/StringRef.h" |
19 | #include "llvm/ADT/StringSet.h" |
20 | #include "llvm/BinaryFormat/ELF.h" |
21 | #include "llvm/Option/ArgList.h" |
22 | #include "llvm/Support/CachePruning.h" |
23 | #include "llvm/Support/CodeGen.h" |
24 | #include "llvm/Support/Compiler.h" |
25 | #include "llvm/Support/Compression.h" |
26 | #include "llvm/Support/Endian.h" |
27 | #include "llvm/Support/FileSystem.h" |
28 | #include "llvm/Support/GlobPattern.h" |
29 | #include "llvm/Support/PrettyStackTrace.h" |
30 | #include <atomic> |
31 | #include <memory> |
32 | #include <optional> |
33 | #include <vector> |
34 | |
35 | namespace lld::elf { |
36 | |
37 | class InputFile; |
38 | class BinaryFile; |
39 | class BitcodeFile; |
40 | class ELFFileBase; |
41 | class SharedFile; |
42 | class InputSectionBase; |
43 | class EhInputSection; |
44 | class Symbol; |
45 | class BitcodeCompiler; |
46 | |
47 | enum ELFKind : uint8_t { |
48 | ELFNoneKind, |
49 | ELF32LEKind, |
50 | ELF32BEKind, |
51 | ELF64LEKind, |
52 | ELF64BEKind |
53 | }; |
54 | |
55 | // For -Bno-symbolic, -Bsymbolic-non-weak-functions, -Bsymbolic-functions, |
56 | // -Bsymbolic-non-weak, -Bsymbolic. |
57 | enum class BsymbolicKind { None, NonWeakFunctions, Functions, NonWeak, All }; |
58 | |
59 | // For --build-id. |
60 | enum class BuildIdKind { None, Fast, Md5, Sha1, Hexstring, Uuid }; |
61 | |
62 | // For --call-graph-profile-sort={none,hfsort,cdsort}. |
63 | enum class CGProfileSortKind { None, Hfsort, Cdsort }; |
64 | |
65 | // For --discard-{all,locals,none}. |
66 | enum class DiscardPolicy { Default, All, Locals, None }; |
67 | |
68 | // For --icf={none,safe,all}. |
69 | enum class ICFLevel { None, Safe, All }; |
70 | |
71 | // For --strip-{all,debug}. |
72 | enum class StripPolicy { None, All, Debug }; |
73 | |
74 | // For --unresolved-symbols. |
75 | enum class UnresolvedPolicy { ReportError, Warn, Ignore }; |
76 | |
77 | // For --orphan-handling. |
78 | enum class OrphanHandlingPolicy { Place, Warn, Error }; |
79 | |
80 | // For --sort-section and linkerscript sorting rules. |
81 | enum class SortSectionPolicy { |
82 | Default, |
83 | None, |
84 | Alignment, |
85 | Name, |
86 | Priority, |
87 | Reverse, |
88 | }; |
89 | |
90 | // For --target2 |
91 | enum class Target2Policy { Abs, Rel, GotRel }; |
92 | |
93 | // For tracking ARM Float Argument PCS |
94 | enum class ARMVFPArgKind { Default, Base, VFP, ToolChain }; |
95 | |
96 | // For -z noseparate-code, -z separate-code and -z separate-loadable-segments. |
97 | enum class SeparateSegmentKind { None, Code, Loadable }; |
98 | |
99 | // For -z *stack |
100 | enum class GnuStackKind { None, Exec, NoExec }; |
101 | |
102 | // For --lto= |
103 | enum LtoKind : uint8_t {UnifiedThin, UnifiedRegular, Default}; |
104 | |
105 | // For -z gcs= |
106 | enum class GcsPolicy { Implicit, Never, Always }; |
107 | |
108 | struct SymbolVersion { |
109 | llvm::StringRef name; |
110 | bool isExternCpp; |
111 | bool hasWildcard; |
112 | }; |
113 | |
114 | // This struct contains symbols version definition that |
115 | // can be found in version script if it is used for link. |
116 | struct VersionDefinition { |
117 | llvm::StringRef name; |
118 | uint16_t id; |
119 | SmallVector<SymbolVersion, 0> nonLocalPatterns; |
120 | SmallVector<SymbolVersion, 0> localPatterns; |
121 | }; |
122 | |
123 | class LinkerDriver { |
124 | public: |
125 | void linkerMain(ArrayRef<const char *> args); |
126 | void addFile(StringRef path, bool withLOption); |
127 | void addLibrary(StringRef name); |
128 | |
129 | private: |
130 | void createFiles(llvm::opt::InputArgList &args); |
131 | void inferMachineType(); |
132 | template <class ELFT> void link(llvm::opt::InputArgList &args); |
133 | template <class ELFT> void compileBitcodeFiles(bool skipLinkedOutput); |
134 | bool tryAddFatLTOFile(MemoryBufferRef mb, StringRef archiveName, |
135 | uint64_t offsetInArchive, bool lazy); |
136 | // True if we are in --whole-archive and --no-whole-archive. |
137 | bool inWholeArchive = false; |
138 | |
139 | // True if we are in --start-lib and --end-lib. |
140 | bool inLib = false; |
141 | |
142 | std::unique_ptr<BitcodeCompiler> lto; |
143 | std::vector<InputFile *> files; |
144 | InputFile *armCmseImpLib = nullptr; |
145 | |
146 | public: |
147 | SmallVector<std::pair<StringRef, unsigned>, 0> archiveFiles; |
148 | }; |
149 | |
150 | // This struct contains the global configuration for the linker. |
151 | // Most fields are direct mapping from the command line options |
152 | // and such fields have the same name as the corresponding options. |
153 | // Most fields are initialized by the ctx.driver. |
154 | struct Config { |
155 | uint8_t osabi = 0; |
156 | uint32_t andFeatures = 0; |
157 | llvm::CachePruningPolicy thinLTOCachePolicy; |
158 | llvm::SetVector<llvm::CachedHashString> dependencyFiles; // for --dependency-file |
159 | llvm::StringMap<uint64_t> sectionStartMap; |
160 | llvm::StringRef bfdname; |
161 | llvm::StringRef chroot; |
162 | llvm::StringRef dependencyFile; |
163 | llvm::StringRef dwoDir; |
164 | llvm::StringRef dynamicLinker; |
165 | llvm::StringRef entry; |
166 | llvm::StringRef emulation; |
167 | llvm::StringRef fini; |
168 | llvm::StringRef init; |
169 | llvm::StringRef ltoAAPipeline; |
170 | llvm::StringRef ltoCSProfileFile; |
171 | llvm::StringRef ltoNewPmPasses; |
172 | llvm::StringRef ltoObjPath; |
173 | llvm::StringRef ltoSampleProfile; |
174 | llvm::StringRef mapFile; |
175 | llvm::StringRef outputFile; |
176 | llvm::StringRef ; |
177 | std::optional<uint64_t> = 0; |
178 | llvm::StringRef ; |
179 | llvm::StringRef ; |
180 | llvm::StringRef optStatsFilename; |
181 | llvm::StringRef progName; |
182 | llvm::StringRef printArchiveStats; |
183 | llvm::StringRef printSymbolOrder; |
184 | llvm::StringRef soName; |
185 | llvm::StringRef sysroot; |
186 | llvm::StringRef thinLTOCacheDir; |
187 | llvm::StringRef thinLTOIndexOnlyArg; |
188 | llvm::StringRef ; |
189 | llvm::StringRef cmseInputLib; |
190 | llvm::StringRef cmseOutputLib; |
191 | StringRef zBtiReport = "none" ; |
192 | StringRef zCetReport = "none" ; |
193 | StringRef zPauthReport = "none" ; |
194 | StringRef zGcsReport = "none" ; |
195 | bool ltoBBAddrMap; |
196 | llvm::StringRef ltoBasicBlockSections; |
197 | std::pair<llvm::StringRef, llvm::StringRef> thinLTOObjectSuffixReplace; |
198 | llvm::StringRef thinLTOPrefixReplaceOld; |
199 | llvm::StringRef thinLTOPrefixReplaceNew; |
200 | llvm::StringRef thinLTOPrefixReplaceNativeObject; |
201 | std::string rpath; |
202 | llvm::SmallVector<VersionDefinition, 0> versionDefinitions; |
203 | llvm::SmallVector<llvm::StringRef, 0> auxiliaryList; |
204 | llvm::SmallVector<llvm::StringRef, 0> filterList; |
205 | llvm::SmallVector<llvm::StringRef, 0> passPlugins; |
206 | llvm::SmallVector<llvm::StringRef, 0> searchPaths; |
207 | llvm::SmallVector<llvm::StringRef, 0> symbolOrderingFile; |
208 | llvm::SmallVector<llvm::StringRef, 0> thinLTOModulesToCompile; |
209 | llvm::SmallVector<llvm::StringRef, 0> undefined; |
210 | llvm::SmallVector<SymbolVersion, 0> dynamicList; |
211 | llvm::SmallVector<uint8_t, 0> buildIdVector; |
212 | llvm::SmallVector<llvm::StringRef, 0> mllvmOpts; |
213 | llvm::MapVector<std::pair<const InputSectionBase *, const InputSectionBase *>, |
214 | uint64_t> |
215 | callGraphProfile; |
216 | bool cmseImplib = false; |
217 | bool allowMultipleDefinition; |
218 | bool fatLTOObjects; |
219 | bool androidPackDynRelocs = false; |
220 | bool armHasArmISA = false; |
221 | bool armHasThumb2ISA = false; |
222 | bool armHasBlx = false; |
223 | bool armHasMovtMovw = false; |
224 | bool armJ1J2BranchEncoding = false; |
225 | bool armCMSESupport = false; |
226 | bool asNeeded = false; |
227 | bool armBe8 = false; |
228 | BsymbolicKind bsymbolic = BsymbolicKind::None; |
229 | CGProfileSortKind callGraphProfileSort; |
230 | bool checkSections; |
231 | bool checkDynamicRelocs; |
232 | std::optional<llvm::DebugCompressionType> compressDebugSections; |
233 | llvm::SmallVector< |
234 | std::tuple<llvm::GlobPattern, llvm::DebugCompressionType, unsigned>, 0> |
235 | compressSections; |
236 | bool cref; |
237 | llvm::SmallVector<std::pair<llvm::GlobPattern, uint64_t>, 0> |
238 | deadRelocInNonAlloc; |
239 | bool debugNames; |
240 | bool demangle = true; |
241 | bool dependentLibraries; |
242 | bool disableVerify; |
243 | bool ehFrameHdr; |
244 | bool emitLLVM; |
245 | bool emitRelocs; |
246 | bool enableNewDtags; |
247 | bool enableNonContiguousRegions; |
248 | bool executeOnly; |
249 | bool exportDynamic; |
250 | bool fixCortexA53Errata843419; |
251 | bool fixCortexA8; |
252 | bool formatBinary = false; |
253 | bool fortranCommon; |
254 | bool gcSections; |
255 | bool gdbIndex; |
256 | bool gnuHash = false; |
257 | bool gnuUnique; |
258 | bool hasDynSymTab; |
259 | bool ignoreDataAddressEquality; |
260 | bool ignoreFunctionAddressEquality; |
261 | bool ltoCSProfileGenerate; |
262 | bool ltoPGOWarnMismatch; |
263 | bool ltoDebugPassManager; |
264 | bool ltoEmitAsm; |
265 | bool ltoUniqueBasicBlockSectionNames; |
266 | bool ltoValidateAllVtablesHaveTypeInfos; |
267 | bool ltoWholeProgramVisibility; |
268 | bool mergeArmExidx; |
269 | bool mipsN32Abi = false; |
270 | bool mmapOutputFile; |
271 | bool nmagic; |
272 | bool noDynamicLinker = false; |
273 | bool noinhibitExec; |
274 | bool nostdlib; |
275 | bool oFormatBinary; |
276 | bool omagic; |
277 | bool optEB = false; |
278 | bool optEL = false; |
279 | bool optimizeBBJumps; |
280 | bool ; |
281 | bool picThunk; |
282 | bool pie; |
283 | bool printGcSections; |
284 | bool printIcfSections; |
285 | bool printMemoryUsage; |
286 | bool rejectMismatch; |
287 | bool relax; |
288 | bool relaxGP; |
289 | bool relocatable; |
290 | bool resolveGroups; |
291 | bool relrGlibc = false; |
292 | bool relrPackDynRelocs = false; |
293 | llvm::DenseSet<llvm::StringRef> saveTempsArgs; |
294 | llvm::SmallVector<std::pair<llvm::GlobPattern, uint32_t>, 0> shuffleSections; |
295 | bool singleRoRx; |
296 | bool shared; |
297 | bool symbolic; |
298 | bool isStatic = false; |
299 | bool sysvHash = false; |
300 | bool target1Rel; |
301 | bool trace; |
302 | bool thinLTOEmitImportsFiles; |
303 | bool thinLTOEmitIndexFiles; |
304 | bool thinLTOIndexOnly; |
305 | bool timeTraceEnabled; |
306 | bool tocOptimize; |
307 | bool pcRelOptimize; |
308 | bool undefinedVersion; |
309 | bool unique; |
310 | bool useAndroidRelrTags = false; |
311 | bool warnBackrefs; |
312 | llvm::SmallVector<llvm::GlobPattern, 0> warnBackrefsExclude; |
313 | bool warnCommon; |
314 | bool warnMissingEntry; |
315 | bool warnSymbolOrdering; |
316 | bool writeAddends; |
317 | bool zCombreloc; |
318 | bool zCopyreloc; |
319 | bool zForceBti; |
320 | bool zForceIbt; |
321 | bool zGlobal; |
322 | bool zHazardplt; |
323 | bool zIfuncNoplt; |
324 | bool zInitfirst; |
325 | bool zInterpose; |
326 | bool zKeepTextSectionPrefix; |
327 | bool zLrodataAfterBss; |
328 | bool zNodefaultlib; |
329 | bool zNodelete; |
330 | bool zNodlopen; |
331 | bool zNow; |
332 | bool zOrigin; |
333 | bool zPacPlt; |
334 | bool zRelro; |
335 | bool zRodynamic; |
336 | bool zShstk; |
337 | bool zStartStopGC; |
338 | uint8_t zStartStopVisibility; |
339 | bool zText; |
340 | bool zRetpolineplt; |
341 | bool zWxneeded; |
342 | DiscardPolicy discard; |
343 | GnuStackKind zGnustack; |
344 | ICFLevel icf; |
345 | OrphanHandlingPolicy orphanHandling; |
346 | SortSectionPolicy sortSection; |
347 | StripPolicy strip; |
348 | UnresolvedPolicy unresolvedSymbols; |
349 | UnresolvedPolicy unresolvedSymbolsInShlib; |
350 | Target2Policy target2; |
351 | GcsPolicy zGcs; |
352 | bool power10Stubs; |
353 | ARMVFPArgKind armVFPArgs = ARMVFPArgKind::Default; |
354 | BuildIdKind buildId = BuildIdKind::None; |
355 | SeparateSegmentKind zSeparate; |
356 | ELFKind ekind = ELFNoneKind; |
357 | uint16_t emachine = llvm::ELF::EM_NONE; |
358 | std::optional<uint64_t> imageBase; |
359 | uint64_t commonPageSize; |
360 | uint64_t maxPageSize; |
361 | uint64_t mipsGotSize; |
362 | uint64_t zStackSize; |
363 | unsigned ltoPartitions; |
364 | unsigned ltoo; |
365 | llvm::CodeGenOptLevel ltoCgo; |
366 | unsigned optimize; |
367 | StringRef thinLTOJobs; |
368 | unsigned timeTraceGranularity; |
369 | int32_t splitStackAdjustSize; |
370 | StringRef packageMetadata; |
371 | |
372 | // The following config options do not directly correspond to any |
373 | // particular command line options. |
374 | |
375 | // True if we need to pass through relocations in input files to the |
376 | // output file. Usually false because we consume relocations. |
377 | bool copyRelocs; |
378 | |
379 | // True if the target is ELF64. False if ELF32. |
380 | bool is64; |
381 | |
382 | // True if the target is little-endian. False if big-endian. |
383 | bool isLE; |
384 | |
385 | // endianness::little if isLE is true. endianness::big otherwise. |
386 | llvm::endianness endianness; |
387 | |
388 | // True if the target is the little-endian MIPS64. |
389 | // |
390 | // The reason why we have this variable only for the MIPS is because |
391 | // we use this often. Some ELF headers for MIPS64EL are in a |
392 | // mixed-endian (which is horrible and I'd say that's a serious spec |
393 | // bug), and we need to know whether we are reading MIPS ELF files or |
394 | // not in various places. |
395 | // |
396 | // (Note that MIPS64EL is not a typo for MIPS64LE. This is the official |
397 | // name whatever that means. A fun hypothesis is that "EL" is short for |
398 | // little-endian written in the little-endian order, but I don't know |
399 | // if that's true.) |
400 | bool isMips64EL; |
401 | |
402 | // True if we need to set the DF_STATIC_TLS flag to an output file, which |
403 | // works as a hint to the dynamic loader that the shared object contains code |
404 | // compiled with the initial-exec TLS model. |
405 | bool hasTlsIe = false; |
406 | |
407 | // Holds set of ELF header flags for the target. |
408 | uint32_t eflags = 0; |
409 | |
410 | // The ELF spec defines two types of relocation table entries, RELA and |
411 | // REL. RELA is a triplet of (offset, info, addend) while REL is a |
412 | // tuple of (offset, info). Addends for REL are implicit and read from |
413 | // the location where the relocations are applied. So, REL is more |
414 | // compact than RELA but requires a bit of more work to process. |
415 | // |
416 | // (From the linker writer's view, this distinction is not necessary. |
417 | // If the ELF had chosen whichever and sticked with it, it would have |
418 | // been easier to write code to process relocations, but it's too late |
419 | // to change the spec.) |
420 | // |
421 | // Each ABI defines its relocation type. IsRela is true if target |
422 | // uses RELA. As far as we know, all 64-bit ABIs are using RELA. A |
423 | // few 32-bit ABIs are using RELA too. |
424 | bool isRela; |
425 | |
426 | // True if we are creating position-independent code. |
427 | bool isPic; |
428 | |
429 | // 4 for ELF32, 8 for ELF64. |
430 | int wordsize; |
431 | |
432 | // Mode of MTE to write to the ELF note. Should be one of NT_MEMTAG_ASYNC (for |
433 | // async), NT_MEMTAG_SYNC (for sync), or NT_MEMTAG_LEVEL_NONE (for none). If |
434 | // async or sync is enabled, write the ELF note specifying the default MTE |
435 | // mode. |
436 | int androidMemtagMode; |
437 | // Signal to the dynamic loader to enable heap MTE. |
438 | bool androidMemtagHeap; |
439 | // Signal to the dynamic loader that this binary expects stack MTE. Generally, |
440 | // this means to map the primary and thread stacks as PROT_MTE. Note: This is |
441 | // not supported on Android 11 & 12. |
442 | bool androidMemtagStack; |
443 | |
444 | // When using a unified pre-link LTO pipeline, specify the backend LTO mode. |
445 | LtoKind ltoKind = LtoKind::Default; |
446 | |
447 | unsigned threadCount; |
448 | |
449 | // If an input file equals a key, remap it to the value. |
450 | llvm::DenseMap<llvm::StringRef, llvm::StringRef> remapInputs; |
451 | // If an input file matches a wildcard pattern, remap it to the value. |
452 | llvm::SmallVector<std::pair<llvm::GlobPattern, llvm::StringRef>, 0> |
453 | remapInputsWildcards; |
454 | }; |
455 | struct ConfigWrapper { |
456 | Config c; |
457 | Config *operator->() { return &c; } |
458 | }; |
459 | |
460 | LLVM_LIBRARY_VISIBILITY extern ConfigWrapper config; |
461 | |
462 | struct DuplicateSymbol { |
463 | const Symbol *sym; |
464 | const InputFile *file; |
465 | InputSectionBase *section; |
466 | uint64_t value; |
467 | }; |
468 | |
469 | struct Ctx { |
470 | LinkerDriver driver; |
471 | SmallVector<std::unique_ptr<MemoryBuffer>> memoryBuffers; |
472 | SmallVector<ELFFileBase *, 0> objectFiles; |
473 | SmallVector<SharedFile *, 0> sharedFiles; |
474 | SmallVector<BinaryFile *, 0> binaryFiles; |
475 | SmallVector<BitcodeFile *, 0> bitcodeFiles; |
476 | SmallVector<BitcodeFile *, 0> lazyBitcodeFiles; |
477 | SmallVector<InputSectionBase *, 0> inputSections; |
478 | SmallVector<EhInputSection *, 0> ehInputSections; |
479 | // Duplicate symbol candidates. |
480 | SmallVector<DuplicateSymbol, 0> duplicates; |
481 | // Symbols in a non-prevailing COMDAT group which should be changed to an |
482 | // Undefined. |
483 | SmallVector<std::pair<Symbol *, unsigned>, 0> nonPrevailingSyms; |
484 | // A tuple of (reference, extractedFile, sym). Used by --why-extract=. |
485 | SmallVector<std::tuple<std::string, const InputFile *, const Symbol &>, 0> |
486 | ; |
487 | // A mapping from a symbol to an InputFile referencing it backward. Used by |
488 | // --warn-backrefs. |
489 | llvm::DenseMap<const Symbol *, |
490 | std::pair<const InputFile *, const InputFile *>> |
491 | backwardReferences; |
492 | llvm::SmallSet<llvm::StringRef, 0> auxiliaryFiles; |
493 | // InputFile for linker created symbols with no source location. |
494 | InputFile *internalFile; |
495 | // True if SHT_LLVM_SYMPART is used. |
496 | std::atomic<bool> hasSympart{false}; |
497 | // True if there are TLS IE relocations. Set DF_STATIC_TLS if -shared. |
498 | std::atomic<bool> hasTlsIe{false}; |
499 | // True if we need to reserve two .got entries for local-dynamic TLS model. |
500 | std::atomic<bool> needsTlsLd{false}; |
501 | // True if all native vtable symbols have corresponding type info symbols |
502 | // during LTO. |
503 | bool ltoAllVtablesHaveTypeInfos; |
504 | |
505 | // Each symbol assignment and DEFINED(sym) reference is assigned an increasing |
506 | // order. Each DEFINED(sym) evaluation checks whether the reference happens |
507 | // before a possible `sym = expr;`. |
508 | unsigned scriptSymOrderCounter = 1; |
509 | llvm::DenseMap<const Symbol *, unsigned> scriptSymOrder; |
510 | |
511 | void reset(); |
512 | |
513 | llvm::raw_fd_ostream openAuxiliaryFile(llvm::StringRef, std::error_code &); |
514 | |
515 | ArrayRef<uint8_t> aarch64PauthAbiCoreInfo; |
516 | }; |
517 | |
518 | LLVM_LIBRARY_VISIBILITY extern Ctx ctx; |
519 | |
520 | // The first two elements of versionDefinitions represent VER_NDX_LOCAL and |
521 | // VER_NDX_GLOBAL. This helper returns other elements. |
522 | static inline ArrayRef<VersionDefinition> namedVersionDefs() { |
523 | return llvm::ArrayRef(config->versionDefinitions).slice(N: 2); |
524 | } |
525 | |
526 | void errorOrWarn(const Twine &msg); |
527 | |
528 | static inline void internalLinkerError(StringRef loc, const Twine &msg) { |
529 | errorOrWarn(msg: loc + "internal linker error: " + msg + "\n" + |
530 | llvm::getBugReportMsg()); |
531 | } |
532 | |
533 | } // namespace lld::elf |
534 | |
535 | #endif |
536 | |