807 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLD_ELF_CONFIG_H10#define LLD_ELF_CONFIG_H11 12#include "lld/Common/CommonLinkerContext.h"13#include "lld/Common/ErrorHandler.h"14#include "llvm/ADT/CachedHashString.h"15#include "llvm/ADT/DenseSet.h"16#include "llvm/ADT/MapVector.h"17#include "llvm/ADT/SetVector.h"18#include "llvm/ADT/SmallSet.h"19#include "llvm/ADT/StringRef.h"20#include "llvm/ADT/StringSet.h"21#include "llvm/BinaryFormat/ELF.h"22#include "llvm/Option/ArgList.h"23#include "llvm/Support/CachePruning.h"24#include "llvm/Support/CodeGen.h"25#include "llvm/Support/Compiler.h"26#include "llvm/Support/Compression.h"27#include "llvm/Support/Endian.h"28#include "llvm/Support/FileSystem.h"29#include "llvm/Support/GlobPattern.h"30#include "llvm/Support/TarWriter.h"31#include <atomic>32#include <memory>33#include <mutex>34#include <optional>35#include <vector>36 37namespace lld::elf {38 39class InputFile;40class BinaryFile;41class BitcodeFile;42class ELFFileBase;43class SharedFile;44class InputSectionBase;45class EhInputSection;46class Defined;47class Undefined;48class Symbol;49class SymbolTable;50class BitcodeCompiler;51class OutputSection;52class LinkerScript;53class TargetInfo;54struct Ctx;55struct Partition;56struct PhdrEntry;57 58class BssSection;59class GdbIndexSection;60class GotPltSection;61class GotSection;62class IBTPltSection;63class IgotPltSection;64class InputSection;65class IpltSection;66class MipsGotSection;67class MipsRldMapSection;68class PPC32Got2Section;69class PPC64LongBranchTargetSection;70class PltSection;71class RelocationBaseSection;72class RelroPaddingSection;73class StringTableSection;74class SymbolTableBaseSection;75class SymtabShndxSection;76class SyntheticSection;77 78enum ELFKind : uint8_t {79 ELFNoneKind,80 ELF32LEKind,81 ELF32BEKind,82 ELF64LEKind,83 ELF64BEKind84};85 86// For -Bno-symbolic, -Bsymbolic-non-weak-functions, -Bsymbolic-functions,87// -Bsymbolic-non-weak, -Bsymbolic.88enum class BsymbolicKind { None, NonWeakFunctions, Functions, NonWeak, All };89 90// For --build-id.91enum class BuildIdKind { None, Fast, Md5, Sha1, Hexstring, Uuid };92 93// For --call-graph-profile-sort={none,hfsort,cdsort}.94enum class CGProfileSortKind { None, Hfsort, Cdsort };95 96// For --discard-{all,locals,none}.97enum class DiscardPolicy { Default, All, Locals, None };98 99// For --icf={none,safe,all}.100enum class ICFLevel { None, Safe, All };101 102// For --strip-{all,debug}.103enum class StripPolicy { None, All, Debug };104 105// For --unresolved-symbols.106enum class UnresolvedPolicy { ReportError, Warn, Ignore };107 108// For --orphan-handling.109enum class OrphanHandlingPolicy { Place, Warn, Error };110 111// For --sort-section and linkerscript sorting rules.112enum class SortSectionPolicy {113 Default,114 None,115 Alignment,116 Name,117 Priority,118 Reverse,119};120 121// For --target2122enum class Target2Policy { Abs, Rel, GotRel };123 124// For tracking ARM Float Argument PCS125enum class ARMVFPArgKind { Default, Base, VFP, ToolChain };126 127// For -z noseparate-code, -z separate-code and -z separate-loadable-segments.128enum class SeparateSegmentKind { None, Code, Loadable };129 130// For -z *stack131enum class GnuStackKind { None, Exec, NoExec };132 133// For --lto=134enum LtoKind : uint8_t {UnifiedThin, UnifiedRegular, Default};135 136// For -z gcs=137enum class GcsPolicy { Implicit, Never, Always };138 139// For -z zicfilp=140enum class ZicfilpPolicy { Implicit, Never, Unlabeled, FuncSig };141 142// For -z zicfiss=143enum class ZicfissPolicy { Implicit, Never, Always };144 145// For some options that resemble -z bti-report={none,warning,error}146enum class ReportPolicy { None, Warning, Error };147 148// Describes the signing schema for a file using the PAuth ABI extension.149// Two files are considered compatible when both `platform` and `version` match.150// The pair (0, 0) is reserved to indicate incompatibility with the PAuth ABI.151struct AArch64PauthAbiCoreInfo {152 uint64_t platform;153 uint64_t version;154 // Returns true if the core info is not the reserved (0, 0) value.155 bool isValid() const { return platform || version; }156 static constexpr size_t size() { return sizeof(platform) + sizeof(version); }157 bool operator==(const AArch64PauthAbiCoreInfo &other) const {158 return platform == other.platform && version == other.version;159 }160 bool operator!=(const AArch64PauthAbiCoreInfo &other) const {161 return !(*this == other);162 }163};164 165struct SymbolVersion {166 llvm::StringRef name;167 bool isExternCpp;168 bool hasWildcard;169};170 171// This struct contains symbols version definition that172// can be found in version script if it is used for link.173struct VersionDefinition {174 llvm::StringRef name;175 uint16_t id;176 SmallVector<SymbolVersion, 0> nonLocalPatterns;177 SmallVector<SymbolVersion, 0> localPatterns;178};179 180class LinkerDriver {181public:182 LinkerDriver(Ctx &ctx);183 LinkerDriver(LinkerDriver &) = delete;184 void linkerMain(ArrayRef<const char *> args);185 void addFile(StringRef path, bool withLOption);186 void addLibrary(StringRef name);187 188private:189 Ctx &ctx;190 void createFiles(llvm::opt::InputArgList &args);191 void inferMachineType();192 template <class ELFT> void link(llvm::opt::InputArgList &args);193 template <class ELFT> void compileBitcodeFiles(bool skipLinkedOutput);194 bool tryAddFatLTOFile(MemoryBufferRef mb, StringRef archiveName,195 uint64_t offsetInArchive, bool lazy);196 // True if we are in --whole-archive and --no-whole-archive.197 bool inWholeArchive = false;198 199 // True if we are in --start-lib and --end-lib.200 bool inLib = false;201 202 std::unique_ptr<BitcodeCompiler> lto;203 SmallVector<std::unique_ptr<InputFile>, 0> files, ltoObjectFiles;204 205public:206 // See InputFile::groupId.207 uint32_t nextGroupId;208 bool isInGroup;209 std::unique_ptr<InputFile> armCmseImpLib;210 SmallVector<std::pair<StringRef, unsigned>, 0> archiveFiles;211};212 213// This struct contains the global configuration for the linker.214// Most fields are direct mapping from the command line options215// and such fields have the same name as the corresponding options.216// Most fields are initialized by the ctx.driver.217struct Config {218 uint8_t osabi = 0;219 uint32_t andFeatures = 0;220 llvm::CachePruningPolicy thinLTOCachePolicy;221 llvm::SetVector<llvm::CachedHashString> dependencyFiles; // for --dependency-file222 llvm::StringMap<uint64_t> sectionStartMap;223 llvm::StringRef bfdname;224 llvm::StringRef chroot;225 llvm::StringRef dependencyFile;226 llvm::StringRef dwoDir;227 llvm::StringRef dynamicLinker;228 llvm::StringRef entry;229 llvm::StringRef emulation;230 llvm::StringRef fini;231 llvm::StringRef init;232 llvm::StringRef ltoAAPipeline;233 llvm::StringRef ltoCSProfileFile;234 llvm::StringRef ltoNewPmPasses;235 llvm::StringRef ltoObjPath;236 llvm::StringRef ltoSampleProfile;237 llvm::StringRef mapFile;238 llvm::StringRef outputFile;239 llvm::StringRef optRemarksFilename;240 std::optional<uint64_t> optRemarksHotnessThreshold = 0;241 llvm::StringRef optRemarksPasses;242 llvm::StringRef optRemarksFormat;243 llvm::StringRef optStatsFilename;244 llvm::StringRef progName;245 llvm::StringRef printArchiveStats;246 llvm::StringRef printSymbolOrder;247 llvm::StringRef soName;248 llvm::StringRef sysroot;249 llvm::StringRef thinLTOCacheDir;250 llvm::StringRef thinLTOIndexOnlyArg;251 llvm::StringRef whyExtract;252 llvm::SmallVector<llvm::GlobPattern, 0> whyLive;253 llvm::StringRef cmseInputLib;254 llvm::StringRef cmseOutputLib;255 ReportPolicy zBtiReport = ReportPolicy::None;256 ReportPolicy zCetReport = ReportPolicy::None;257 ReportPolicy zPauthReport = ReportPolicy::None;258 ReportPolicy zGcsReport = ReportPolicy::None;259 ReportPolicy zGcsReportDynamic = ReportPolicy::None;260 ReportPolicy zExecuteOnlyReport = ReportPolicy::None;261 ReportPolicy zZicfilpUnlabeledReport = ReportPolicy::None;262 ReportPolicy zZicfilpFuncSigReport = ReportPolicy::None;263 ReportPolicy zZicfissReport = ReportPolicy::None;264 bool ltoBBAddrMap;265 llvm::StringRef ltoBasicBlockSections;266 std::pair<llvm::StringRef, llvm::StringRef> thinLTOObjectSuffixReplace;267 llvm::StringRef thinLTOPrefixReplaceOld;268 llvm::StringRef thinLTOPrefixReplaceNew;269 llvm::StringRef thinLTOPrefixReplaceNativeObject;270 std::string rpath;271 llvm::SmallVector<VersionDefinition, 0> versionDefinitions;272 llvm::SmallVector<llvm::StringRef, 0> auxiliaryList;273 llvm::SmallVector<llvm::StringRef, 0> filterList;274 llvm::SmallVector<llvm::StringRef, 0> passPlugins;275 llvm::SmallVector<llvm::StringRef, 0> searchPaths;276 llvm::SmallVector<llvm::StringRef, 0> symbolOrderingFile;277 llvm::SmallVector<llvm::StringRef, 0> thinLTOModulesToCompile;278 llvm::StringRef dtltoDistributor;279 llvm::SmallVector<llvm::StringRef, 0> dtltoDistributorArgs;280 llvm::StringRef dtltoCompiler;281 llvm::SmallVector<llvm::StringRef, 0> dtltoCompilerPrependArgs;282 llvm::SmallVector<llvm::StringRef, 0> dtltoCompilerArgs;283 llvm::SmallVector<llvm::StringRef, 0> undefined;284 llvm::SmallVector<SymbolVersion, 0> dynamicList;285 llvm::SmallVector<uint8_t, 0> buildIdVector;286 llvm::SmallVector<llvm::StringRef, 0> mllvmOpts;287 llvm::MapVector<std::pair<const InputSectionBase *, const InputSectionBase *>,288 uint64_t>289 callGraphProfile;290 bool cmseImplib = false;291 bool allowMultipleDefinition;292 bool fatLTOObjects;293 bool androidPackDynRelocs = false;294 bool armHasArmISA = false;295 bool armHasThumb2ISA = false;296 bool armHasBlx = false;297 bool armHasMovtMovw = false;298 bool armJ1J2BranchEncoding = false;299 bool armCMSESupport = false;300 bool asNeeded = false;301 bool armBe8 = false;302 BsymbolicKind bsymbolic = BsymbolicKind::None;303 CGProfileSortKind callGraphProfileSort;304 llvm::StringRef irpgoProfilePath;305 bool bpStartupFunctionSort = false;306 bool bpCompressionSortStartupFunctions = false;307 bool bpFunctionOrderForCompression = false;308 bool bpDataOrderForCompression = false;309 bool bpVerboseSectionOrderer = false;310 bool branchToBranch = false;311 bool checkSections;312 bool checkDynamicRelocs;313 std::optional<llvm::DebugCompressionType> compressDebugSections;314 llvm::SmallVector<315 std::tuple<llvm::GlobPattern, llvm::DebugCompressionType, unsigned>, 0>316 compressSections;317 bool cref;318 llvm::SmallVector<std::pair<llvm::GlobPattern, uint64_t>, 0>319 deadRelocInNonAlloc;320 bool debugNames;321 bool demangle = true;322 bool dependentLibraries;323 bool disableVerify;324 bool ehFrameHdr;325 bool emitLLVM;326 bool emitRelocs;327 bool enableNewDtags;328 bool enableNonContiguousRegions;329 bool executeOnly;330 bool exportDynamic;331 bool fixCortexA53Errata843419;332 bool fixCortexA8;333 bool formatBinary = false;334 bool fortranCommon;335 bool gcSections;336 bool gdbIndex;337 bool gnuHash = false;338 bool gnuUnique;339 bool ignoreDataAddressEquality;340 bool ignoreFunctionAddressEquality;341 bool ltoCSProfileGenerate;342 bool ltoPGOWarnMismatch;343 bool ltoDebugPassManager;344 bool ltoEmitAsm;345 bool ltoUniqueBasicBlockSectionNames;346 bool ltoValidateAllVtablesHaveTypeInfos;347 bool ltoWholeProgramVisibility;348 bool mergeArmExidx;349 bool mipsN32Abi = false;350 bool mmapOutputFile;351 bool nmagic;352 bool noinhibitExec;353 bool nostdlib;354 bool oFormatBinary;355 bool omagic;356 bool optEB = false;357 bool optEL = false;358 bool optimizeBBJumps;359 bool optRemarksWithHotness;360 bool picThunk;361 bool pie;362 llvm::StringRef printGcSections;363 bool printIcfSections;364 bool printMemoryUsage;365 std::optional<uint64_t> randomizeSectionPadding;366 bool rejectMismatch;367 bool relax;368 bool relaxGP;369 bool relocatable;370 bool resolveGroups;371 bool relrGlibc = false;372 bool relrPackDynRelocs = false;373 llvm::DenseSet<llvm::StringRef> saveTempsArgs;374 llvm::SmallVector<std::pair<llvm::GlobPattern, uint32_t>, 0> shuffleSections;375 bool singleRoRx;376 bool singleXoRx;377 bool shared;378 bool symbolic;379 bool isStatic = false;380 bool sysvHash = false;381 bool target1Rel;382 bool trace;383 bool thinLTOEmitImportsFiles;384 bool thinLTOEmitIndexFiles;385 bool thinLTOIndexOnly;386 bool timeTraceEnabled;387 bool tocOptimize;388 bool pcRelOptimize;389 bool undefinedVersion;390 bool unique;391 bool useAndroidRelrTags = false;392 bool warnBackrefs;393 llvm::SmallVector<llvm::GlobPattern, 0> warnBackrefsExclude;394 bool warnCommon;395 bool warnMissingEntry;396 bool warnSymbolOrdering;397 bool writeAddends;398 bool zCombreloc;399 bool zCopyreloc;400 bool zDynamicUndefined;401 bool zForceBti;402 bool zForceIbt;403 bool zGlobal;404 bool zHazardplt;405 bool zIfuncNoplt;406 bool zInitfirst;407 bool zInterpose;408 bool zKeepDataSectionPrefix;409 bool zKeepTextSectionPrefix;410 bool zLrodataAfterBss;411 bool zNoBtCfi;412 bool zNodefaultlib;413 bool zNodelete;414 bool zNodlopen;415 bool zNow;416 bool zOrigin;417 bool zPacPlt;418 bool zRelro;419 bool zRodynamic;420 bool zSectionHeader;421 bool zShstk;422 bool zStartStopGC;423 uint8_t zStartStopVisibility;424 bool zText;425 bool zRetpolineplt;426 bool zWxneeded;427 ZicfilpPolicy zZicfilp;428 ZicfissPolicy zZicfiss;429 DiscardPolicy discard;430 GnuStackKind zGnustack;431 ICFLevel icf;432 OrphanHandlingPolicy orphanHandling;433 SortSectionPolicy sortSection;434 StripPolicy strip;435 UnresolvedPolicy unresolvedSymbols;436 UnresolvedPolicy unresolvedSymbolsInShlib;437 Target2Policy target2;438 GcsPolicy zGcs;439 bool power10Stubs;440 ARMVFPArgKind armVFPArgs = ARMVFPArgKind::Default;441 BuildIdKind buildId = BuildIdKind::None;442 SeparateSegmentKind zSeparate;443 ELFKind ekind = ELFNoneKind;444 uint16_t emachine = llvm::ELF::EM_NONE;445 std::optional<uint64_t> imageBase;446 uint64_t commonPageSize;447 uint64_t maxPageSize;448 uint64_t mipsGotSize;449 uint64_t zStackSize;450 unsigned ltoPartitions;451 unsigned ltoo;452 llvm::CodeGenOptLevel ltoCgo;453 unsigned optimize;454 StringRef thinLTOJobs;455 unsigned timeTraceGranularity;456 int32_t splitStackAdjustSize;457 SmallVector<uint8_t, 0> packageMetadata;458 459 // The following config options do not directly correspond to any460 // particular command line options.461 462 // True if we need to pass through relocations in input files to the463 // output file. Usually false because we consume relocations.464 bool copyRelocs;465 466 // True if the target is ELF64. False if ELF32.467 bool is64;468 469 // True if the target is little-endian. False if big-endian.470 bool isLE;471 472 // endianness::little if isLE is true. endianness::big otherwise.473 llvm::endianness endianness;474 475 // True if the target is the little-endian MIPS64.476 //477 // The reason why we have this variable only for the MIPS is because478 // we use this often. Some ELF headers for MIPS64EL are in a479 // mixed-endian (which is horrible and I'd say that's a serious spec480 // bug), and we need to know whether we are reading MIPS ELF files or481 // not in various places.482 //483 // (Note that MIPS64EL is not a typo for MIPS64LE. This is the official484 // name whatever that means. A fun hypothesis is that "EL" is short for485 // little-endian written in the little-endian order, but I don't know486 // if that's true.)487 bool isMips64EL;488 489 // True if we need to set the DF_STATIC_TLS flag to an output file, which490 // works as a hint to the dynamic loader that the shared object contains code491 // compiled with the initial-exec TLS model.492 bool hasTlsIe = false;493 494 // Holds set of ELF header flags for the target.495 uint32_t eflags = 0;496 497 // The ELF spec defines two types of relocation table entries, RELA and498 // REL. RELA is a triplet of (offset, info, addend) while REL is a499 // tuple of (offset, info). Addends for REL are implicit and read from500 // the location where the relocations are applied. So, REL is more501 // compact than RELA but requires a bit of more work to process.502 //503 // (From the linker writer's view, this distinction is not necessary.504 // If the ELF had chosen whichever and sticked with it, it would have505 // been easier to write code to process relocations, but it's too late506 // to change the spec.)507 //508 // Each ABI defines its relocation type. IsRela is true if target509 // uses RELA. As far as we know, all 64-bit ABIs are using RELA. A510 // few 32-bit ABIs are using RELA too.511 bool isRela;512 513 // True if we are creating position-independent code.514 bool isPic;515 516 // 4 for ELF32, 8 for ELF64.517 int wordsize;518 519 // Mode of MTE to write to the ELF note. Should be one of NT_MEMTAG_ASYNC (for520 // async), NT_MEMTAG_SYNC (for sync), or NT_MEMTAG_LEVEL_NONE (for none). If521 // async or sync is enabled, write the ELF note specifying the default MTE522 // mode.523 int androidMemtagMode;524 // Signal to the dynamic loader to enable heap MTE.525 bool androidMemtagHeap;526 // Signal to the dynamic loader that this binary expects stack MTE. Generally,527 // this means to map the primary and thread stacks as PROT_MTE. Note: This is528 // not supported on Android 11 & 12.529 bool androidMemtagStack;530 531 // When using a unified pre-link LTO pipeline, specify the backend LTO mode.532 LtoKind ltoKind = LtoKind::Default;533 534 unsigned threadCount;535 536 // If an input file equals a key, remap it to the value.537 llvm::DenseMap<llvm::StringRef, llvm::StringRef> remapInputs;538 // If an input file matches a wildcard pattern, remap it to the value.539 llvm::SmallVector<std::pair<llvm::GlobPattern, llvm::StringRef>, 0>540 remapInputsWildcards;541};542 543// Some index properties of a symbol are stored separately in this auxiliary544// struct to decrease sizeof(SymbolUnion) in the majority of cases.545struct SymbolAux {546 uint32_t gotIdx = -1;547 uint32_t pltIdx = -1;548 uint32_t tlsDescIdx = -1;549 uint32_t tlsGdIdx = -1;550};551 552struct DuplicateSymbol {553 const Symbol *sym;554 const InputFile *file;555 InputSectionBase *section;556 uint64_t value;557};558 559struct UndefinedDiag {560 Undefined *sym;561 struct Loc {562 InputSectionBase *sec;563 uint64_t offset;564 };565 SmallVector<Loc, 0> locs;566 bool isWarning;567};568 569// Linker generated sections which can be used as inputs and are not specific to570// a partition.571struct InStruct {572 std::unique_ptr<InputSection> attributes;573 std::unique_ptr<SyntheticSection> hexagonAttributes;574 std::unique_ptr<SyntheticSection> riscvAttributes;575 std::unique_ptr<BssSection> bss;576 std::unique_ptr<BssSection> bssRelRo;577 std::unique_ptr<SyntheticSection> gnuProperty;578 std::unique_ptr<SyntheticSection> gnuStack;579 std::unique_ptr<GotSection> got;580 std::unique_ptr<GotPltSection> gotPlt;581 std::unique_ptr<IgotPltSection> igotPlt;582 std::unique_ptr<RelroPaddingSection> relroPadding;583 std::unique_ptr<SyntheticSection> armCmseSGSection;584 std::unique_ptr<PPC64LongBranchTargetSection> ppc64LongBranchTarget;585 std::unique_ptr<SyntheticSection> mipsAbiFlags;586 std::unique_ptr<MipsGotSection> mipsGot;587 std::unique_ptr<SyntheticSection> mipsOptions;588 std::unique_ptr<SyntheticSection> mipsReginfo;589 std::unique_ptr<MipsRldMapSection> mipsRldMap;590 std::unique_ptr<SyntheticSection> partEnd;591 std::unique_ptr<SyntheticSection> partIndex;592 std::unique_ptr<PltSection> plt;593 std::unique_ptr<IpltSection> iplt;594 std::unique_ptr<PPC32Got2Section> ppc32Got2;595 std::unique_ptr<IBTPltSection> ibtPlt;596 std::unique_ptr<RelocationBaseSection> relaPlt;597 // Non-SHF_ALLOC sections598 std::unique_ptr<SyntheticSection> debugNames;599 std::unique_ptr<GdbIndexSection> gdbIndex;600 std::unique_ptr<StringTableSection> shStrTab;601 std::unique_ptr<StringTableSection> strTab;602 std::unique_ptr<SymbolTableBaseSection> symTab;603 std::unique_ptr<SymtabShndxSection> symTabShndx;604};605 606struct Ctx : CommonLinkerContext {607 Config arg;608 LinkerDriver driver;609 LinkerScript *script;610 std::unique_ptr<TargetInfo> target;611 612 // These variables are initialized by Writer and should not be used before613 // Writer is initialized.614 uint8_t *bufferStart = nullptr;615 Partition *mainPart = nullptr;616 PhdrEntry *tlsPhdr = nullptr;617 struct OutSections {618 std::unique_ptr<OutputSection> elfHeader;619 std::unique_ptr<OutputSection> programHeaders;620 OutputSection *preinitArray = nullptr;621 OutputSection *initArray = nullptr;622 OutputSection *finiArray = nullptr;623 };624 OutSections out;625 SmallVector<OutputSection *, 0> outputSections;626 std::vector<Partition> partitions;627 628 InStruct in;629 630 // Some linker-generated symbols need to be created as631 // Defined symbols.632 struct ElfSym {633 // __bss_start634 Defined *bss;635 636 // etext and _etext637 Defined *etext1;638 Defined *etext2;639 640 // edata and _edata641 Defined *edata1;642 Defined *edata2;643 644 // end and _end645 Defined *end1;646 Defined *end2;647 648 // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to649 // be at some offset from the base of the .got section, usually 0 or650 // the end of the .got.651 Defined *globalOffsetTable;652 653 // _gp, _gp_disp and __gnu_local_gp symbols. Only for MIPS.654 Defined *mipsGp;655 Defined *mipsGpDisp;656 Defined *mipsLocalGp;657 658 // __global_pointer$ for RISC-V.659 Defined *riscvGlobalPointer;660 661 // __rel{,a}_iplt_{start,end} symbols.662 Defined *relaIpltStart;663 Defined *relaIpltEnd;664 665 // _TLS_MODULE_BASE_ on targets that support TLSDESC.666 Defined *tlsModuleBase;667 };668 ElfSym sym{};669 std::unique_ptr<SymbolTable> symtab;670 SmallVector<Symbol *, 0> synthesizedSymbols;671 672 SmallVector<std::unique_ptr<MemoryBuffer>> memoryBuffers;673 SmallVector<ELFFileBase *, 0> objectFiles;674 SmallVector<SharedFile *, 0> sharedFiles;675 SmallVector<BinaryFile *, 0> binaryFiles;676 SmallVector<BitcodeFile *, 0> bitcodeFiles;677 SmallVector<BitcodeFile *, 0> lazyBitcodeFiles;678 SmallVector<InputSectionBase *, 0> inputSections;679 SmallVector<EhInputSection *, 0> ehInputSections;680 681 SmallVector<SymbolAux, 0> symAux;682 // Duplicate symbol candidates.683 SmallVector<DuplicateSymbol, 0> duplicates;684 // Undefined diagnostics are collected in a vector and emitted once all of685 // them are known, so that some postprocessing on the list of undefined686 // symbols can happen before lld emits diagnostics.687 std::mutex relocMutex;688 SmallVector<UndefinedDiag, 0> undefErrs;689 // Symbols in a non-prevailing COMDAT group which should be changed to an690 // Undefined.691 SmallVector<std::pair<Symbol *, unsigned>, 0> nonPrevailingSyms;692 // A tuple of (reference, extractedFile, sym). Used by --why-extract=.693 SmallVector<std::tuple<std::string, const InputFile *, const Symbol &>, 0>694 whyExtractRecords;695 // A mapping from a symbol to an InputFile referencing it backward. Used by696 // --warn-backrefs.697 llvm::DenseMap<const Symbol *,698 std::pair<const InputFile *, const InputFile *>>699 backwardReferences;700 llvm::SmallSet<llvm::StringRef, 0> auxiliaryFiles;701 // If --reproduce is specified, all input files are written to this tar702 // archive.703 std::unique_ptr<llvm::TarWriter> tar;704 // InputFile for linker created symbols with no source location.705 InputFile *internalFile = nullptr;706 // Dummy Undefined for relocations without a symbol.707 Undefined *dummySym = nullptr;708 // True if symbols can be exported (isExported) or preemptible.709 bool hasDynsym = false;710 // True if SHT_LLVM_SYMPART is used.711 std::atomic<bool> hasSympart{false};712 // True if there are TLS IE relocations. Set DF_STATIC_TLS if -shared.713 std::atomic<bool> hasTlsIe{false};714 // True if we need to reserve two .got entries for local-dynamic TLS model.715 std::atomic<bool> needsTlsLd{false};716 // True if all native vtable symbols have corresponding type info symbols717 // during LTO.718 bool ltoAllVtablesHaveTypeInfos = false;719 // Number of Vernaux entries (needed shared object names).720 uint32_t vernauxNum = 0;721 722 // Each symbol assignment and DEFINED(sym) reference is assigned an increasing723 // order. Each DEFINED(sym) evaluation checks whether the reference happens724 // before a possible `sym = expr;`.725 unsigned scriptSymOrderCounter = 1;726 llvm::DenseMap<const Symbol *, unsigned> scriptSymOrder;727 728 // The set of TOC entries (.toc + addend) for which we should not apply729 // toc-indirect to toc-relative relaxation. const Symbol * refers to the730 // STT_SECTION symbol associated to the .toc input section.731 llvm::DenseSet<std::pair<const Symbol *, uint64_t>> ppc64noTocRelax;732 733 Ctx();734 735 llvm::raw_fd_ostream openAuxiliaryFile(llvm::StringRef, std::error_code &);736 737 std::optional<AArch64PauthAbiCoreInfo> aarch64PauthAbiCoreInfo;738};739 740// The first two elements of versionDefinitions represent VER_NDX_LOCAL and741// VER_NDX_GLOBAL. This helper returns other elements.742static inline ArrayRef<VersionDefinition> namedVersionDefs(Ctx &ctx) {743 return llvm::ArrayRef(ctx.arg.versionDefinitions).slice(2);744}745 746struct ELFSyncStream : SyncStream {747 Ctx &ctx;748 ELFSyncStream(Ctx &ctx, DiagLevel level)749 : SyncStream(ctx.e, level), ctx(ctx) {}750};751 752template <typename T>753std::enable_if_t<!std::is_pointer_v<std::remove_reference_t<T>>,754 const ELFSyncStream &>755operator<<(const ELFSyncStream &s, T &&v) {756 s.os << std::forward<T>(v);757 return s;758}759 760inline const ELFSyncStream &operator<<(const ELFSyncStream &s, const char *v) {761 s.os << v;762 return s;763}764 765inline const ELFSyncStream &operator<<(const ELFSyncStream &s, Error v) {766 s.os << llvm::toString(std::move(v));767 return s;768}769 770// Report a log if --verbose is specified.771ELFSyncStream Log(Ctx &ctx);772 773// Print a message to stdout.774ELFSyncStream Msg(Ctx &ctx);775 776// Report a warning. Upgraded to an error if --fatal-warnings is specified.777ELFSyncStream Warn(Ctx &ctx);778 779// Report an error that will suppress the output file generation. Downgraded to780// a warning if --noinhibit-exec is specified.781ELFSyncStream Err(Ctx &ctx);782 783// Report an error regardless of --noinhibit-exec.784ELFSyncStream ErrAlways(Ctx &ctx);785 786// Report a fatal error that exits immediately. This should generally be avoided787// in favor of Err.788ELFSyncStream Fatal(Ctx &ctx);789 790uint64_t errCount(Ctx &ctx);791 792ELFSyncStream InternalErr(Ctx &ctx, const uint8_t *buf);793 794#define CHECK2(E, S) lld::check2((E), [&] { return toStr(ctx, S); })795 796inline DiagLevel toDiagLevel(ReportPolicy policy) {797 if (policy == ReportPolicy::Error)798 return DiagLevel::Err;799 else if (policy == ReportPolicy::Warning)800 return DiagLevel::Warn;801 return DiagLevel::None;802}803 804} // namespace lld::elf805 806#endif807