xref: /freebsd/contrib/llvm-project/lld/ELF/Config.h (revision 62987288060ff68c817b7056815aa9fb8ba8ecd7)
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