| 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/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 | |
| 37 | namespace lld::elf { |
| 38 | |
| 39 | class InputFile; |
| 40 | class BinaryFile; |
| 41 | class BitcodeFile; |
| 42 | class ELFFileBase; |
| 43 | class SharedFile; |
| 44 | class InputSectionBase; |
| 45 | class EhInputSection; |
| 46 | class Defined; |
| 47 | class Undefined; |
| 48 | class Symbol; |
| 49 | class SymbolTable; |
| 50 | class BitcodeCompiler; |
| 51 | class OutputSection; |
| 52 | class LinkerScript; |
| 53 | class TargetInfo; |
| 54 | struct Ctx; |
| 55 | struct Partition; |
| 56 | struct PhdrEntry; |
| 57 | |
| 58 | class BssSection; |
| 59 | class GdbIndexSection; |
| 60 | class GotPltSection; |
| 61 | class GotSection; |
| 62 | class IBTPltSection; |
| 63 | class IgotPltSection; |
| 64 | class InputSection; |
| 65 | class IpltSection; |
| 66 | class MipsGotSection; |
| 67 | class MipsRldMapSection; |
| 68 | class PPC32Got2Section; |
| 69 | class PPC64LongBranchTargetSection; |
| 70 | class PltSection; |
| 71 | class RelocationBaseSection; |
| 72 | class RelroPaddingSection; |
| 73 | class StringTableSection; |
| 74 | class SymbolTableBaseSection; |
| 75 | class SymtabShndxSection; |
| 76 | class SyntheticSection; |
| 77 | |
| 78 | enum ELFKind : uint8_t { |
| 79 | ELFNoneKind, |
| 80 | ELF32LEKind, |
| 81 | ELF32BEKind, |
| 82 | ELF64LEKind, |
| 83 | ELF64BEKind |
| 84 | }; |
| 85 | |
| 86 | // For -Bno-symbolic, -Bsymbolic-non-weak-functions, -Bsymbolic-functions, |
| 87 | // -Bsymbolic-non-weak, -Bsymbolic. |
| 88 | enum class BsymbolicKind { None, NonWeakFunctions, Functions, NonWeak, All }; |
| 89 | |
| 90 | // For --build-id. |
| 91 | enum class BuildIdKind { None, Fast, Md5, Sha1, Hexstring, Uuid }; |
| 92 | |
| 93 | // For --call-graph-profile-sort={none,hfsort,cdsort}. |
| 94 | enum class CGProfileSortKind { None, Hfsort, Cdsort }; |
| 95 | |
| 96 | // For --discard-{all,locals,none}. |
| 97 | enum class DiscardPolicy { Default, All, Locals, None }; |
| 98 | |
| 99 | // For --icf={none,safe,all}. |
| 100 | enum class ICFLevel { None, Safe, All }; |
| 101 | |
| 102 | // For --strip-{all,debug}. |
| 103 | enum class StripPolicy { None, All, Debug }; |
| 104 | |
| 105 | // For --unresolved-symbols. |
| 106 | enum class UnresolvedPolicy { ReportError, Warn, Ignore }; |
| 107 | |
| 108 | // For --orphan-handling. |
| 109 | enum class OrphanHandlingPolicy { Place, Warn, Error }; |
| 110 | |
| 111 | // For --sort-section and linkerscript sorting rules. |
| 112 | enum class SortSectionPolicy { |
| 113 | Default, |
| 114 | None, |
| 115 | Alignment, |
| 116 | Name, |
| 117 | Priority, |
| 118 | Reverse, |
| 119 | }; |
| 120 | |
| 121 | // For --target2 |
| 122 | enum class Target2Policy { Abs, Rel, GotRel }; |
| 123 | |
| 124 | // For tracking ARM Float Argument PCS |
| 125 | enum class ARMVFPArgKind { Default, Base, VFP, ToolChain }; |
| 126 | |
| 127 | // For -z noseparate-code, -z separate-code and -z separate-loadable-segments. |
| 128 | enum class SeparateSegmentKind { None, Code, Loadable }; |
| 129 | |
| 130 | // For -z *stack |
| 131 | enum class GnuStackKind { None, Exec, NoExec }; |
| 132 | |
| 133 | // For --lto= |
| 134 | enum LtoKind : uint8_t {UnifiedThin, UnifiedRegular, Default}; |
| 135 | |
| 136 | // For -z gcs= |
| 137 | enum class GcsPolicy { Implicit, Never, Always }; |
| 138 | |
| 139 | // For -z zicfilp= |
| 140 | enum class ZicfilpPolicy { Implicit, Never, Unlabeled, FuncSig }; |
| 141 | |
| 142 | // For -z zicfiss= |
| 143 | enum class ZicfissPolicy { Implicit, Never, Always }; |
| 144 | |
| 145 | // For some options that resemble -z bti-report={none,warning,error} |
| 146 | enum 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. |
| 151 | struct 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 | |
| 165 | struct SymbolVersion { |
| 166 | llvm::StringRef name; |
| 167 | bool isExternCpp; |
| 168 | bool hasWildcard; |
| 169 | }; |
| 170 | |
| 171 | // This struct contains symbols version definition that |
| 172 | // can be found in version script if it is used for link. |
| 173 | struct VersionDefinition { |
| 174 | llvm::StringRef name; |
| 175 | uint16_t id; |
| 176 | SmallVector<SymbolVersion, 0> nonLocalPatterns; |
| 177 | SmallVector<SymbolVersion, 0> localPatterns; |
| 178 | }; |
| 179 | |
| 180 | class LinkerDriver { |
| 181 | public: |
| 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 | |
| 188 | private: |
| 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 | |
| 205 | public: |
| 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 options |
| 215 | // and such fields have the same name as the corresponding options. |
| 216 | // Most fields are initialized by the ctx.driver. |
| 217 | struct Config { |
| 218 | uint8_t osabi = 0; |
| 219 | uint32_t andFeatures = 0; |
| 220 | llvm::CachePruningPolicy thinLTOCachePolicy; |
| 221 | llvm::SetVector<llvm::CachedHashString> dependencyFiles; // for --dependency-file |
| 222 | 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 ; |
| 240 | std::optional<uint64_t> = 0; |
| 241 | llvm::StringRef ; |
| 242 | llvm::StringRef ; |
| 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 ; |
| 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> dtltoCompilerArgs; |
| 282 | llvm::SmallVector<llvm::StringRef, 0> undefined; |
| 283 | llvm::SmallVector<SymbolVersion, 0> dynamicList; |
| 284 | llvm::SmallVector<uint8_t, 0> buildIdVector; |
| 285 | llvm::SmallVector<llvm::StringRef, 0> mllvmOpts; |
| 286 | llvm::MapVector<std::pair<const InputSectionBase *, const InputSectionBase *>, |
| 287 | uint64_t> |
| 288 | callGraphProfile; |
| 289 | bool cmseImplib = false; |
| 290 | bool allowMultipleDefinition; |
| 291 | bool fatLTOObjects; |
| 292 | bool androidPackDynRelocs = false; |
| 293 | bool armHasArmISA = false; |
| 294 | bool armHasThumb2ISA = false; |
| 295 | bool armHasBlx = false; |
| 296 | bool armHasMovtMovw = false; |
| 297 | bool armJ1J2BranchEncoding = false; |
| 298 | bool armCMSESupport = false; |
| 299 | bool asNeeded = false; |
| 300 | bool armBe8 = false; |
| 301 | BsymbolicKind bsymbolic = BsymbolicKind::None; |
| 302 | CGProfileSortKind callGraphProfileSort; |
| 303 | llvm::StringRef irpgoProfilePath; |
| 304 | bool bpStartupFunctionSort = false; |
| 305 | bool bpCompressionSortStartupFunctions = false; |
| 306 | bool bpFunctionOrderForCompression = false; |
| 307 | bool bpDataOrderForCompression = false; |
| 308 | bool bpVerboseSectionOrderer = false; |
| 309 | bool branchToBranch = false; |
| 310 | bool checkSections; |
| 311 | bool checkDynamicRelocs; |
| 312 | std::optional<llvm::DebugCompressionType> compressDebugSections; |
| 313 | llvm::SmallVector< |
| 314 | std::tuple<llvm::GlobPattern, llvm::DebugCompressionType, unsigned>, 0> |
| 315 | compressSections; |
| 316 | bool cref; |
| 317 | llvm::SmallVector<std::pair<llvm::GlobPattern, uint64_t>, 0> |
| 318 | deadRelocInNonAlloc; |
| 319 | bool debugNames; |
| 320 | bool demangle = true; |
| 321 | bool dependentLibraries; |
| 322 | bool disableVerify; |
| 323 | bool ehFrameHdr; |
| 324 | bool emitLLVM; |
| 325 | bool emitRelocs; |
| 326 | bool enableNewDtags; |
| 327 | bool enableNonContiguousRegions; |
| 328 | bool executeOnly; |
| 329 | bool exportDynamic; |
| 330 | bool fixCortexA53Errata843419; |
| 331 | bool fixCortexA8; |
| 332 | bool formatBinary = false; |
| 333 | bool fortranCommon; |
| 334 | bool gcSections; |
| 335 | bool gdbIndex; |
| 336 | bool gnuHash = false; |
| 337 | bool gnuUnique; |
| 338 | bool ignoreDataAddressEquality; |
| 339 | bool ignoreFunctionAddressEquality; |
| 340 | bool ltoCSProfileGenerate; |
| 341 | bool ltoPGOWarnMismatch; |
| 342 | bool ltoDebugPassManager; |
| 343 | bool ltoEmitAsm; |
| 344 | bool ltoUniqueBasicBlockSectionNames; |
| 345 | bool ltoValidateAllVtablesHaveTypeInfos; |
| 346 | bool ltoWholeProgramVisibility; |
| 347 | bool mergeArmExidx; |
| 348 | bool mipsN32Abi = false; |
| 349 | bool mmapOutputFile; |
| 350 | bool nmagic; |
| 351 | bool noinhibitExec; |
| 352 | bool nostdlib; |
| 353 | bool oFormatBinary; |
| 354 | bool omagic; |
| 355 | bool optEB = false; |
| 356 | bool optEL = false; |
| 357 | bool optimizeBBJumps; |
| 358 | bool ; |
| 359 | bool picThunk; |
| 360 | bool pie; |
| 361 | bool printGcSections; |
| 362 | bool printIcfSections; |
| 363 | bool printMemoryUsage; |
| 364 | std::optional<uint64_t> randomizeSectionPadding; |
| 365 | bool rejectMismatch; |
| 366 | bool relax; |
| 367 | bool relaxGP; |
| 368 | bool relocatable; |
| 369 | bool resolveGroups; |
| 370 | bool relrGlibc = false; |
| 371 | bool relrPackDynRelocs = false; |
| 372 | llvm::DenseSet<llvm::StringRef> saveTempsArgs; |
| 373 | llvm::SmallVector<std::pair<llvm::GlobPattern, uint32_t>, 0> shuffleSections; |
| 374 | bool singleRoRx; |
| 375 | bool singleXoRx; |
| 376 | bool shared; |
| 377 | bool symbolic; |
| 378 | bool isStatic = false; |
| 379 | bool sysvHash = false; |
| 380 | bool target1Rel; |
| 381 | bool trace; |
| 382 | bool thinLTOEmitImportsFiles; |
| 383 | bool thinLTOEmitIndexFiles; |
| 384 | bool thinLTOIndexOnly; |
| 385 | bool timeTraceEnabled; |
| 386 | bool tocOptimize; |
| 387 | bool pcRelOptimize; |
| 388 | bool undefinedVersion; |
| 389 | bool unique; |
| 390 | bool useAndroidRelrTags = false; |
| 391 | bool warnBackrefs; |
| 392 | llvm::SmallVector<llvm::GlobPattern, 0> warnBackrefsExclude; |
| 393 | bool warnCommon; |
| 394 | bool warnMissingEntry; |
| 395 | bool warnSymbolOrdering; |
| 396 | bool writeAddends; |
| 397 | bool zCombreloc; |
| 398 | bool zCopyreloc; |
| 399 | bool zDynamicUndefined; |
| 400 | bool zForceBti; |
| 401 | bool zForceIbt; |
| 402 | bool zGlobal; |
| 403 | bool zHazardplt; |
| 404 | bool zIfuncNoplt; |
| 405 | bool zInitfirst; |
| 406 | bool zInterpose; |
| 407 | bool zKeepTextSectionPrefix; |
| 408 | bool zLrodataAfterBss; |
| 409 | bool zNoBtCfi; |
| 410 | bool zNodefaultlib; |
| 411 | bool zNodelete; |
| 412 | bool zNodlopen; |
| 413 | bool zNow; |
| 414 | bool zOrigin; |
| 415 | bool zPacPlt; |
| 416 | bool zRelro; |
| 417 | bool zRodynamic; |
| 418 | bool ; |
| 419 | bool zShstk; |
| 420 | bool zStartStopGC; |
| 421 | uint8_t zStartStopVisibility; |
| 422 | bool zText; |
| 423 | bool zRetpolineplt; |
| 424 | bool zWxneeded; |
| 425 | ZicfilpPolicy zZicfilp; |
| 426 | ZicfissPolicy zZicfiss; |
| 427 | DiscardPolicy discard; |
| 428 | GnuStackKind zGnustack; |
| 429 | ICFLevel icf; |
| 430 | OrphanHandlingPolicy orphanHandling; |
| 431 | SortSectionPolicy sortSection; |
| 432 | StripPolicy strip; |
| 433 | UnresolvedPolicy unresolvedSymbols; |
| 434 | UnresolvedPolicy unresolvedSymbolsInShlib; |
| 435 | Target2Policy target2; |
| 436 | GcsPolicy zGcs; |
| 437 | bool power10Stubs; |
| 438 | ARMVFPArgKind armVFPArgs = ARMVFPArgKind::Default; |
| 439 | BuildIdKind buildId = BuildIdKind::None; |
| 440 | SeparateSegmentKind zSeparate; |
| 441 | ELFKind ekind = ELFNoneKind; |
| 442 | uint16_t emachine = llvm::ELF::EM_NONE; |
| 443 | std::optional<uint64_t> imageBase; |
| 444 | uint64_t commonPageSize; |
| 445 | uint64_t maxPageSize; |
| 446 | uint64_t mipsGotSize; |
| 447 | uint64_t zStackSize; |
| 448 | unsigned ltoPartitions; |
| 449 | unsigned ltoo; |
| 450 | llvm::CodeGenOptLevel ltoCgo; |
| 451 | unsigned optimize; |
| 452 | StringRef thinLTOJobs; |
| 453 | unsigned timeTraceGranularity; |
| 454 | int32_t splitStackAdjustSize; |
| 455 | SmallVector<uint8_t, 0> packageMetadata; |
| 456 | |
| 457 | // The following config options do not directly correspond to any |
| 458 | // particular command line options. |
| 459 | |
| 460 | // True if we need to pass through relocations in input files to the |
| 461 | // output file. Usually false because we consume relocations. |
| 462 | bool copyRelocs; |
| 463 | |
| 464 | // True if the target is ELF64. False if ELF32. |
| 465 | bool is64; |
| 466 | |
| 467 | // True if the target is little-endian. False if big-endian. |
| 468 | bool isLE; |
| 469 | |
| 470 | // endianness::little if isLE is true. endianness::big otherwise. |
| 471 | llvm::endianness endianness; |
| 472 | |
| 473 | // True if the target is the little-endian MIPS64. |
| 474 | // |
| 475 | // The reason why we have this variable only for the MIPS is because |
| 476 | // we use this often. Some ELF headers for MIPS64EL are in a |
| 477 | // mixed-endian (which is horrible and I'd say that's a serious spec |
| 478 | // bug), and we need to know whether we are reading MIPS ELF files or |
| 479 | // not in various places. |
| 480 | // |
| 481 | // (Note that MIPS64EL is not a typo for MIPS64LE. This is the official |
| 482 | // name whatever that means. A fun hypothesis is that "EL" is short for |
| 483 | // little-endian written in the little-endian order, but I don't know |
| 484 | // if that's true.) |
| 485 | bool isMips64EL; |
| 486 | |
| 487 | // True if we need to set the DF_STATIC_TLS flag to an output file, which |
| 488 | // works as a hint to the dynamic loader that the shared object contains code |
| 489 | // compiled with the initial-exec TLS model. |
| 490 | bool hasTlsIe = false; |
| 491 | |
| 492 | // Holds set of ELF header flags for the target. |
| 493 | uint32_t eflags = 0; |
| 494 | |
| 495 | // The ELF spec defines two types of relocation table entries, RELA and |
| 496 | // REL. RELA is a triplet of (offset, info, addend) while REL is a |
| 497 | // tuple of (offset, info). Addends for REL are implicit and read from |
| 498 | // the location where the relocations are applied. So, REL is more |
| 499 | // compact than RELA but requires a bit of more work to process. |
| 500 | // |
| 501 | // (From the linker writer's view, this distinction is not necessary. |
| 502 | // If the ELF had chosen whichever and sticked with it, it would have |
| 503 | // been easier to write code to process relocations, but it's too late |
| 504 | // to change the spec.) |
| 505 | // |
| 506 | // Each ABI defines its relocation type. IsRela is true if target |
| 507 | // uses RELA. As far as we know, all 64-bit ABIs are using RELA. A |
| 508 | // few 32-bit ABIs are using RELA too. |
| 509 | bool isRela; |
| 510 | |
| 511 | // True if we are creating position-independent code. |
| 512 | bool isPic; |
| 513 | |
| 514 | // 4 for ELF32, 8 for ELF64. |
| 515 | int wordsize; |
| 516 | |
| 517 | // Mode of MTE to write to the ELF note. Should be one of NT_MEMTAG_ASYNC (for |
| 518 | // async), NT_MEMTAG_SYNC (for sync), or NT_MEMTAG_LEVEL_NONE (for none). If |
| 519 | // async or sync is enabled, write the ELF note specifying the default MTE |
| 520 | // mode. |
| 521 | int androidMemtagMode; |
| 522 | // Signal to the dynamic loader to enable heap MTE. |
| 523 | bool androidMemtagHeap; |
| 524 | // Signal to the dynamic loader that this binary expects stack MTE. Generally, |
| 525 | // this means to map the primary and thread stacks as PROT_MTE. Note: This is |
| 526 | // not supported on Android 11 & 12. |
| 527 | bool androidMemtagStack; |
| 528 | |
| 529 | // When using a unified pre-link LTO pipeline, specify the backend LTO mode. |
| 530 | LtoKind ltoKind = LtoKind::Default; |
| 531 | |
| 532 | unsigned threadCount; |
| 533 | |
| 534 | // If an input file equals a key, remap it to the value. |
| 535 | llvm::DenseMap<llvm::StringRef, llvm::StringRef> remapInputs; |
| 536 | // If an input file matches a wildcard pattern, remap it to the value. |
| 537 | llvm::SmallVector<std::pair<llvm::GlobPattern, llvm::StringRef>, 0> |
| 538 | remapInputsWildcards; |
| 539 | }; |
| 540 | |
| 541 | // Some index properties of a symbol are stored separately in this auxiliary |
| 542 | // struct to decrease sizeof(SymbolUnion) in the majority of cases. |
| 543 | struct SymbolAux { |
| 544 | uint32_t gotIdx = -1; |
| 545 | uint32_t pltIdx = -1; |
| 546 | uint32_t tlsDescIdx = -1; |
| 547 | uint32_t tlsGdIdx = -1; |
| 548 | }; |
| 549 | |
| 550 | struct DuplicateSymbol { |
| 551 | const Symbol *sym; |
| 552 | const InputFile *file; |
| 553 | InputSectionBase *section; |
| 554 | uint64_t value; |
| 555 | }; |
| 556 | |
| 557 | struct UndefinedDiag { |
| 558 | Undefined *sym; |
| 559 | struct Loc { |
| 560 | InputSectionBase *sec; |
| 561 | uint64_t offset; |
| 562 | }; |
| 563 | SmallVector<Loc, 0> locs; |
| 564 | bool isWarning; |
| 565 | }; |
| 566 | |
| 567 | // Linker generated sections which can be used as inputs and are not specific to |
| 568 | // a partition. |
| 569 | struct InStruct { |
| 570 | std::unique_ptr<InputSection> attributes; |
| 571 | std::unique_ptr<SyntheticSection> riscvAttributes; |
| 572 | std::unique_ptr<BssSection> bss; |
| 573 | std::unique_ptr<BssSection> bssRelRo; |
| 574 | std::unique_ptr<SyntheticSection> gnuProperty; |
| 575 | std::unique_ptr<SyntheticSection> gnuStack; |
| 576 | std::unique_ptr<GotSection> got; |
| 577 | std::unique_ptr<GotPltSection> gotPlt; |
| 578 | std::unique_ptr<IgotPltSection> igotPlt; |
| 579 | std::unique_ptr<RelroPaddingSection> relroPadding; |
| 580 | std::unique_ptr<SyntheticSection> armCmseSGSection; |
| 581 | std::unique_ptr<PPC64LongBranchTargetSection> ppc64LongBranchTarget; |
| 582 | std::unique_ptr<SyntheticSection> mipsAbiFlags; |
| 583 | std::unique_ptr<MipsGotSection> mipsGot; |
| 584 | std::unique_ptr<SyntheticSection> mipsOptions; |
| 585 | std::unique_ptr<SyntheticSection> mipsReginfo; |
| 586 | std::unique_ptr<MipsRldMapSection> mipsRldMap; |
| 587 | std::unique_ptr<SyntheticSection> partEnd; |
| 588 | std::unique_ptr<SyntheticSection> partIndex; |
| 589 | std::unique_ptr<PltSection> plt; |
| 590 | std::unique_ptr<IpltSection> iplt; |
| 591 | std::unique_ptr<PPC32Got2Section> ppc32Got2; |
| 592 | std::unique_ptr<IBTPltSection> ibtPlt; |
| 593 | std::unique_ptr<RelocationBaseSection> relaPlt; |
| 594 | // Non-SHF_ALLOC sections |
| 595 | std::unique_ptr<SyntheticSection> debugNames; |
| 596 | std::unique_ptr<GdbIndexSection> gdbIndex; |
| 597 | std::unique_ptr<StringTableSection> shStrTab; |
| 598 | std::unique_ptr<StringTableSection> strTab; |
| 599 | std::unique_ptr<SymbolTableBaseSection> symTab; |
| 600 | std::unique_ptr<SymtabShndxSection> symTabShndx; |
| 601 | }; |
| 602 | |
| 603 | struct Ctx : CommonLinkerContext { |
| 604 | Config arg; |
| 605 | LinkerDriver driver; |
| 606 | LinkerScript *script; |
| 607 | std::unique_ptr<TargetInfo> target; |
| 608 | |
| 609 | // These variables are initialized by Writer and should not be used before |
| 610 | // Writer is initialized. |
| 611 | uint8_t *bufferStart = nullptr; |
| 612 | Partition *mainPart = nullptr; |
| 613 | PhdrEntry *tlsPhdr = nullptr; |
| 614 | struct OutSections { |
| 615 | std::unique_ptr<OutputSection> ; |
| 616 | std::unique_ptr<OutputSection> ; |
| 617 | OutputSection *preinitArray = nullptr; |
| 618 | OutputSection *initArray = nullptr; |
| 619 | OutputSection *finiArray = nullptr; |
| 620 | }; |
| 621 | OutSections out; |
| 622 | SmallVector<OutputSection *, 0> outputSections; |
| 623 | std::vector<Partition> partitions; |
| 624 | |
| 625 | InStruct in; |
| 626 | |
| 627 | // Some linker-generated symbols need to be created as |
| 628 | // Defined symbols. |
| 629 | struct ElfSym { |
| 630 | // __bss_start |
| 631 | Defined *bss; |
| 632 | |
| 633 | // etext and _etext |
| 634 | Defined *etext1; |
| 635 | Defined *etext2; |
| 636 | |
| 637 | // edata and _edata |
| 638 | Defined *edata1; |
| 639 | Defined *edata2; |
| 640 | |
| 641 | // end and _end |
| 642 | Defined *end1; |
| 643 | Defined *end2; |
| 644 | |
| 645 | // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to |
| 646 | // be at some offset from the base of the .got section, usually 0 or |
| 647 | // the end of the .got. |
| 648 | Defined *globalOffsetTable; |
| 649 | |
| 650 | // _gp, _gp_disp and __gnu_local_gp symbols. Only for MIPS. |
| 651 | Defined *mipsGp; |
| 652 | Defined *mipsGpDisp; |
| 653 | Defined *mipsLocalGp; |
| 654 | |
| 655 | // __global_pointer$ for RISC-V. |
| 656 | Defined *riscvGlobalPointer; |
| 657 | |
| 658 | // __rel{,a}_iplt_{start,end} symbols. |
| 659 | Defined *relaIpltStart; |
| 660 | Defined *relaIpltEnd; |
| 661 | |
| 662 | // _TLS_MODULE_BASE_ on targets that support TLSDESC. |
| 663 | Defined *tlsModuleBase; |
| 664 | }; |
| 665 | ElfSym sym{}; |
| 666 | std::unique_ptr<SymbolTable> symtab; |
| 667 | SmallVector<Symbol *, 0> synthesizedSymbols; |
| 668 | |
| 669 | SmallVector<std::unique_ptr<MemoryBuffer>> memoryBuffers; |
| 670 | SmallVector<ELFFileBase *, 0> objectFiles; |
| 671 | SmallVector<SharedFile *, 0> sharedFiles; |
| 672 | SmallVector<BinaryFile *, 0> binaryFiles; |
| 673 | SmallVector<BitcodeFile *, 0> bitcodeFiles; |
| 674 | SmallVector<BitcodeFile *, 0> lazyBitcodeFiles; |
| 675 | SmallVector<InputSectionBase *, 0> inputSections; |
| 676 | SmallVector<EhInputSection *, 0> ehInputSections; |
| 677 | |
| 678 | SmallVector<SymbolAux, 0> symAux; |
| 679 | // Duplicate symbol candidates. |
| 680 | SmallVector<DuplicateSymbol, 0> duplicates; |
| 681 | // Undefined diagnostics are collected in a vector and emitted once all of |
| 682 | // them are known, so that some postprocessing on the list of undefined |
| 683 | // symbols can happen before lld emits diagnostics. |
| 684 | std::mutex relocMutex; |
| 685 | SmallVector<UndefinedDiag, 0> undefErrs; |
| 686 | // Symbols in a non-prevailing COMDAT group which should be changed to an |
| 687 | // Undefined. |
| 688 | SmallVector<std::pair<Symbol *, unsigned>, 0> nonPrevailingSyms; |
| 689 | // A tuple of (reference, extractedFile, sym). Used by --why-extract=. |
| 690 | SmallVector<std::tuple<std::string, const InputFile *, const Symbol &>, 0> |
| 691 | ; |
| 692 | // A mapping from a symbol to an InputFile referencing it backward. Used by |
| 693 | // --warn-backrefs. |
| 694 | llvm::DenseMap<const Symbol *, |
| 695 | std::pair<const InputFile *, const InputFile *>> |
| 696 | backwardReferences; |
| 697 | llvm::SmallSet<llvm::StringRef, 0> auxiliaryFiles; |
| 698 | // If --reproduce is specified, all input files are written to this tar |
| 699 | // archive. |
| 700 | std::unique_ptr<llvm::TarWriter> tar; |
| 701 | // InputFile for linker created symbols with no source location. |
| 702 | InputFile *internalFile = nullptr; |
| 703 | // True if symbols can be exported (isExported) or preemptible. |
| 704 | bool hasDynsym = false; |
| 705 | // True if SHT_LLVM_SYMPART is used. |
| 706 | std::atomic<bool> hasSympart{false}; |
| 707 | // True if there are TLS IE relocations. Set DF_STATIC_TLS if -shared. |
| 708 | std::atomic<bool> hasTlsIe{false}; |
| 709 | // True if we need to reserve two .got entries for local-dynamic TLS model. |
| 710 | std::atomic<bool> needsTlsLd{false}; |
| 711 | // True if all native vtable symbols have corresponding type info symbols |
| 712 | // during LTO. |
| 713 | bool ltoAllVtablesHaveTypeInfos = false; |
| 714 | // Number of Vernaux entries (needed shared object names). |
| 715 | uint32_t vernauxNum = 0; |
| 716 | |
| 717 | // Each symbol assignment and DEFINED(sym) reference is assigned an increasing |
| 718 | // order. Each DEFINED(sym) evaluation checks whether the reference happens |
| 719 | // before a possible `sym = expr;`. |
| 720 | unsigned scriptSymOrderCounter = 1; |
| 721 | llvm::DenseMap<const Symbol *, unsigned> scriptSymOrder; |
| 722 | |
| 723 | // The set of TOC entries (.toc + addend) for which we should not apply |
| 724 | // toc-indirect to toc-relative relaxation. const Symbol * refers to the |
| 725 | // STT_SECTION symbol associated to the .toc input section. |
| 726 | llvm::DenseSet<std::pair<const Symbol *, uint64_t>> ppc64noTocRelax; |
| 727 | |
| 728 | Ctx(); |
| 729 | |
| 730 | llvm::raw_fd_ostream openAuxiliaryFile(llvm::StringRef, std::error_code &); |
| 731 | |
| 732 | std::optional<AArch64PauthAbiCoreInfo> aarch64PauthAbiCoreInfo; |
| 733 | }; |
| 734 | |
| 735 | // The first two elements of versionDefinitions represent VER_NDX_LOCAL and |
| 736 | // VER_NDX_GLOBAL. This helper returns other elements. |
| 737 | static inline ArrayRef<VersionDefinition> namedVersionDefs(Ctx &ctx) { |
| 738 | return llvm::ArrayRef(ctx.arg.versionDefinitions).slice(N: 2); |
| 739 | } |
| 740 | |
| 741 | struct ELFSyncStream : SyncStream { |
| 742 | Ctx &ctx; |
| 743 | ELFSyncStream(Ctx &ctx, DiagLevel level) |
| 744 | : SyncStream(ctx.e, level), ctx(ctx) {} |
| 745 | }; |
| 746 | |
| 747 | template <typename T> |
| 748 | std::enable_if_t<!std::is_pointer_v<std::remove_reference_t<T>>, |
| 749 | const ELFSyncStream &> |
| 750 | operator<<(const ELFSyncStream &s, T &&v) { |
| 751 | s.os << std::forward<T>(v); |
| 752 | return s; |
| 753 | } |
| 754 | |
| 755 | inline const ELFSyncStream &operator<<(const ELFSyncStream &s, const char *v) { |
| 756 | s.os << v; |
| 757 | return s; |
| 758 | } |
| 759 | |
| 760 | inline const ELFSyncStream &operator<<(const ELFSyncStream &s, Error v) { |
| 761 | s.os << llvm::toString(E: std::move(v)); |
| 762 | return s; |
| 763 | } |
| 764 | |
| 765 | // Report a log if --verbose is specified. |
| 766 | ELFSyncStream Log(Ctx &ctx); |
| 767 | |
| 768 | // Print a message to stdout. |
| 769 | ELFSyncStream Msg(Ctx &ctx); |
| 770 | |
| 771 | // Report a warning. Upgraded to an error if --fatal-warnings is specified. |
| 772 | ELFSyncStream Warn(Ctx &ctx); |
| 773 | |
| 774 | // Report an error that will suppress the output file generation. Downgraded to |
| 775 | // a warning if --noinhibit-exec is specified. |
| 776 | ELFSyncStream Err(Ctx &ctx); |
| 777 | |
| 778 | // Report an error regardless of --noinhibit-exec. |
| 779 | ELFSyncStream ErrAlways(Ctx &ctx); |
| 780 | |
| 781 | // Report a fatal error that exits immediately. This should generally be avoided |
| 782 | // in favor of Err. |
| 783 | ELFSyncStream Fatal(Ctx &ctx); |
| 784 | |
| 785 | uint64_t errCount(Ctx &ctx); |
| 786 | |
| 787 | ELFSyncStream InternalErr(Ctx &ctx, const uint8_t *buf); |
| 788 | |
| 789 | #define CHECK2(E, S) lld::check2((E), [&] { return toStr(ctx, S); }) |
| 790 | |
| 791 | inline DiagLevel toDiagLevel(ReportPolicy policy) { |
| 792 | if (policy == ReportPolicy::Error) |
| 793 | return DiagLevel::Err; |
| 794 | else if (policy == ReportPolicy::Warning) |
| 795 | return DiagLevel::Warn; |
| 796 | return DiagLevel::None; |
| 797 | } |
| 798 | |
| 799 | } // namespace lld::elf |
| 800 | |
| 801 | #endif |
| 802 | |