10b57cec5SDimitry Andric //===- Config.h -------------------------------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric #ifndef LLD_ELF_CONFIG_H
100b57cec5SDimitry Andric #define LLD_ELF_CONFIG_H
110b57cec5SDimitry Andric
120b57cec5SDimitry Andric #include "lld/Common/ErrorHandler.h"
13e8d8bef9SDimitry Andric #include "llvm/ADT/CachedHashString.h"
14753f127fSDimitry Andric #include "llvm/ADT/DenseSet.h"
150b57cec5SDimitry Andric #include "llvm/ADT/MapVector.h"
16e8d8bef9SDimitry Andric #include "llvm/ADT/SetVector.h"
1706c3fb27SDimitry Andric #include "llvm/ADT/SmallSet.h"
180b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
190b57cec5SDimitry Andric #include "llvm/ADT/StringSet.h"
200b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h"
21bdd1243dSDimitry Andric #include "llvm/Option/ArgList.h"
220b57cec5SDimitry Andric #include "llvm/Support/CachePruning.h"
230b57cec5SDimitry Andric #include "llvm/Support/CodeGen.h"
24bdd1243dSDimitry Andric #include "llvm/Support/Compiler.h"
25bdd1243dSDimitry Andric #include "llvm/Support/Compression.h"
260b57cec5SDimitry Andric #include "llvm/Support/Endian.h"
2706c3fb27SDimitry Andric #include "llvm/Support/FileSystem.h"
285ffd83dbSDimitry Andric #include "llvm/Support/GlobPattern.h"
29fe6060f1SDimitry Andric #include "llvm/Support/PrettyStackTrace.h"
300b57cec5SDimitry Andric #include <atomic>
310eae32dcSDimitry Andric #include <memory>
32bdd1243dSDimitry Andric #include <optional>
330b57cec5SDimitry Andric #include <vector>
340b57cec5SDimitry Andric
35bdd1243dSDimitry Andric namespace lld::elf {
360b57cec5SDimitry Andric
370b57cec5SDimitry Andric class InputFile;
3881ad6265SDimitry Andric class BinaryFile;
3981ad6265SDimitry Andric class BitcodeFile;
4081ad6265SDimitry Andric class ELFFileBase;
4181ad6265SDimitry Andric class SharedFile;
420b57cec5SDimitry Andric class InputSectionBase;
43bdd1243dSDimitry Andric class EhInputSection;
4481ad6265SDimitry Andric class Symbol;
45bdd1243dSDimitry Andric class BitcodeCompiler;
460b57cec5SDimitry Andric
470eae32dcSDimitry Andric enum ELFKind : uint8_t {
480b57cec5SDimitry Andric ELFNoneKind,
490b57cec5SDimitry Andric ELF32LEKind,
500b57cec5SDimitry Andric ELF32BEKind,
510b57cec5SDimitry Andric ELF64LEKind,
520b57cec5SDimitry Andric ELF64BEKind
530b57cec5SDimitry Andric };
540b57cec5SDimitry Andric
556e75b2fbSDimitry Andric // For -Bno-symbolic, -Bsymbolic-non-weak-functions, -Bsymbolic-functions,
565f757f3fSDimitry Andric // -Bsymbolic-non-weak, -Bsymbolic.
575f757f3fSDimitry Andric enum class BsymbolicKind { None, NonWeakFunctions, Functions, NonWeak, All };
586e75b2fbSDimitry Andric
590b57cec5SDimitry Andric // For --build-id.
600b57cec5SDimitry Andric enum class BuildIdKind { None, Fast, Md5, Sha1, Hexstring, Uuid };
610b57cec5SDimitry Andric
625f757f3fSDimitry Andric // For --call-graph-profile-sort={none,hfsort,cdsort}.
635f757f3fSDimitry Andric enum class CGProfileSortKind { None, Hfsort, Cdsort };
645f757f3fSDimitry Andric
650b57cec5SDimitry Andric // For --discard-{all,locals,none}.
660b57cec5SDimitry Andric enum class DiscardPolicy { Default, All, Locals, None };
670b57cec5SDimitry Andric
680b57cec5SDimitry Andric // For --icf={none,safe,all}.
690b57cec5SDimitry Andric enum class ICFLevel { None, Safe, All };
700b57cec5SDimitry Andric
710b57cec5SDimitry Andric // For --strip-{all,debug}.
720b57cec5SDimitry Andric enum class StripPolicy { None, All, Debug };
730b57cec5SDimitry Andric
740b57cec5SDimitry Andric // For --unresolved-symbols.
750b57cec5SDimitry Andric enum class UnresolvedPolicy { ReportError, Warn, Ignore };
760b57cec5SDimitry Andric
770b57cec5SDimitry Andric // For --orphan-handling.
780b57cec5SDimitry Andric enum class OrphanHandlingPolicy { Place, Warn, Error };
790b57cec5SDimitry Andric
800b57cec5SDimitry Andric // For --sort-section and linkerscript sorting rules.
8106c3fb27SDimitry Andric enum class SortSectionPolicy {
8206c3fb27SDimitry Andric Default,
8306c3fb27SDimitry Andric None,
8406c3fb27SDimitry Andric Alignment,
8506c3fb27SDimitry Andric Name,
8606c3fb27SDimitry Andric Priority,
8706c3fb27SDimitry Andric Reverse,
8806c3fb27SDimitry Andric };
890b57cec5SDimitry Andric
900b57cec5SDimitry Andric // For --target2
910b57cec5SDimitry Andric enum class Target2Policy { Abs, Rel, GotRel };
920b57cec5SDimitry Andric
930b57cec5SDimitry Andric // For tracking ARM Float Argument PCS
940b57cec5SDimitry Andric enum class ARMVFPArgKind { Default, Base, VFP, ToolChain };
950b57cec5SDimitry Andric
9685868e8aSDimitry Andric // For -z noseparate-code, -z separate-code and -z separate-loadable-segments.
9785868e8aSDimitry Andric enum class SeparateSegmentKind { None, Code, Loadable };
9885868e8aSDimitry Andric
99480093f4SDimitry Andric // For -z *stack
100480093f4SDimitry Andric enum class GnuStackKind { None, Exec, NoExec };
101480093f4SDimitry Andric
10206c3fb27SDimitry Andric // For --lto=
10306c3fb27SDimitry Andric enum LtoKind : uint8_t {UnifiedThin, UnifiedRegular, Default};
10406c3fb27SDimitry Andric
1050fca6ea1SDimitry Andric // For -z gcs=
1060fca6ea1SDimitry Andric enum class GcsPolicy { Implicit, Never, Always };
1070fca6ea1SDimitry Andric
1080b57cec5SDimitry Andric struct SymbolVersion {
1090b57cec5SDimitry Andric llvm::StringRef name;
1100b57cec5SDimitry Andric bool isExternCpp;
1110b57cec5SDimitry Andric bool hasWildcard;
1120b57cec5SDimitry Andric };
1130b57cec5SDimitry Andric
1140b57cec5SDimitry Andric // This struct contains symbols version definition that
1150b57cec5SDimitry Andric // can be found in version script if it is used for link.
1160b57cec5SDimitry Andric struct VersionDefinition {
1170b57cec5SDimitry Andric llvm::StringRef name;
11885868e8aSDimitry Andric uint16_t id;
11904eeddc0SDimitry Andric SmallVector<SymbolVersion, 0> nonLocalPatterns;
12004eeddc0SDimitry Andric SmallVector<SymbolVersion, 0> localPatterns;
1210b57cec5SDimitry Andric };
1220b57cec5SDimitry Andric
123bdd1243dSDimitry Andric class LinkerDriver {
124bdd1243dSDimitry Andric public:
125bdd1243dSDimitry Andric void linkerMain(ArrayRef<const char *> args);
126bdd1243dSDimitry Andric void addFile(StringRef path, bool withLOption);
127bdd1243dSDimitry Andric void addLibrary(StringRef name);
128bdd1243dSDimitry Andric
129bdd1243dSDimitry Andric private:
130bdd1243dSDimitry Andric void createFiles(llvm::opt::InputArgList &args);
131bdd1243dSDimitry Andric void inferMachineType();
1320fca6ea1SDimitry Andric template <class ELFT> void link(llvm::opt::InputArgList &args);
133bdd1243dSDimitry Andric template <class ELFT> void compileBitcodeFiles(bool skipLinkedOutput);
1345f757f3fSDimitry Andric bool tryAddFatLTOFile(MemoryBufferRef mb, StringRef archiveName,
1355f757f3fSDimitry Andric uint64_t offsetInArchive, bool lazy);
136bdd1243dSDimitry Andric // True if we are in --whole-archive and --no-whole-archive.
137bdd1243dSDimitry Andric bool inWholeArchive = false;
138bdd1243dSDimitry Andric
139bdd1243dSDimitry Andric // True if we are in --start-lib and --end-lib.
140bdd1243dSDimitry Andric bool inLib = false;
141bdd1243dSDimitry Andric
142bdd1243dSDimitry Andric std::unique_ptr<BitcodeCompiler> lto;
143bdd1243dSDimitry Andric std::vector<InputFile *> files;
1440fca6ea1SDimitry Andric InputFile *armCmseImpLib = nullptr;
145bdd1243dSDimitry Andric
146bdd1243dSDimitry Andric public:
147bdd1243dSDimitry Andric SmallVector<std::pair<StringRef, unsigned>, 0> archiveFiles;
148bdd1243dSDimitry Andric };
149bdd1243dSDimitry Andric
1500b57cec5SDimitry Andric // This struct contains the global configuration for the linker.
1510b57cec5SDimitry Andric // Most fields are direct mapping from the command line options
1520b57cec5SDimitry Andric // and such fields have the same name as the corresponding options.
153bdd1243dSDimitry Andric // Most fields are initialized by the ctx.driver.
154bdd1243dSDimitry Andric struct Config {
1550b57cec5SDimitry Andric uint8_t osabi = 0;
1560b57cec5SDimitry Andric uint32_t andFeatures = 0;
1570b57cec5SDimitry Andric llvm::CachePruningPolicy thinLTOCachePolicy;
158e8d8bef9SDimitry Andric llvm::SetVector<llvm::CachedHashString> dependencyFiles; // for --dependency-file
1590b57cec5SDimitry Andric llvm::StringMap<uint64_t> sectionStartMap;
1605ffd83dbSDimitry Andric llvm::StringRef bfdname;
1610b57cec5SDimitry Andric llvm::StringRef chroot;
162e8d8bef9SDimitry Andric llvm::StringRef dependencyFile;
1630b57cec5SDimitry Andric llvm::StringRef dwoDir;
164e8d8bef9SDimitry Andric llvm::StringRef dynamicLinker;
1650b57cec5SDimitry Andric llvm::StringRef entry;
1660b57cec5SDimitry Andric llvm::StringRef emulation;
1670b57cec5SDimitry Andric llvm::StringRef fini;
1680b57cec5SDimitry Andric llvm::StringRef init;
1690b57cec5SDimitry Andric llvm::StringRef ltoAAPipeline;
1700b57cec5SDimitry Andric llvm::StringRef ltoCSProfileFile;
1710b57cec5SDimitry Andric llvm::StringRef ltoNewPmPasses;
1720b57cec5SDimitry Andric llvm::StringRef ltoObjPath;
1730b57cec5SDimitry Andric llvm::StringRef ltoSampleProfile;
1740b57cec5SDimitry Andric llvm::StringRef mapFile;
1750b57cec5SDimitry Andric llvm::StringRef outputFile;
1760b57cec5SDimitry Andric llvm::StringRef optRemarksFilename;
177bdd1243dSDimitry Andric std::optional<uint64_t> optRemarksHotnessThreshold = 0;
1780b57cec5SDimitry Andric llvm::StringRef optRemarksPasses;
1790b57cec5SDimitry Andric llvm::StringRef optRemarksFormat;
18081ad6265SDimitry Andric llvm::StringRef optStatsFilename;
1810b57cec5SDimitry Andric llvm::StringRef progName;
1825ffd83dbSDimitry Andric llvm::StringRef printArchiveStats;
1830b57cec5SDimitry Andric llvm::StringRef printSymbolOrder;
1840b57cec5SDimitry Andric llvm::StringRef soName;
1850b57cec5SDimitry Andric llvm::StringRef sysroot;
1860b57cec5SDimitry Andric llvm::StringRef thinLTOCacheDir;
1870b57cec5SDimitry Andric llvm::StringRef thinLTOIndexOnlyArg;
188349cc55cSDimitry Andric llvm::StringRef whyExtract;
18906c3fb27SDimitry Andric llvm::StringRef cmseInputLib;
19006c3fb27SDimitry Andric llvm::StringRef cmseOutputLib;
1910eae32dcSDimitry Andric StringRef zBtiReport = "none";
1920eae32dcSDimitry Andric StringRef zCetReport = "none";
1930fca6ea1SDimitry Andric StringRef zPauthReport = "none";
1940fca6ea1SDimitry Andric StringRef zGcsReport = "none";
1950fca6ea1SDimitry Andric bool ltoBBAddrMap;
1965ffd83dbSDimitry Andric llvm::StringRef ltoBasicBlockSections;
1970b57cec5SDimitry Andric std::pair<llvm::StringRef, llvm::StringRef> thinLTOObjectSuffixReplace;
19806c3fb27SDimitry Andric llvm::StringRef thinLTOPrefixReplaceOld;
19906c3fb27SDimitry Andric llvm::StringRef thinLTOPrefixReplaceNew;
20006c3fb27SDimitry Andric llvm::StringRef thinLTOPrefixReplaceNativeObject;
2010b57cec5SDimitry Andric std::string rpath;
202bdd1243dSDimitry Andric llvm::SmallVector<VersionDefinition, 0> versionDefinitions;
203bdd1243dSDimitry Andric llvm::SmallVector<llvm::StringRef, 0> auxiliaryList;
204bdd1243dSDimitry Andric llvm::SmallVector<llvm::StringRef, 0> filterList;
205bdd1243dSDimitry Andric llvm::SmallVector<llvm::StringRef, 0> passPlugins;
206bdd1243dSDimitry Andric llvm::SmallVector<llvm::StringRef, 0> searchPaths;
207bdd1243dSDimitry Andric llvm::SmallVector<llvm::StringRef, 0> symbolOrderingFile;
208bdd1243dSDimitry Andric llvm::SmallVector<llvm::StringRef, 0> thinLTOModulesToCompile;
209bdd1243dSDimitry Andric llvm::SmallVector<llvm::StringRef, 0> undefined;
210bdd1243dSDimitry Andric llvm::SmallVector<SymbolVersion, 0> dynamicList;
211bdd1243dSDimitry Andric llvm::SmallVector<uint8_t, 0> buildIdVector;
212bdd1243dSDimitry Andric llvm::SmallVector<llvm::StringRef, 0> mllvmOpts;
2130b57cec5SDimitry Andric llvm::MapVector<std::pair<const InputSectionBase *, const InputSectionBase *>,
2140b57cec5SDimitry Andric uint64_t>
2150b57cec5SDimitry Andric callGraphProfile;
21606c3fb27SDimitry Andric bool cmseImplib = false;
2170b57cec5SDimitry Andric bool allowMultipleDefinition;
2185f757f3fSDimitry Andric bool fatLTOObjects;
21981ad6265SDimitry Andric bool androidPackDynRelocs = false;
220*62987288SDimitry Andric bool armHasArmISA = false;
221*62987288SDimitry Andric bool armHasThumb2ISA = false;
2220b57cec5SDimitry Andric bool armHasBlx = false;
2230b57cec5SDimitry Andric bool armHasMovtMovw = false;
2240b57cec5SDimitry Andric bool armJ1J2BranchEncoding = false;
22506c3fb27SDimitry Andric bool armCMSESupport = false;
2260b57cec5SDimitry Andric bool asNeeded = false;
22706c3fb27SDimitry Andric bool armBe8 = false;
2286e75b2fbSDimitry Andric BsymbolicKind bsymbolic = BsymbolicKind::None;
2295f757f3fSDimitry Andric CGProfileSortKind callGraphProfileSort;
2300b57cec5SDimitry Andric bool checkSections;
231fe6060f1SDimitry Andric bool checkDynamicRelocs;
2320fca6ea1SDimitry Andric std::optional<llvm::DebugCompressionType> compressDebugSections;
2330fca6ea1SDimitry Andric llvm::SmallVector<
2340fca6ea1SDimitry Andric std::tuple<llvm::GlobPattern, llvm::DebugCompressionType, unsigned>, 0>
2350fca6ea1SDimitry Andric compressSections;
2360b57cec5SDimitry Andric bool cref;
237bdd1243dSDimitry Andric llvm::SmallVector<std::pair<llvm::GlobPattern, uint64_t>, 0>
238bdd1243dSDimitry Andric deadRelocInNonAlloc;
2390fca6ea1SDimitry Andric bool debugNames;
2400b57cec5SDimitry Andric bool demangle = true;
2410b57cec5SDimitry Andric bool dependentLibraries;
2420b57cec5SDimitry Andric bool disableVerify;
2430b57cec5SDimitry Andric bool ehFrameHdr;
2440b57cec5SDimitry Andric bool emitLLVM;
2450b57cec5SDimitry Andric bool emitRelocs;
2460b57cec5SDimitry Andric bool enableNewDtags;
2470fca6ea1SDimitry Andric bool enableNonContiguousRegions;
2480b57cec5SDimitry Andric bool executeOnly;
2490b57cec5SDimitry Andric bool exportDynamic;
2500b57cec5SDimitry Andric bool fixCortexA53Errata843419;
25185868e8aSDimitry Andric bool fixCortexA8;
2520b57cec5SDimitry Andric bool formatBinary = false;
253e8d8bef9SDimitry Andric bool fortranCommon;
2540b57cec5SDimitry Andric bool gcSections;
2550b57cec5SDimitry Andric bool gdbIndex;
2560b57cec5SDimitry Andric bool gnuHash = false;
2570b57cec5SDimitry Andric bool gnuUnique;
2580b57cec5SDimitry Andric bool hasDynSymTab;
2590b57cec5SDimitry Andric bool ignoreDataAddressEquality;
2600b57cec5SDimitry Andric bool ignoreFunctionAddressEquality;
2610b57cec5SDimitry Andric bool ltoCSProfileGenerate;
262349cc55cSDimitry Andric bool ltoPGOWarnMismatch;
2630b57cec5SDimitry Andric bool ltoDebugPassManager;
2645ffd83dbSDimitry Andric bool ltoEmitAsm;
2655ffd83dbSDimitry Andric bool ltoUniqueBasicBlockSectionNames;
2665f757f3fSDimitry Andric bool ltoValidateAllVtablesHaveTypeInfos;
2675ffd83dbSDimitry Andric bool ltoWholeProgramVisibility;
2680b57cec5SDimitry Andric bool mergeArmExidx;
2690b57cec5SDimitry Andric bool mipsN32Abi = false;
270480093f4SDimitry Andric bool mmapOutputFile;
2710b57cec5SDimitry Andric bool nmagic;
27255e4f9d5SDimitry Andric bool noDynamicLinker = false;
2730b57cec5SDimitry Andric bool noinhibitExec;
2740b57cec5SDimitry Andric bool nostdlib;
2750b57cec5SDimitry Andric bool oFormatBinary;
2760b57cec5SDimitry Andric bool omagic;
277fe6060f1SDimitry Andric bool optEB = false;
278fe6060f1SDimitry Andric bool optEL = false;
2795ffd83dbSDimitry Andric bool optimizeBBJumps;
2800b57cec5SDimitry Andric bool optRemarksWithHotness;
2810b57cec5SDimitry Andric bool picThunk;
2820b57cec5SDimitry Andric bool pie;
2830b57cec5SDimitry Andric bool printGcSections;
2840b57cec5SDimitry Andric bool printIcfSections;
28506c3fb27SDimitry Andric bool printMemoryUsage;
2860fca6ea1SDimitry Andric bool rejectMismatch;
287349cc55cSDimitry Andric bool relax;
28806c3fb27SDimitry Andric bool relaxGP;
2890b57cec5SDimitry Andric bool relocatable;
2900fca6ea1SDimitry Andric bool resolveGroups;
29181ad6265SDimitry Andric bool relrGlibc = false;
29281ad6265SDimitry Andric bool relrPackDynRelocs = false;
293753f127fSDimitry Andric llvm::DenseSet<llvm::StringRef> saveTempsArgs;
294bdd1243dSDimitry Andric llvm::SmallVector<std::pair<llvm::GlobPattern, uint32_t>, 0> shuffleSections;
2950b57cec5SDimitry Andric bool singleRoRx;
2960b57cec5SDimitry Andric bool shared;
2975ffd83dbSDimitry Andric bool symbolic;
2980b57cec5SDimitry Andric bool isStatic = false;
2990b57cec5SDimitry Andric bool sysvHash = false;
3000b57cec5SDimitry Andric bool target1Rel;
3010b57cec5SDimitry Andric bool trace;
3020b57cec5SDimitry Andric bool thinLTOEmitImportsFiles;
30381ad6265SDimitry Andric bool thinLTOEmitIndexFiles;
3040b57cec5SDimitry Andric bool thinLTOIndexOnly;
3055ffd83dbSDimitry Andric bool timeTraceEnabled;
3060b57cec5SDimitry Andric bool tocOptimize;
307e8d8bef9SDimitry Andric bool pcRelOptimize;
3080b57cec5SDimitry Andric bool undefinedVersion;
3095ffd83dbSDimitry Andric bool unique;
3100b57cec5SDimitry Andric bool useAndroidRelrTags = false;
3110b57cec5SDimitry Andric bool warnBackrefs;
312bdd1243dSDimitry Andric llvm::SmallVector<llvm::GlobPattern, 0> warnBackrefsExclude;
3130b57cec5SDimitry Andric bool warnCommon;
3140b57cec5SDimitry Andric bool warnMissingEntry;
3150b57cec5SDimitry Andric bool warnSymbolOrdering;
3160b57cec5SDimitry Andric bool writeAddends;
3170b57cec5SDimitry Andric bool zCombreloc;
3180b57cec5SDimitry Andric bool zCopyreloc;
3195ffd83dbSDimitry Andric bool zForceBti;
320480093f4SDimitry Andric bool zForceIbt;
3210b57cec5SDimitry Andric bool zGlobal;
3220b57cec5SDimitry Andric bool zHazardplt;
3230b57cec5SDimitry Andric bool zIfuncNoplt;
3240b57cec5SDimitry Andric bool zInitfirst;
3250b57cec5SDimitry Andric bool zInterpose;
3260b57cec5SDimitry Andric bool zKeepTextSectionPrefix;
3270fca6ea1SDimitry Andric bool zLrodataAfterBss;
3280b57cec5SDimitry Andric bool zNodefaultlib;
3290b57cec5SDimitry Andric bool zNodelete;
3300b57cec5SDimitry Andric bool zNodlopen;
3310b57cec5SDimitry Andric bool zNow;
3320b57cec5SDimitry Andric bool zOrigin;
3335ffd83dbSDimitry Andric bool zPacPlt;
3340b57cec5SDimitry Andric bool zRelro;
3350b57cec5SDimitry Andric bool zRodynamic;
336480093f4SDimitry Andric bool zShstk;
337fe6060f1SDimitry Andric bool zStartStopGC;
3385ffd83dbSDimitry Andric uint8_t zStartStopVisibility;
3390b57cec5SDimitry Andric bool zText;
3400b57cec5SDimitry Andric bool zRetpolineplt;
3410b57cec5SDimitry Andric bool zWxneeded;
3420b57cec5SDimitry Andric DiscardPolicy discard;
343480093f4SDimitry Andric GnuStackKind zGnustack;
3440b57cec5SDimitry Andric ICFLevel icf;
3450b57cec5SDimitry Andric OrphanHandlingPolicy orphanHandling;
3460b57cec5SDimitry Andric SortSectionPolicy sortSection;
3470b57cec5SDimitry Andric StripPolicy strip;
3480b57cec5SDimitry Andric UnresolvedPolicy unresolvedSymbols;
349e8d8bef9SDimitry Andric UnresolvedPolicy unresolvedSymbolsInShlib;
3500b57cec5SDimitry Andric Target2Policy target2;
3510fca6ea1SDimitry Andric GcsPolicy zGcs;
3524824e7fdSDimitry Andric bool power10Stubs;
3530b57cec5SDimitry Andric ARMVFPArgKind armVFPArgs = ARMVFPArgKind::Default;
3540b57cec5SDimitry Andric BuildIdKind buildId = BuildIdKind::None;
35585868e8aSDimitry Andric SeparateSegmentKind zSeparate;
3560b57cec5SDimitry Andric ELFKind ekind = ELFNoneKind;
3570b57cec5SDimitry Andric uint16_t emachine = llvm::ELF::EM_NONE;
358bdd1243dSDimitry Andric std::optional<uint64_t> imageBase;
3590b57cec5SDimitry Andric uint64_t commonPageSize;
3600b57cec5SDimitry Andric uint64_t maxPageSize;
3610b57cec5SDimitry Andric uint64_t mipsGotSize;
3620b57cec5SDimitry Andric uint64_t zStackSize;
3630b57cec5SDimitry Andric unsigned ltoPartitions;
3640b57cec5SDimitry Andric unsigned ltoo;
3655f757f3fSDimitry Andric llvm::CodeGenOptLevel ltoCgo;
3660b57cec5SDimitry Andric unsigned optimize;
3675ffd83dbSDimitry Andric StringRef thinLTOJobs;
3685ffd83dbSDimitry Andric unsigned timeTraceGranularity;
3690b57cec5SDimitry Andric int32_t splitStackAdjustSize;
37061cfbce3SDimitry Andric StringRef packageMetadata;
3710b57cec5SDimitry Andric
3720b57cec5SDimitry Andric // The following config options do not directly correspond to any
373480093f4SDimitry Andric // particular command line options.
3740b57cec5SDimitry Andric
3750b57cec5SDimitry Andric // True if we need to pass through relocations in input files to the
3760b57cec5SDimitry Andric // output file. Usually false because we consume relocations.
3770b57cec5SDimitry Andric bool copyRelocs;
3780b57cec5SDimitry Andric
3790b57cec5SDimitry Andric // True if the target is ELF64. False if ELF32.
3800b57cec5SDimitry Andric bool is64;
3810b57cec5SDimitry Andric
3820b57cec5SDimitry Andric // True if the target is little-endian. False if big-endian.
3830b57cec5SDimitry Andric bool isLE;
3840b57cec5SDimitry Andric
3850b57cec5SDimitry Andric // endianness::little if isLE is true. endianness::big otherwise.
3865f757f3fSDimitry Andric llvm::endianness endianness;
3870b57cec5SDimitry Andric
3880b57cec5SDimitry Andric // True if the target is the little-endian MIPS64.
3890b57cec5SDimitry Andric //
3900b57cec5SDimitry Andric // The reason why we have this variable only for the MIPS is because
3910b57cec5SDimitry Andric // we use this often. Some ELF headers for MIPS64EL are in a
3920b57cec5SDimitry Andric // mixed-endian (which is horrible and I'd say that's a serious spec
3930b57cec5SDimitry Andric // bug), and we need to know whether we are reading MIPS ELF files or
3940b57cec5SDimitry Andric // not in various places.
3950b57cec5SDimitry Andric //
3960b57cec5SDimitry Andric // (Note that MIPS64EL is not a typo for MIPS64LE. This is the official
3970b57cec5SDimitry Andric // name whatever that means. A fun hypothesis is that "EL" is short for
3980b57cec5SDimitry Andric // little-endian written in the little-endian order, but I don't know
3990b57cec5SDimitry Andric // if that's true.)
4000b57cec5SDimitry Andric bool isMips64EL;
4010b57cec5SDimitry Andric
4024824e7fdSDimitry Andric // True if we need to set the DF_STATIC_TLS flag to an output file, which
4034824e7fdSDimitry Andric // works as a hint to the dynamic loader that the shared object contains code
4044824e7fdSDimitry Andric // compiled with the initial-exec TLS model.
4054824e7fdSDimitry Andric bool hasTlsIe = false;
4060b57cec5SDimitry Andric
4070b57cec5SDimitry Andric // Holds set of ELF header flags for the target.
4080b57cec5SDimitry Andric uint32_t eflags = 0;
4090b57cec5SDimitry Andric
4100b57cec5SDimitry Andric // The ELF spec defines two types of relocation table entries, RELA and
4110b57cec5SDimitry Andric // REL. RELA is a triplet of (offset, info, addend) while REL is a
4120b57cec5SDimitry Andric // tuple of (offset, info). Addends for REL are implicit and read from
4130b57cec5SDimitry Andric // the location where the relocations are applied. So, REL is more
4140b57cec5SDimitry Andric // compact than RELA but requires a bit of more work to process.
4150b57cec5SDimitry Andric //
4160b57cec5SDimitry Andric // (From the linker writer's view, this distinction is not necessary.
4170b57cec5SDimitry Andric // If the ELF had chosen whichever and sticked with it, it would have
4180b57cec5SDimitry Andric // been easier to write code to process relocations, but it's too late
4190b57cec5SDimitry Andric // to change the spec.)
4200b57cec5SDimitry Andric //
4210b57cec5SDimitry Andric // Each ABI defines its relocation type. IsRela is true if target
4220b57cec5SDimitry Andric // uses RELA. As far as we know, all 64-bit ABIs are using RELA. A
4230b57cec5SDimitry Andric // few 32-bit ABIs are using RELA too.
4240b57cec5SDimitry Andric bool isRela;
4250b57cec5SDimitry Andric
4260b57cec5SDimitry Andric // True if we are creating position-independent code.
4270b57cec5SDimitry Andric bool isPic;
4280b57cec5SDimitry Andric
4290b57cec5SDimitry Andric // 4 for ELF32, 8 for ELF64.
4300b57cec5SDimitry Andric int wordsize;
43181ad6265SDimitry Andric
43281ad6265SDimitry Andric // Mode of MTE to write to the ELF note. Should be one of NT_MEMTAG_ASYNC (for
43381ad6265SDimitry Andric // async), NT_MEMTAG_SYNC (for sync), or NT_MEMTAG_LEVEL_NONE (for none). If
43481ad6265SDimitry Andric // async or sync is enabled, write the ELF note specifying the default MTE
43581ad6265SDimitry Andric // mode.
43681ad6265SDimitry Andric int androidMemtagMode;
43781ad6265SDimitry Andric // Signal to the dynamic loader to enable heap MTE.
43881ad6265SDimitry Andric bool androidMemtagHeap;
43981ad6265SDimitry Andric // Signal to the dynamic loader that this binary expects stack MTE. Generally,
44081ad6265SDimitry Andric // this means to map the primary and thread stacks as PROT_MTE. Note: This is
44181ad6265SDimitry Andric // not supported on Android 11 & 12.
44281ad6265SDimitry Andric bool androidMemtagStack;
443bdd1243dSDimitry Andric
44406c3fb27SDimitry Andric // When using a unified pre-link LTO pipeline, specify the backend LTO mode.
44506c3fb27SDimitry Andric LtoKind ltoKind = LtoKind::Default;
44606c3fb27SDimitry Andric
447bdd1243dSDimitry Andric unsigned threadCount;
44806c3fb27SDimitry Andric
44906c3fb27SDimitry Andric // If an input file equals a key, remap it to the value.
45006c3fb27SDimitry Andric llvm::DenseMap<llvm::StringRef, llvm::StringRef> remapInputs;
45106c3fb27SDimitry Andric // If an input file matches a wildcard pattern, remap it to the value.
45206c3fb27SDimitry Andric llvm::SmallVector<std::pair<llvm::GlobPattern, llvm::StringRef>, 0>
45306c3fb27SDimitry Andric remapInputsWildcards;
454bdd1243dSDimitry Andric };
455bdd1243dSDimitry Andric struct ConfigWrapper {
456bdd1243dSDimitry Andric Config c;
457bdd1243dSDimitry Andric Config *operator->() { return &c; }
4580b57cec5SDimitry Andric };
4590b57cec5SDimitry Andric
460bdd1243dSDimitry Andric LLVM_LIBRARY_VISIBILITY extern ConfigWrapper config;
4610b57cec5SDimitry Andric
46281ad6265SDimitry Andric struct DuplicateSymbol {
46381ad6265SDimitry Andric const Symbol *sym;
46481ad6265SDimitry Andric const InputFile *file;
46581ad6265SDimitry Andric InputSectionBase *section;
46681ad6265SDimitry Andric uint64_t value;
46781ad6265SDimitry Andric };
46881ad6265SDimitry Andric
46981ad6265SDimitry Andric struct Ctx {
470bdd1243dSDimitry Andric LinkerDriver driver;
47181ad6265SDimitry Andric SmallVector<std::unique_ptr<MemoryBuffer>> memoryBuffers;
47281ad6265SDimitry Andric SmallVector<ELFFileBase *, 0> objectFiles;
47381ad6265SDimitry Andric SmallVector<SharedFile *, 0> sharedFiles;
47481ad6265SDimitry Andric SmallVector<BinaryFile *, 0> binaryFiles;
47581ad6265SDimitry Andric SmallVector<BitcodeFile *, 0> bitcodeFiles;
47681ad6265SDimitry Andric SmallVector<BitcodeFile *, 0> lazyBitcodeFiles;
477bdd1243dSDimitry Andric SmallVector<InputSectionBase *, 0> inputSections;
478bdd1243dSDimitry Andric SmallVector<EhInputSection *, 0> ehInputSections;
47981ad6265SDimitry Andric // Duplicate symbol candidates.
48081ad6265SDimitry Andric SmallVector<DuplicateSymbol, 0> duplicates;
48181ad6265SDimitry Andric // Symbols in a non-prevailing COMDAT group which should be changed to an
48281ad6265SDimitry Andric // Undefined.
48381ad6265SDimitry Andric SmallVector<std::pair<Symbol *, unsigned>, 0> nonPrevailingSyms;
48481ad6265SDimitry Andric // A tuple of (reference, extractedFile, sym). Used by --why-extract=.
48581ad6265SDimitry Andric SmallVector<std::tuple<std::string, const InputFile *, const Symbol &>, 0>
48681ad6265SDimitry Andric whyExtractRecords;
48781ad6265SDimitry Andric // A mapping from a symbol to an InputFile referencing it backward. Used by
48881ad6265SDimitry Andric // --warn-backrefs.
48981ad6265SDimitry Andric llvm::DenseMap<const Symbol *,
49081ad6265SDimitry Andric std::pair<const InputFile *, const InputFile *>>
49181ad6265SDimitry Andric backwardReferences;
49206c3fb27SDimitry Andric llvm::SmallSet<llvm::StringRef, 0> auxiliaryFiles;
4937a6dacacSDimitry Andric // InputFile for linker created symbols with no source location.
4947a6dacacSDimitry Andric InputFile *internalFile;
495bdd1243dSDimitry Andric // True if SHT_LLVM_SYMPART is used.
496bdd1243dSDimitry Andric std::atomic<bool> hasSympart{false};
497bdd1243dSDimitry Andric // True if there are TLS IE relocations. Set DF_STATIC_TLS if -shared.
498bdd1243dSDimitry Andric std::atomic<bool> hasTlsIe{false};
499bdd1243dSDimitry Andric // True if we need to reserve two .got entries for local-dynamic TLS model.
500bdd1243dSDimitry Andric std::atomic<bool> needsTlsLd{false};
5015f757f3fSDimitry Andric // True if all native vtable symbols have corresponding type info symbols
5025f757f3fSDimitry Andric // during LTO.
5035f757f3fSDimitry Andric bool ltoAllVtablesHaveTypeInfos;
5045f757f3fSDimitry Andric
5055f757f3fSDimitry Andric // Each symbol assignment and DEFINED(sym) reference is assigned an increasing
5065f757f3fSDimitry Andric // order. Each DEFINED(sym) evaluation checks whether the reference happens
5075f757f3fSDimitry Andric // before a possible `sym = expr;`.
5085f757f3fSDimitry Andric unsigned scriptSymOrderCounter = 1;
5095f757f3fSDimitry Andric llvm::DenseMap<const Symbol *, unsigned> scriptSymOrder;
510bdd1243dSDimitry Andric
511bdd1243dSDimitry Andric void reset();
51206c3fb27SDimitry Andric
51306c3fb27SDimitry Andric llvm::raw_fd_ostream openAuxiliaryFile(llvm::StringRef, std::error_code &);
5140fca6ea1SDimitry Andric
5150fca6ea1SDimitry Andric ArrayRef<uint8_t> aarch64PauthAbiCoreInfo;
51681ad6265SDimitry Andric };
51781ad6265SDimitry Andric
518bdd1243dSDimitry Andric LLVM_LIBRARY_VISIBILITY extern Ctx ctx;
51981ad6265SDimitry Andric
52085868e8aSDimitry Andric // The first two elements of versionDefinitions represent VER_NDX_LOCAL and
52185868e8aSDimitry Andric // VER_NDX_GLOBAL. This helper returns other elements.
namedVersionDefs()52285868e8aSDimitry Andric static inline ArrayRef<VersionDefinition> namedVersionDefs() {
523bdd1243dSDimitry Andric return llvm::ArrayRef(config->versionDefinitions).slice(2);
52485868e8aSDimitry Andric }
52585868e8aSDimitry Andric
5261fd87a68SDimitry Andric void errorOrWarn(const Twine &msg);
527fe6060f1SDimitry Andric
internalLinkerError(StringRef loc,const Twine & msg)528fe6060f1SDimitry Andric static inline void internalLinkerError(StringRef loc, const Twine &msg) {
529fe6060f1SDimitry Andric errorOrWarn(loc + "internal linker error: " + msg + "\n" +
530fe6060f1SDimitry Andric llvm::getBugReportMsg());
531fe6060f1SDimitry Andric }
532fe6060f1SDimitry Andric
533bdd1243dSDimitry Andric } // namespace lld::elf
5340b57cec5SDimitry Andric
5350b57cec5SDimitry Andric #endif
536