184487f11SMichael J. Spencer //===- Driver.cpp ---------------------------------------------------------===//
284487f11SMichael J. Spencer //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
684487f11SMichael J. Spencer //
784487f11SMichael J. Spencer //===----------------------------------------------------------------------===//
8ec29bee7SRui Ueyama //
9ec29bee7SRui Ueyama // The driver drives the entire linking process. It is responsible for
10ec29bee7SRui Ueyama // parsing command line options and doing whatever it is instructed to do.
11ec29bee7SRui Ueyama //
12ec29bee7SRui Ueyama // One notable thing in the LLD's driver when compared to other linkers is
13ec29bee7SRui Ueyama // that the LLD's driver is agnostic on the host operating system.
14ec29bee7SRui Ueyama // Other linkers usually have implicit default values (such as a dynamic
15ec29bee7SRui Ueyama // linker path or library paths) for each host OS.
16ec29bee7SRui Ueyama //
17ec29bee7SRui Ueyama // I don't think implicit default values are useful because they are
18ec29bee7SRui Ueyama // usually explicitly specified by the compiler driver. They can even
19ec29bee7SRui Ueyama // be harmful when you are doing cross-linking. Therefore, in LLD, we
2081cb7107SRui Ueyama // simply trust the compiler driver to pass all required options and
2181cb7107SRui Ueyama // don't try to make effort on our side.
22ec29bee7SRui Ueyama //
23ec29bee7SRui Ueyama //===----------------------------------------------------------------------===//
2484487f11SMichael J. Spencer
25afff74e2SRui Ueyama #include "Driver.h"
26192e1fa5SRafael Espindola #include "Config.h"
270b289529SRui Ueyama #include "ICF.h"
28afff74e2SRui Ueyama #include "InputFiles.h"
29b91bf1a9SRui Ueyama #include "InputSection.h"
30717677afSRui Ueyama #include "LinkerScript.h"
31f187c4d2SSam Clegg #include "MarkLive.h"
32a8dba487SGeorge Rimar #include "OutputSections.h"
332ec34544SRui Ueyama #include "ScriptParser.h"
34afff74e2SRui Ueyama #include "SymbolTable.h"
35d26b52fdSRafael Espindola #include "Symbols.h"
36dc7936ecSPeter Collingbourne #include "SyntheticSections.h"
37ff777685SRui Ueyama #include "Target.h"
3884487f11SMichael J. Spencer #include "Writer.h"
393e03944fSRui Ueyama #include "lld/Common/Args.h"
403f851704SRui Ueyama #include "lld/Common/Driver.h"
41b8a59c8aSBob Haarman #include "lld/Common/ErrorHandler.h"
427fd99fc4SRui Ueyama #include "lld/Common/Filesystem.h"
432017d52bSRui Ueyama #include "lld/Common/Memory.h"
44ee173718SRui Ueyama #include "lld/Common/Strings.h"
459dc740d0SGeorge Rimar #include "lld/Common/TargetOptionsCommandFlags.h"
463f851704SRui Ueyama #include "lld/Common/Version.h"
47de300e66SJames Henderson #include "llvm/ADT/SetVector.h"
482e9eac13SRafael Espindola #include "llvm/ADT/StringExtras.h"
497b14a62dSRui Ueyama #include "llvm/ADT/StringSwitch.h"
50fa602d74SArthur Eubanks #include "llvm/Config/llvm-config.h"
51dd63b9f5SSteven Wu #include "llvm/LTO/LTO.h"
523d854240SFangrui Song #include "llvm/Object/Archive.h"
533acda917SWei Wang #include "llvm/Remarks/HotnessThresholdParser.h"
54cd513a41SPeter Collingbourne #include "llvm/Support/CommandLine.h"
55dbf93397SGeorge Rimar #include "llvm/Support/Compression.h"
5627bb7990SFangrui Song #include "llvm/Support/FileSystem.h"
5743f4b037SRui Ueyama #include "llvm/Support/GlobPattern.h"
58a327a4c3SPeter Collingbourne #include "llvm/Support/LEB128.h"
59932f0276SReid Kleckner #include "llvm/Support/Parallel.h"
607f1f9127SRui Ueyama #include "llvm/Support/Path.h"
61ec1c75e0SRui Ueyama #include "llvm/Support/TarWriter.h"
629f77ef0cSRafael Espindola #include "llvm/Support/TargetSelect.h"
63e7cb3744SRussell Gallop #include "llvm/Support/TimeProfiler.h"
64a4672403SRui Ueyama #include "llvm/Support/raw_ostream.h"
65e160f0d0SDavide Italiano #include <cstdlib>
66cacf967eSRui Ueyama #include <utility>
6784487f11SMichael J. Spencer
6884487f11SMichael J. Spencer using namespace llvm;
691ef7b3ffSDenis Protivensky using namespace llvm::ELF;
703ce825edSRui Ueyama using namespace llvm::object;
71673b6095SRui Ueyama using namespace llvm::sys;
72d19bc048SRui Ueyama using namespace llvm::support;
7307837b8fSFangrui Song using namespace lld;
7407837b8fSFangrui Song using namespace lld::elf;
7584487f11SMichael J. Spencer
765fc4323eSFangrui Song std::unique_ptr<Configuration> elf::config;
777c7702b3SFangrui Song std::unique_ptr<Ctx> elf::ctx;
785fc4323eSFangrui Song std::unique_ptr<LinkerDriver> elf::driver;
79f5c4aca9SRui Ueyama
803837f427SRui Ueyama static void setConfigs(opt::InputArgList &args);
813837f427SRui Ueyama static void readConfigs(opt::InputArgList &args);
82d57e74b7SRui Ueyama
errorOrWarn(const Twine & msg)83d754c0b6SFangrui Song void elf::errorOrWarn(const Twine &msg) {
84d754c0b6SFangrui Song if (config->noinhibitExec)
85d754c0b6SFangrui Song warn(msg);
86d754c0b6SFangrui Song else
87d754c0b6SFangrui Song error(msg);
88d754c0b6SFangrui Song }
89d754c0b6SFangrui Song
link(ArrayRef<const char * > args,llvm::raw_ostream & stdoutOS,llvm::raw_ostream & stderrOS,bool exitEarly,bool disableOutput)9083d59e05SAlexandre Ganea bool elf::link(ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
9183d59e05SAlexandre Ganea llvm::raw_ostream &stderrOS, bool exitEarly,
9283d59e05SAlexandre Ganea bool disableOutput) {
9383d59e05SAlexandre Ganea // This driver-specific context will be freed later by lldMain().
9483d59e05SAlexandre Ganea auto *ctx = new CommonLinkerContext;
95d3fec7fbSJames Y Knight
9683d59e05SAlexandre Ganea ctx->e.initialize(stdoutOS, stderrOS, exitEarly, disableOutput);
9783d59e05SAlexandre Ganea ctx->e.cleanupCallback = []() {
983837f427SRui Ueyama inputSections.clear();
993837f427SRui Ueyama outputSections.clear();
1005d3bd7f3SFangrui Song symAux.clear();
10107320e40SRui Ueyama
1023837f427SRui Ueyama tar = nullptr;
103cb203f3fSFangrui Song in.reset();
1044e247522SRui Ueyama
105cb203f3fSFangrui Song partitions.clear();
106cb203f3fSFangrui Song partitions.emplace_back();
107ba2816beSPeter Collingbourne
1083837f427SRui Ueyama SharedFile::vernauxNum = 0;
109f2efb574SAlexandre Ganea };
11083d59e05SAlexandre Ganea ctx->e.logName = args::getFilenameWithoutExe(args[0]);
11183d59e05SAlexandre Ganea ctx->e.errorLimitExceededMsg = "too many errors emitted, stopping now (use "
11287e6251dSFangrui Song "--error-limit=0 to see all errors)";
113f2efb574SAlexandre Ganea
1145fc4323eSFangrui Song config = std::make_unique<Configuration>();
1157c7702b3SFangrui Song elf::ctx = std::make_unique<Ctx>();
1165fc4323eSFangrui Song driver = std::make_unique<LinkerDriver>();
1175fc4323eSFangrui Song script = std::make_unique<LinkerScript>();
1185fc4323eSFangrui Song symtab = std::make_unique<SymbolTable>();
119f2efb574SAlexandre Ganea
120cb203f3fSFangrui Song partitions.clear();
121cb203f3fSFangrui Song partitions.emplace_back();
122d3e20705SPeter Collingbourne
1233837f427SRui Ueyama config->progName = args[0];
12407320e40SRui Ueyama
125fdd6ed8eSReshabh Sharma driver->linkerMain(args);
1267d1f5fd8SRui Ueyama
12783d59e05SAlexandre Ganea return errorCount() == 0;
12884487f11SMichael J. Spencer }
12984487f11SMichael J. Spencer
1307b14a62dSRui Ueyama // Parses a linker -m option.
parseEmulation(StringRef emul)1313837f427SRui Ueyama static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef emul) {
1323837f427SRui Ueyama uint8_t osabi = 0;
1333837f427SRui Ueyama StringRef s = emul;
1343837f427SRui Ueyama if (s.endswith("_fbsd")) {
1353837f427SRui Ueyama s = s.drop_back(5);
1363837f427SRui Ueyama osabi = ELFOSABI_FREEBSD;
1377cc713adSRafael Espindola }
1387b14a62dSRui Ueyama
1393837f427SRui Ueyama std::pair<ELFKind, uint16_t> ret =
1403837f427SRui Ueyama StringSwitch<std::pair<ELFKind, uint16_t>>(s)
141d82679d8SFangrui Song .Cases("aarch64elf", "aarch64linux", {ELF64LEKind, EM_AARCH64})
1427605a9a0SFangrui Song .Cases("aarch64elfb", "aarch64linuxb", {ELF64BEKind, EM_AARCH64})
143ad270ec3SEugene Leviant .Cases("armelf", "armelf_linux_eabi", {ELF32LEKind, EM_ARM})
1441e52f25dSRui Ueyama .Case("elf32_x86_64", {ELF32LEKind, EM_X86_64})
1458e0c3267SRui Ueyama .Cases("elf32btsmip", "elf32btsmipn32", {ELF32BEKind, EM_MIPS})
1468e0c3267SRui Ueyama .Cases("elf32ltsmip", "elf32ltsmipn32", {ELF32LEKind, EM_MIPS})
1475cd9c6bcSRui Ueyama .Case("elf32lriscv", {ELF32LEKind, EM_RISCV})
1484134143cSRui Ueyama .Cases("elf32ppc", "elf32ppclinux", {ELF32BEKind, EM_PPC})
149275eb828SBrandon Bergren .Cases("elf32lppc", "elf32lppclinux", {ELF32LEKind, EM_PPC})
1507b14a62dSRui Ueyama .Case("elf64btsmip", {ELF64BEKind, EM_MIPS})
1517b14a62dSRui Ueyama .Case("elf64ltsmip", {ELF64LEKind, EM_MIPS})
1525cd9c6bcSRui Ueyama .Case("elf64lriscv", {ELF64LEKind, EM_RISCV})
1537b14a62dSRui Ueyama .Case("elf64ppc", {ELF64BEKind, EM_PPC64})
15417208f1eSFangrui Song .Case("elf64lppc", {ELF64LEKind, EM_PPC64})
155c79ecdd8SRui Ueyama .Cases("elf_amd64", "elf_x86_64", {ELF64LEKind, EM_X86_64})
1567b14a62dSRui Ueyama .Case("elf_i386", {ELF32LEKind, EM_386})
1576c50990dSRui Ueyama .Case("elf_iamcu", {ELF32LEKind, EM_IAMCU})
158aff950e9SLemonBoy .Case("elf64_sparc", {ELF64BEKind, EM_SPARCV9})
15992c6141cSLemonBoy .Case("msp430elf", {ELF32LEKind, EM_MSP430})
1607b14a62dSRui Ueyama .Default({ELFNoneKind, EM_NONE});
1617b14a62dSRui Ueyama
1623837f427SRui Ueyama if (ret.first == ELFNoneKind)
1633837f427SRui Ueyama error("unknown emulation: " + emul);
16492c6141cSLemonBoy if (ret.second == EM_MSP430)
16592c6141cSLemonBoy osabi = ELFOSABI_STANDALONE;
1663837f427SRui Ueyama return std::make_tuple(ret.first, ret.second, osabi);
1671ef7b3ffSDenis Protivensky }
1681ef7b3ffSDenis Protivensky
1699b09369bSRui Ueyama // Returns slices of MB by parsing MB as an archive file.
1709b09369bSRui Ueyama // Each slice consists of a member file in the archive.
getArchiveMembers(MemoryBufferRef mb)1710b1413a8SRafael Espindola std::vector<std::pair<MemoryBufferRef, uint64_t>> static getArchiveMembers(
1723837f427SRui Ueyama MemoryBufferRef mb) {
1733837f427SRui Ueyama std::unique_ptr<Archive> file =
1743837f427SRui Ueyama CHECK(Archive::create(mb),
1753837f427SRui Ueyama mb.getBufferIdentifier() + ": failed to parse archive");
1769b09369bSRui Ueyama
1773837f427SRui Ueyama std::vector<std::pair<MemoryBufferRef, uint64_t>> v;
1783837f427SRui Ueyama Error err = Error::success();
1793837f427SRui Ueyama bool addToTar = file->isThin() && tar;
180681b1be7SFangrui Song for (const Archive::Child &c : file->children(err)) {
1813837f427SRui Ueyama MemoryBufferRef mbref =
1823837f427SRui Ueyama CHECK(c.getMemoryBufferRef(),
1833837f427SRui Ueyama mb.getBufferIdentifier() +
1847d7ff80fSEugene Leviant ": could not get the buffer for a child of the archive");
1853837f427SRui Ueyama if (addToTar)
1863837f427SRui Ueyama tar->append(relativeToRoot(check(c.getFullName())), mbref.getBuffer());
1873837f427SRui Ueyama v.push_back(std::make_pair(mbref, c.getChildOffset()));
1889b09369bSRui Ueyama }
1893837f427SRui Ueyama if (err)
1903837f427SRui Ueyama fatal(mb.getBufferIdentifier() + ": Archive::children failed: " +
1913837f427SRui Ueyama toString(std::move(err)));
192d418b1daSPeter Collingbourne
193d418b1daSPeter Collingbourne // Take ownership of memory buffers created for members of thin archives.
194c0b986aaSFangrui Song std::vector<std::unique_ptr<MemoryBuffer>> mbs = file->takeThinBuffers();
1959a572164SFangrui Song std::move(mbs.begin(), mbs.end(), std::back_inserter(ctx->memoryBuffers));
196d418b1daSPeter Collingbourne
1973837f427SRui Ueyama return v;
1989b09369bSRui Ueyama }
1999b09369bSRui Ueyama
isBitcode(MemoryBufferRef mb)20050f5f37bSFangrui Song static bool isBitcode(MemoryBufferRef mb) {
20150f5f37bSFangrui Song return identify_magic(mb.getBuffer()) == llvm::file_magic::bitcode;
20250f5f37bSFangrui Song }
20350f5f37bSFangrui Song
204b201a20eSRui Ueyama // Opens a file and create a file object. Path has to be resolved already.
addFile(StringRef path,bool withLOption)2053837f427SRui Ueyama void LinkerDriver::addFile(StringRef path, bool withLOption) {
2065002a67eSRui Ueyama using namespace sys::fs;
207034f58a9SDavide Italiano
2083837f427SRui Ueyama Optional<MemoryBufferRef> buffer = readFile(path);
2095413bf1bSKazu Hirata if (!buffer)
21021eecb4fSRui Ueyama return;
2113837f427SRui Ueyama MemoryBufferRef mbref = *buffer;
212983ed2b7SRui Ueyama
2133837f427SRui Ueyama if (config->formatBinary) {
2143837f427SRui Ueyama files.push_back(make<BinaryFile>(mbref));
215a9424f39SMichael J. Spencer return;
216a9424f39SMichael J. Spencer }
217a9424f39SMichael J. Spencer
2183837f427SRui Ueyama switch (identify_magic(mbref.getBuffer())) {
219983ed2b7SRui Ueyama case file_magic::unknown:
2203837f427SRui Ueyama readLinkerScript(mbref);
221983ed2b7SRui Ueyama return;
222fd7deda5SRui Ueyama case file_magic::archive: {
2233837f427SRui Ueyama if (inWholeArchive) {
224242316bcSFangrui Song for (const auto &p : getArchiveMembers(mbref)) {
225242316bcSFangrui Song if (isBitcode(p.first))
226242316bcSFangrui Song files.push_back(make<BitcodeFile>(p.first, path, p.second, false));
227242316bcSFangrui Song else
228242316bcSFangrui Song files.push_back(createObjFile(p.first, path));
229242316bcSFangrui Song }
2303ce825edSRui Ueyama return;
2313ce825edSRui Ueyama }
232fd7deda5SRui Ueyama
2333d854240SFangrui Song auto members = getArchiveMembers(mbref);
2343d854240SFangrui Song archiveFiles.emplace_back(path, members.size());
235fd7deda5SRui Ueyama
2363d854240SFangrui Song // Handle archives and --start-lib/--end-lib using the same code path. This
2373d854240SFangrui Song // scans all the ELF relocatable object files and bitcode files in the
2383d854240SFangrui Song // archive rather than just the index file, with the benefit that the
2393d854240SFangrui Song // symbols are only loaded once. For many projects archives see high
2403d854240SFangrui Song // utilization rates and it is a net performance win. --start-lib scans
2413d854240SFangrui Song // symbols in the same order that llvm-ar adds them to the index, so in the
2423d854240SFangrui Song // common case the semantics are identical. If the archive symbol table was
2433d854240SFangrui Song // created in a different order, or is incomplete, this strategy has
2443d854240SFangrui Song // different semantics. Such output differences are considered user error.
2453d854240SFangrui Song //
24699580e29SFangrui Song // All files within the archive get the same group ID to allow mutual
24799580e29SFangrui Song // references for --warn-backrefs.
24899580e29SFangrui Song bool saved = InputFile::isInGroup;
24999580e29SFangrui Song InputFile::isInGroup = true;
2503d854240SFangrui Song for (const std::pair<MemoryBufferRef, uint64_t> &p : members) {
251d838bf2aSFangrui Song auto magic = identify_magic(p.first.getBuffer());
252242316bcSFangrui Song if (magic == file_magic::elf_relocatable)
253242316bcSFangrui Song files.push_back(createObjFile(p.first, path, true));
254242316bcSFangrui Song else if (magic == file_magic::bitcode)
255242316bcSFangrui Song files.push_back(make<BitcodeFile>(p.first, path, p.second, true));
256d838bf2aSFangrui Song else
2573d854240SFangrui Song warn(path + ": archive member '" + p.first.getBufferIdentifier() +
258d838bf2aSFangrui Song "' is neither ET_REL nor LLVM bitcode");
259d838bf2aSFangrui Song }
26099580e29SFangrui Song InputFile::isInGroup = saved;
26199580e29SFangrui Song if (!saved)
26299580e29SFangrui Song ++InputFile::nextGroupId;
263fd7deda5SRui Ueyama return;
264fd7deda5SRui Ueyama }
265af70764aSRafael Espindola case file_magic::elf_shared_object:
2663837f427SRui Ueyama if (config->isStatic || config->relocatable) {
2673837f427SRui Ueyama error("attempted static link of dynamic object " + path);
26858941ee1SGeorge Rimar return;
26958941ee1SGeorge Rimar }
270d2ccdbfaSRui Ueyama
2714d9f6caeSFangrui Song // Shared objects are identified by soname. soname is (if specified)
2724d9f6caeSFangrui Song // DT_SONAME and falls back to filename. If a file was specified by -lfoo,
2734d9f6caeSFangrui Song // the directory part is ignored. Note that path may be a temporary and
2744d9f6caeSFangrui Song // cannot be stored into SharedFile::soName.
2754d9f6caeSFangrui Song path = mbref.getBufferIdentifier();
2763837f427SRui Ueyama files.push_back(
2773837f427SRui Ueyama make<SharedFile>(mbref, withLOption ? path::filename(path) : path));
278983ed2b7SRui Ueyama return;
279d0de239fSRui Ueyama case file_magic::bitcode:
280242316bcSFangrui Song files.push_back(make<BitcodeFile>(mbref, "", 0, inLib));
281242316bcSFangrui Song break;
282d0de239fSRui Ueyama case file_magic::elf_relocatable:
283242316bcSFangrui Song files.push_back(createObjFile(mbref, "", inLib));
284d0de239fSRui Ueyama break;
285d0de239fSRui Ueyama default:
2863837f427SRui Ueyama error(path + ": unknown file type");
287983ed2b7SRui Ueyama }
288f5c4aca9SRui Ueyama }
289f5c4aca9SRui Ueyama
29021eecb4fSRui Ueyama // Add a given library by searching it from input search paths.
addLibrary(StringRef name)2913837f427SRui Ueyama void LinkerDriver::addLibrary(StringRef name) {
2923837f427SRui Ueyama if (Optional<std::string> path = searchLibrary(name))
2936d0b4274SFangrui Song addFile(saver().save(*path), /*withLOption=*/true);
294bfccefd5SDavide Italiano else
295cfc32267Sserge-sans-paille error("unable to find library -l" + name, ErrorTag::LibNotFound, {name});
29621eecb4fSRui Ueyama }
29721eecb4fSRui Ueyama
2981fc5d488SRui Ueyama // This function is called on startup. We need this for LTO since
2991fc5d488SRui Ueyama // LTO calls LLVM functions to compile bitcode files to native code.
3001fc5d488SRui Ueyama // Technically this can be delayed until we read bitcode files, but
3011fc5d488SRui Ueyama // we don't bother to do lazily because the initialization is fast.
initLLVM()3029dc740d0SGeorge Rimar static void initLLVM() {
3031fc5d488SRui Ueyama InitializeAllTargets();
3041fc5d488SRui Ueyama InitializeAllTargetMCs();
3051fc5d488SRui Ueyama InitializeAllAsmPrinters();
3061fc5d488SRui Ueyama InitializeAllAsmParsers();
3071fc5d488SRui Ueyama }
3081fc5d488SRui Ueyama
309d32c63deSRui Ueyama // Some command line options or some combinations of them are not allowed.
310d32c63deSRui Ueyama // This function checks for such errors.
checkOptions()311d5f65063SSam Clegg static void checkOptions() {
312d32c63deSRui Ueyama // The MIPS ABI as of 2016 does not support the GNU-style symbol lookup
313d32c63deSRui Ueyama // table which is a relatively new feature.
3143837f427SRui Ueyama if (config->emachine == EM_MIPS && config->gnuHash)
3159db06423SRui Ueyama error("the .gnu.hash section is not compatible with the MIPS target");
316d32c63deSRui Ueyama
3173837f427SRui Ueyama if (config->fixCortexA53Errata843419 && config->emachine != EM_AARCH64)
3189db06423SRui Ueyama error("--fix-cortex-a53-843419 is only supported on AArch64 targets");
319732cd8cbSPeter Smith
320ea99ce5eSPeter Smith if (config->fixCortexA8 && config->emachine != EM_ARM)
321ea99ce5eSPeter Smith error("--fix-cortex-a8 is only supported on ARM targets");
322ea99ce5eSPeter Smith
3233837f427SRui Ueyama if (config->tocOptimize && config->emachine != EM_PPC64)
324baef18dfSFangrui Song error("--toc-optimize is only supported on PowerPC64 targets");
3257f3f05e0SSean Fertile
326cddb0dbcSNemanja Ivanovic if (config->pcRelOptimize && config->emachine != EM_PPC64)
327baef18dfSFangrui Song error("--pcrel-optimize is only supported on PowerPC64 targets");
328cddb0dbcSNemanja Ivanovic
3293837f427SRui Ueyama if (config->pie && config->shared)
330786e866fSGeorge Rimar error("-shared and -pie may not be used together");
331786e866fSGeorge Rimar
3323837f427SRui Ueyama if (!config->shared && !config->filterList.empty())
333f525c928SGeorge Rimar error("-F may not be used without -shared");
334f525c928SGeorge Rimar
3353837f427SRui Ueyama if (!config->shared && !config->auxiliaryList.empty())
336cf8247efSRui Ueyama error("-f may not be used without -shared");
337cf8247efSRui Ueyama
3388e5184afSFangrui Song if (config->strip == StripPolicy::All && config->emitRelocs)
3398e5184afSFangrui Song error("--strip-all and --emit-relocs may not be used together");
3408e5184afSFangrui Song
3413837f427SRui Ueyama if (config->zText && config->zIfuncNoplt)
342e041d15fSFangrui Song error("-z text and -z ifunc-noplt may not be used together");
343e041d15fSFangrui Song
3443837f427SRui Ueyama if (config->relocatable) {
3453837f427SRui Ueyama if (config->shared)
34658941ee1SGeorge Rimar error("-r and -shared may not be used together");
3473837f427SRui Ueyama if (config->gdbIndex)
3484a294825SFangrui Song error("-r and --gdb-index may not be used together");
3493837f427SRui Ueyama if (config->icf != ICFLevel::None)
350262b927dSGeorge Rimar error("-r and --icf may not be used together");
3513837f427SRui Ueyama if (config->pie)
352786e866fSGeorge Rimar error("-r and -pie may not be used together");
35354933667SRui Ueyama if (config->exportDynamic)
35454933667SRui Ueyama error("-r and --export-dynamic may not be used together");
355d32c63deSRui Ueyama }
356a932cd40SDavid Bolvansky
3573837f427SRui Ueyama if (config->executeOnly) {
3583837f427SRui Ueyama if (config->emachine != EM_AARCH64)
359bf6e259bSFangrui Song error("--execute-only is only supported on AArch64 targets");
360a932cd40SDavid Bolvansky
3613837f427SRui Ueyama if (config->singleRoRx && !script->hasSectionsCommand)
362bf6e259bSFangrui Song error("--execute-only and --no-rosegment cannot be used together");
363a932cd40SDavid Bolvansky }
3642057f836SRui Ueyama
3657cd429f2SFangrui Song if (config->zRetpolineplt && config->zForceIbt)
3667cd429f2SFangrui Song error("-z force-ibt may not be used with -z retpolineplt");
367e208208aSPeter Smith
3683837f427SRui Ueyama if (config->emachine != EM_AARCH64) {
369105a2700SFangrui Song if (config->zPacPlt)
3705a3a9e99SFangrui Song error("-z pac-plt only supported on AArch64");
371105a2700SFangrui Song if (config->zForceBti)
3725a3a9e99SFangrui Song error("-z force-bti only supported on AArch64");
3732b4e6052SDaniel Kiss if (config->zBtiReport != "none")
3742b4e6052SDaniel Kiss error("-z bti-report only supported on AArch64");
375e208208aSPeter Smith }
3762b4e6052SDaniel Kiss
3772b4e6052SDaniel Kiss if (config->emachine != EM_386 && config->emachine != EM_X86_64 &&
3782b4e6052SDaniel Kiss config->zCetReport != "none")
3792b4e6052SDaniel Kiss error("-z cet-report only supported on X86 and X86_64");
380d1aa97b5SRui Ueyama }
381d32c63deSRui Ueyama
getReproduceOption(opt::InputArgList & args)3823837f427SRui Ueyama static const char *getReproduceOption(opt::InputArgList &args) {
3833837f427SRui Ueyama if (auto *arg = args.getLastArg(OPT_reproduce))
3843837f427SRui Ueyama return arg->getValue();
385e160f0d0SDavide Italiano return getenv("LLD_REPRODUCE");
386e160f0d0SDavide Italiano }
387e160f0d0SDavide Italiano
hasZOption(opt::InputArgList & args,StringRef key)3883837f427SRui Ueyama static bool hasZOption(opt::InputArgList &args, StringRef key) {
3893837f427SRui Ueyama for (auto *arg : args.filtered(OPT_z))
3903837f427SRui Ueyama if (key == arg->getValue())
3911a8fffa2SRui Ueyama return true;
3921a8fffa2SRui Ueyama return false;
3931a8fffa2SRui Ueyama }
3941a8fffa2SRui Ueyama
getZFlag(opt::InputArgList & args,StringRef k1,StringRef k2,bool Default)3953837f427SRui Ueyama static bool getZFlag(opt::InputArgList &args, StringRef k1, StringRef k2,
39688fe5c95SRui Ueyama bool Default) {
3973837f427SRui Ueyama for (auto *arg : args.filtered_reverse(OPT_z)) {
3983837f427SRui Ueyama if (k1 == arg->getValue())
39988fe5c95SRui Ueyama return true;
4003837f427SRui Ueyama if (k2 == arg->getValue())
40188fe5c95SRui Ueyama return false;
40288fe5c95SRui Ueyama }
40388fe5c95SRui Ueyama return Default;
40488fe5c95SRui Ueyama }
40588fe5c95SRui Ueyama
getZSeparate(opt::InputArgList & args)40602649506SFangrui Song static SeparateSegmentKind getZSeparate(opt::InputArgList &args) {
40702649506SFangrui Song for (auto *arg : args.filtered_reverse(OPT_z)) {
40802649506SFangrui Song StringRef v = arg->getValue();
40902649506SFangrui Song if (v == "noseparate-code")
41002649506SFangrui Song return SeparateSegmentKind::None;
41102649506SFangrui Song if (v == "separate-code")
41202649506SFangrui Song return SeparateSegmentKind::Code;
41302649506SFangrui Song if (v == "separate-loadable-segments")
41402649506SFangrui Song return SeparateSegmentKind::Loadable;
41502649506SFangrui Song }
41602649506SFangrui Song return SeparateSegmentKind::None;
41702649506SFangrui Song }
41802649506SFangrui Song
getZGnuStack(opt::InputArgList & args)4192a0fcae3SMichał Górny static GnuStackKind getZGnuStack(opt::InputArgList &args) {
4202a0fcae3SMichał Górny for (auto *arg : args.filtered_reverse(OPT_z)) {
4212a0fcae3SMichał Górny if (StringRef("execstack") == arg->getValue())
4222a0fcae3SMichał Górny return GnuStackKind::Exec;
4232a0fcae3SMichał Górny if (StringRef("noexecstack") == arg->getValue())
4242a0fcae3SMichał Górny return GnuStackKind::NoExec;
4252a0fcae3SMichał Górny if (StringRef("nognustack") == arg->getValue())
4262a0fcae3SMichał Górny return GnuStackKind::None;
4272a0fcae3SMichał Górny }
4282a0fcae3SMichał Górny
4292a0fcae3SMichał Górny return GnuStackKind::NoExec;
4302a0fcae3SMichał Górny }
4312a0fcae3SMichał Górny
getZStartStopVisibility(opt::InputArgList & args)432fffd05d5SPetr Hosek static uint8_t getZStartStopVisibility(opt::InputArgList &args) {
433fffd05d5SPetr Hosek for (auto *arg : args.filtered_reverse(OPT_z)) {
434fffd05d5SPetr Hosek std::pair<StringRef, StringRef> kv = StringRef(arg->getValue()).split('=');
435fffd05d5SPetr Hosek if (kv.first == "start-stop-visibility") {
436fffd05d5SPetr Hosek if (kv.second == "default")
437fffd05d5SPetr Hosek return STV_DEFAULT;
438fffd05d5SPetr Hosek else if (kv.second == "internal")
439fffd05d5SPetr Hosek return STV_INTERNAL;
440fffd05d5SPetr Hosek else if (kv.second == "hidden")
441fffd05d5SPetr Hosek return STV_HIDDEN;
442fffd05d5SPetr Hosek else if (kv.second == "protected")
443fffd05d5SPetr Hosek return STV_PROTECTED;
444fffd05d5SPetr Hosek error("unknown -z start-stop-visibility= value: " + StringRef(kv.second));
445fffd05d5SPetr Hosek }
446fffd05d5SPetr Hosek }
447fffd05d5SPetr Hosek return STV_PROTECTED;
448fffd05d5SPetr Hosek }
449fffd05d5SPetr Hosek
45087034ad2SFangrui Song constexpr const char *knownZFlags[] = {
45187034ad2SFangrui Song "combreloc",
45287034ad2SFangrui Song "copyreloc",
45387034ad2SFangrui Song "defs",
45487034ad2SFangrui Song "execstack",
45587034ad2SFangrui Song "force-bti",
45687034ad2SFangrui Song "force-ibt",
45787034ad2SFangrui Song "global",
45887034ad2SFangrui Song "hazardplt",
45987034ad2SFangrui Song "ifunc-noplt",
46087034ad2SFangrui Song "initfirst",
46187034ad2SFangrui Song "interpose",
46287034ad2SFangrui Song "keep-text-section-prefix",
46387034ad2SFangrui Song "lazy",
46487034ad2SFangrui Song "muldefs",
46587034ad2SFangrui Song "nocombreloc",
46687034ad2SFangrui Song "nocopyreloc",
46787034ad2SFangrui Song "nodefaultlib",
46887034ad2SFangrui Song "nodelete",
46987034ad2SFangrui Song "nodlopen",
47087034ad2SFangrui Song "noexecstack",
47187034ad2SFangrui Song "nognustack",
47287034ad2SFangrui Song "nokeep-text-section-prefix",
4734a8de283SFangrui Song "nopack-relative-relocs",
47487034ad2SFangrui Song "norelro",
47587034ad2SFangrui Song "noseparate-code",
47687034ad2SFangrui Song "nostart-stop-gc",
47787034ad2SFangrui Song "notext",
47887034ad2SFangrui Song "now",
47987034ad2SFangrui Song "origin",
48087034ad2SFangrui Song "pac-plt",
4814a8de283SFangrui Song "pack-relative-relocs",
48287034ad2SFangrui Song "rel",
48387034ad2SFangrui Song "rela",
48487034ad2SFangrui Song "relro",
48587034ad2SFangrui Song "retpolineplt",
48687034ad2SFangrui Song "rodynamic",
48787034ad2SFangrui Song "separate-code",
48887034ad2SFangrui Song "separate-loadable-segments",
48987034ad2SFangrui Song "shstk",
49087034ad2SFangrui Song "start-stop-gc",
49187034ad2SFangrui Song "text",
49287034ad2SFangrui Song "undefs",
49387034ad2SFangrui Song "wxneeded",
49487034ad2SFangrui Song };
49587034ad2SFangrui Song
isKnownZFlag(StringRef s)4963837f427SRui Ueyama static bool isKnownZFlag(StringRef s) {
49787034ad2SFangrui Song return llvm::is_contained(knownZFlags, s) ||
49887034ad2SFangrui Song s.startswith("common-page-size=") || s.startswith("bti-report=") ||
49987034ad2SFangrui Song s.startswith("cet-report=") ||
5004ce56b81SFangrui Song s.startswith("dead-reloc-in-nonalloc=") ||
501fffd05d5SPetr Hosek s.startswith("max-page-size=") || s.startswith("stack-size=") ||
502fffd05d5SPetr Hosek s.startswith("start-stop-visibility=");
5032fa0604bSRui Ueyama }
5042fa0604bSRui Ueyama
5058c3641d0SFangrui Song // Report a warning for an unknown -z option.
checkZOptions(opt::InputArgList & args)5063837f427SRui Ueyama static void checkZOptions(opt::InputArgList &args) {
5073837f427SRui Ueyama for (auto *arg : args.filtered(OPT_z))
5083837f427SRui Ueyama if (!isKnownZFlag(arg->getValue()))
5098c3641d0SFangrui Song warn("unknown -z value: " + StringRef(arg->getValue()));
5102fa0604bSRui Ueyama }
5112fa0604bSRui Ueyama
51265001f57SJin Xin Ng constexpr const char *saveTempsValues[] = {
51365001f57SJin Xin Ng "resolution", "preopt", "promote", "internalize", "import",
51465001f57SJin Xin Ng "opt", "precodegen", "prelink", "combinedindex"};
51565001f57SJin Xin Ng
linkerMain(ArrayRef<const char * > argsArr)516fdd6ed8eSReshabh Sharma void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
5173837f427SRui Ueyama ELFOptTable parser;
5183837f427SRui Ueyama opt::InputArgList args = parser.parse(argsArr.slice(1));
51972b1ee25SRui Ueyama
520faab70b7SSam Clegg // Interpret these flags early because error()/warn() depend on them.
521136d27abSRui Ueyama errorHandler().errorLimit = args::getInteger(args, OPT_error_limit, 20);
5228c3641d0SFangrui Song errorHandler().fatalWarnings =
5238c3641d0SFangrui Song args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false);
5243837f427SRui Ueyama checkZOptions(args);
52572b1ee25SRui Ueyama
52672b1ee25SRui Ueyama // Handle -help
5273837f427SRui Ueyama if (args.hasArg(OPT_help)) {
52864626b34SRafael Espindola printHelp();
5291eb9f441SRui Ueyama return;
5301eb9f441SRui Ueyama }
5310a94bffeSGeorge Rimar
532bdc8bc04SRui Ueyama // Handle -v or -version.
533bdc8bc04SRui Ueyama //
534bdc8bc04SRui Ueyama // A note about "compatible with GNU linkers" message: this is a hack for
535bf6e259bSFangrui Song // scripts generated by GNU Libtool up to 2021-10 to recognize LLD as
536bf6e259bSFangrui Song // a GNU compatible linker. See
537bf6e259bSFangrui Song // <https://lists.gnu.org/archive/html/libtool/2017-01/msg00007.html>.
538bdc8bc04SRui Ueyama //
539bdc8bc04SRui Ueyama // This is somewhat ugly hack, but in reality, we had no choice other
540bdc8bc04SRui Ueyama // than doing this. Considering the very long release cycle of Libtool,
541bdc8bc04SRui Ueyama // it is not easy to improve it to recognize LLD as a GNU compatible
542bdc8bc04SRui Ueyama // linker in a timely manner. Even if we can make it, there are still a
543bdc8bc04SRui Ueyama // lot of "configure" scripts out there that are generated by old version
544bdc8bc04SRui Ueyama // of Libtool. We cannot convince every software developer to migrate to
545bdc8bc04SRui Ueyama // the latest version and re-generate scripts. So we have this hack.
5463837f427SRui Ueyama if (args.hasArg(OPT_v) || args.hasArg(OPT_version))
547bdc8bc04SRui Ueyama message(getLLDVersion() + " (compatible with GNU linkers)");
548bdc8bc04SRui Ueyama
5493837f427SRui Ueyama if (const char *path = getReproduceOption(args)) {
550fe65877cSRui Ueyama // Note that --reproduce is a debug option so you can ignore it
551fe65877cSRui Ueyama // if you are trying to understand the whole picture of the code.
5523837f427SRui Ueyama Expected<std::unique_ptr<TarWriter>> errOrWriter =
5533837f427SRui Ueyama TarWriter::create(path, path::stem(path));
5543837f427SRui Ueyama if (errOrWriter) {
5553837f427SRui Ueyama tar = std::move(*errOrWriter);
5563837f427SRui Ueyama tar->append("response.txt", createResponseFile(args));
5573837f427SRui Ueyama tar->append("version.txt", getLLDVersion() + "\n");
558bd4757ccSChristy Lee StringRef ltoSampleProfile = args.getLastArgValue(OPT_lto_sample_profile);
559bd4757ccSChristy Lee if (!ltoSampleProfile.empty())
560bd4757ccSChristy Lee readFile(ltoSampleProfile);
5617f1f9127SRui Ueyama } else {
5623837f427SRui Ueyama error("--reproduce: " + toString(errOrWriter.takeError()));
5637f1f9127SRui Ueyama }
5641dd2b3d1SRafael Espindola }
565034f58a9SDavide Italiano
5663837f427SRui Ueyama readConfigs(args);
567ee981860SGeorge Rimar
568ee981860SGeorge Rimar // The behavior of -v or --version is a bit strange, but this is
569ee981860SGeorge Rimar // needed for compatibility with GNU linkers.
5703837f427SRui Ueyama if (args.hasArg(OPT_v) && !args.hasArg(OPT_INPUT))
571ee981860SGeorge Rimar return;
5723837f427SRui Ueyama if (args.hasArg(OPT_version))
573ee981860SGeorge Rimar return;
574ee981860SGeorge Rimar
575e7cb3744SRussell Gallop // Initialize time trace profiler.
576e7cb3744SRussell Gallop if (config->timeTraceEnabled)
577e7cb3744SRussell Gallop timeTraceProfilerInitialize(config->timeTraceGranularity, config->progName);
578e7cb3744SRussell Gallop
579e7cb3744SRussell Gallop {
580e7cb3744SRussell Gallop llvm::TimeTraceScope timeScope("ExecuteLinker");
581e7cb3744SRussell Gallop
5829dc740d0SGeorge Rimar initLLVM();
5833837f427SRui Ueyama createFiles(args);
58466f28f7cSRui Ueyama if (errorCount())
58566f28f7cSRui Ueyama return;
58666f28f7cSRui Ueyama
587c185c012SRui Ueyama inferMachineType();
5883837f427SRui Ueyama setConfigs(args);
589d5f65063SSam Clegg checkOptions();
590b8a59c8aSBob Haarman if (errorCount())
59121eecb4fSRui Ueyama return;
592f5bcf2a7SRui Ueyama
5937518d38fSFangrui Song link(args);
5943ce825edSRui Ueyama }
5953ce825edSRui Ueyama
596e7cb3744SRussell Gallop if (config->timeTraceEnabled) {
597f3091831SNico Weber checkError(timeTraceProfilerWrite(
598a2c1f7c9SNico Weber args.getLastArgValue(OPT_time_trace_eq).str(), config->outputFile));
599e7cb3744SRussell Gallop timeTraceProfilerCleanup();
600e7cb3744SRussell Gallop }
601e7cb3744SRussell Gallop }
602e7cb3744SRussell Gallop
getRpath(opt::InputArgList & args)6033837f427SRui Ueyama static std::string getRpath(opt::InputArgList &args) {
6043837f427SRui Ueyama std::vector<StringRef> v = args::getStrings(args, OPT_rpath);
6053837f427SRui Ueyama return llvm::join(v.begin(), v.end(), ":");
6067edde294SRui Ueyama }
6077edde294SRui Ueyama
608dc0464c2SRui Ueyama // Determines what we should do if there are remaining unresolved
609dc0464c2SRui Ueyama // symbols after the name resolution.
setUnresolvedSymbolPolicy(opt::InputArgList & args)61055d310adSFangrui Song static void setUnresolvedSymbolPolicy(opt::InputArgList &args) {
6113837f427SRui Ueyama UnresolvedPolicy errorOrWarn = args.hasFlag(OPT_error_unresolved_symbols,
6120cbf1fd2SRui Ueyama OPT_warn_unresolved_symbols, true)
613dc0464c2SRui Ueyama ? UnresolvedPolicy::ReportError
614dc0464c2SRui Ueyama : UnresolvedPolicy::Warn;
615bf6e259bSFangrui Song // -shared implies --unresolved-symbols=ignore-all because missing
61655d310adSFangrui Song // symbols are likely to be resolved at runtime.
61755d310adSFangrui Song bool diagRegular = !config->shared, diagShlib = !config->shared;
618dc0464c2SRui Ueyama
61955d310adSFangrui Song for (const opt::Arg *arg : args) {
6203837f427SRui Ueyama switch (arg->getOption().getID()) {
621dc0464c2SRui Ueyama case OPT_unresolved_symbols: {
6223837f427SRui Ueyama StringRef s = arg->getValue();
62355d310adSFangrui Song if (s == "ignore-all") {
62455d310adSFangrui Song diagRegular = false;
62555d310adSFangrui Song diagShlib = false;
62655d310adSFangrui Song } else if (s == "ignore-in-object-files") {
62755d310adSFangrui Song diagRegular = false;
62855d310adSFangrui Song diagShlib = true;
62955d310adSFangrui Song } else if (s == "ignore-in-shared-libs") {
63055d310adSFangrui Song diagRegular = true;
63155d310adSFangrui Song diagShlib = false;
63255d310adSFangrui Song } else if (s == "report-all") {
63355d310adSFangrui Song diagRegular = true;
63455d310adSFangrui Song diagShlib = true;
63555d310adSFangrui Song } else {
6363837f427SRui Ueyama error("unknown --unresolved-symbols value: " + s);
63755d310adSFangrui Song }
63855d310adSFangrui Song break;
639dc0464c2SRui Ueyama }
640dc0464c2SRui Ueyama case OPT_no_undefined:
64155d310adSFangrui Song diagRegular = true;
64255d310adSFangrui Song break;
643dc0464c2SRui Ueyama case OPT_z:
6443837f427SRui Ueyama if (StringRef(arg->getValue()) == "defs")
64555d310adSFangrui Song diagRegular = true;
64655d310adSFangrui Song else if (StringRef(arg->getValue()) == "undefs")
64755d310adSFangrui Song diagRegular = false;
64855d310adSFangrui Song break;
64955d310adSFangrui Song case OPT_allow_shlib_undefined:
65055d310adSFangrui Song diagShlib = false;
65155d310adSFangrui Song break;
65255d310adSFangrui Song case OPT_no_allow_shlib_undefined:
65355d310adSFangrui Song diagShlib = true;
65455d310adSFangrui Song break;
655dc0464c2SRui Ueyama }
656e86dcd0cSGeorge Rimar }
657e86dcd0cSGeorge Rimar
65855d310adSFangrui Song config->unresolvedSymbols =
65955d310adSFangrui Song diagRegular ? errorOrWarn : UnresolvedPolicy::Ignore;
66055d310adSFangrui Song config->unresolvedSymbolsInShlib =
66155d310adSFangrui Song diagShlib ? errorOrWarn : UnresolvedPolicy::Ignore;
662403b093eSRafael Espindola }
663403b093eSRafael Espindola
getTarget2(opt::InputArgList & args)6643837f427SRui Ueyama static Target2Policy getTarget2(opt::InputArgList &args) {
6653837f427SRui Ueyama StringRef s = args.getLastArgValue(OPT_target2, "got-rel");
6663837f427SRui Ueyama if (s == "rel")
6679bbd4e27SPeter Smith return Target2Policy::Rel;
6683837f427SRui Ueyama if (s == "abs")
6699bbd4e27SPeter Smith return Target2Policy::Abs;
6703837f427SRui Ueyama if (s == "got-rel")
6719bbd4e27SPeter Smith return Target2Policy::GotRel;
6723837f427SRui Ueyama error("unknown --target2 option: " + s);
6739bbd4e27SPeter Smith return Target2Policy::GotRel;
6749bbd4e27SPeter Smith }
6759bbd4e27SPeter Smith
isOutputFormatBinary(opt::InputArgList & args)6763837f427SRui Ueyama static bool isOutputFormatBinary(opt::InputArgList &args) {
6773837f427SRui Ueyama StringRef s = args.getLastArgValue(OPT_oformat, "elf");
6783837f427SRui Ueyama if (s == "binary")
67986ce267aSGeorge Rimar return true;
6803837f427SRui Ueyama if (!s.startswith("elf"))
6813837f427SRui Ueyama error("unknown --oformat value: " + s);
68286ce267aSGeorge Rimar return false;
68386ce267aSGeorge Rimar }
68486ce267aSGeorge Rimar
getDiscard(opt::InputArgList & args)6853837f427SRui Ueyama static DiscardPolicy getDiscard(opt::InputArgList &args) {
6863837f427SRui Ueyama auto *arg =
6873837f427SRui Ueyama args.getLastArg(OPT_discard_all, OPT_discard_locals, OPT_discard_none);
6883837f427SRui Ueyama if (!arg)
6899503f6d2SGeorge Rimar return DiscardPolicy::Default;
6903837f427SRui Ueyama if (arg->getOption().getID() == OPT_discard_all)
6919503f6d2SGeorge Rimar return DiscardPolicy::All;
6923837f427SRui Ueyama if (arg->getOption().getID() == OPT_discard_locals)
6939503f6d2SGeorge Rimar return DiscardPolicy::Locals;
6949503f6d2SGeorge Rimar return DiscardPolicy::None;
6959503f6d2SGeorge Rimar }
6969503f6d2SGeorge Rimar
getDynamicLinker(opt::InputArgList & args)6973837f427SRui Ueyama static StringRef getDynamicLinker(opt::InputArgList &args) {
6983837f427SRui Ueyama auto *arg = args.getLastArg(OPT_dynamic_linker, OPT_no_dynamic_linker);
6990fbf28f7SFangrui Song if (!arg)
70087b0d686SGeorge Rimar return "";
7010fbf28f7SFangrui Song if (arg->getOption().getID() == OPT_no_dynamic_linker) {
7020fbf28f7SFangrui Song // --no-dynamic-linker suppresses undefined weak symbols in .dynsym
7030fbf28f7SFangrui Song config->noDynamicLinker = true;
7040fbf28f7SFangrui Song return "";
7050fbf28f7SFangrui Song }
7063837f427SRui Ueyama return arg->getValue();
70787b0d686SGeorge Rimar }
70887b0d686SGeorge Rimar
getMemtagMode(opt::InputArgList & args)709786c89feSMitch Phillips static int getMemtagMode(opt::InputArgList &args) {
710786c89feSMitch Phillips StringRef memtagModeArg = args.getLastArgValue(OPT_android_memtag_mode);
711786c89feSMitch Phillips if (!config->androidMemtagHeap && !config->androidMemtagStack) {
712786c89feSMitch Phillips if (!memtagModeArg.empty())
713786c89feSMitch Phillips error("when using --android-memtag-mode, at least one of "
714786c89feSMitch Phillips "--android-memtag-heap or "
715786c89feSMitch Phillips "--android-memtag-stack is required");
716786c89feSMitch Phillips return ELF::NT_MEMTAG_LEVEL_NONE;
717786c89feSMitch Phillips }
718786c89feSMitch Phillips
719786c89feSMitch Phillips if (memtagModeArg == "sync" || memtagModeArg.empty())
720786c89feSMitch Phillips return ELF::NT_MEMTAG_LEVEL_SYNC;
721786c89feSMitch Phillips if (memtagModeArg == "async")
722786c89feSMitch Phillips return ELF::NT_MEMTAG_LEVEL_ASYNC;
723786c89feSMitch Phillips if (memtagModeArg == "none")
724786c89feSMitch Phillips return ELF::NT_MEMTAG_LEVEL_NONE;
725786c89feSMitch Phillips
726786c89feSMitch Phillips error("unknown --android-memtag-mode value: \"" + memtagModeArg +
727786c89feSMitch Phillips "\", should be one of {async, sync, none}");
728786c89feSMitch Phillips return ELF::NT_MEMTAG_LEVEL_NONE;
729786c89feSMitch Phillips }
730786c89feSMitch Phillips
getICF(opt::InputArgList & args)7313837f427SRui Ueyama static ICFLevel getICF(opt::InputArgList &args) {
7323837f427SRui Ueyama auto *arg = args.getLastArg(OPT_icf_none, OPT_icf_safe, OPT_icf_all);
7333837f427SRui Ueyama if (!arg || arg->getOption().getID() == OPT_icf_none)
734a327a4c3SPeter Collingbourne return ICFLevel::None;
7353837f427SRui Ueyama if (arg->getOption().getID() == OPT_icf_safe)
736a327a4c3SPeter Collingbourne return ICFLevel::Safe;
737a327a4c3SPeter Collingbourne return ICFLevel::All;
738a327a4c3SPeter Collingbourne }
739a327a4c3SPeter Collingbourne
getStrip(opt::InputArgList & args)7403837f427SRui Ueyama static StripPolicy getStrip(opt::InputArgList &args) {
7413837f427SRui Ueyama if (args.hasArg(OPT_relocatable))
742524d44c6SRui Ueyama return StripPolicy::None;
743524d44c6SRui Ueyama
7443837f427SRui Ueyama auto *arg = args.getLastArg(OPT_strip_all, OPT_strip_debug);
7453837f427SRui Ueyama if (!arg)
746524d44c6SRui Ueyama return StripPolicy::None;
7473837f427SRui Ueyama if (arg->getOption().getID() == OPT_strip_all)
748f21aade0SGeorge Rimar return StripPolicy::All;
749f21aade0SGeorge Rimar return StripPolicy::Debug;
750f21aade0SGeorge Rimar }
751f21aade0SGeorge Rimar
parseSectionAddress(StringRef s,opt::InputArgList & args,const opt::Arg & arg)7523837f427SRui Ueyama static uint64_t parseSectionAddress(StringRef s, opt::InputArgList &args,
7533837f427SRui Ueyama const opt::Arg &arg) {
7543837f427SRui Ueyama uint64_t va = 0;
7553837f427SRui Ueyama if (s.startswith("0x"))
7563837f427SRui Ueyama s = s.drop_front(2);
7573837f427SRui Ueyama if (!to_integer(s, va, 16))
7583837f427SRui Ueyama error("invalid argument: " + arg.getAsString(args));
7593837f427SRui Ueyama return va;
760d73ef173SGeorge Rimar }
761d73ef173SGeorge Rimar
getSectionStartMap(opt::InputArgList & args)7623837f427SRui Ueyama static StringMap<uint64_t> getSectionStartMap(opt::InputArgList &args) {
7633837f427SRui Ueyama StringMap<uint64_t> ret;
7643837f427SRui Ueyama for (auto *arg : args.filtered(OPT_section_start)) {
7653837f427SRui Ueyama StringRef name;
7663837f427SRui Ueyama StringRef addr;
7673837f427SRui Ueyama std::tie(name, addr) = StringRef(arg->getValue()).split('=');
7683837f427SRui Ueyama ret[name] = parseSectionAddress(addr, args, *arg);
769d73ef173SGeorge Rimar }
770d73ef173SGeorge Rimar
7713837f427SRui Ueyama if (auto *arg = args.getLastArg(OPT_Ttext))
7723837f427SRui Ueyama ret[".text"] = parseSectionAddress(arg->getValue(), args, *arg);
7733837f427SRui Ueyama if (auto *arg = args.getLastArg(OPT_Tdata))
7743837f427SRui Ueyama ret[".data"] = parseSectionAddress(arg->getValue(), args, *arg);
7753837f427SRui Ueyama if (auto *arg = args.getLastArg(OPT_Tbss))
7763837f427SRui Ueyama ret[".bss"] = parseSectionAddress(arg->getValue(), args, *arg);
7773837f427SRui Ueyama return ret;
778d73ef173SGeorge Rimar }
779d73ef173SGeorge Rimar
getSortSection(opt::InputArgList & args)7803837f427SRui Ueyama static SortSectionPolicy getSortSection(opt::InputArgList &args) {
7813837f427SRui Ueyama StringRef s = args.getLastArgValue(OPT_sort_section);
7823837f427SRui Ueyama if (s == "alignment")
783be394db3SGeorge Rimar return SortSectionPolicy::Alignment;
7843837f427SRui Ueyama if (s == "name")
785be394db3SGeorge Rimar return SortSectionPolicy::Name;
7863837f427SRui Ueyama if (!s.empty())
7873837f427SRui Ueyama error("unknown --sort-section rule: " + s);
788b2a0abdfSRui Ueyama return SortSectionPolicy::Default;
789be394db3SGeorge Rimar }
790be394db3SGeorge Rimar
getOrphanHandling(opt::InputArgList & args)7913837f427SRui Ueyama static OrphanHandlingPolicy getOrphanHandling(opt::InputArgList &args) {
7923837f427SRui Ueyama StringRef s = args.getLastArgValue(OPT_orphan_handling, "place");
7933837f427SRui Ueyama if (s == "warn")
7949814d151SGeorge Rimar return OrphanHandlingPolicy::Warn;
7953837f427SRui Ueyama if (s == "error")
7969814d151SGeorge Rimar return OrphanHandlingPolicy::Error;
7973837f427SRui Ueyama if (s != "place")
7983837f427SRui Ueyama error("unknown --orphan-handling mode: " + s);
7999814d151SGeorge Rimar return OrphanHandlingPolicy::Place;
8009814d151SGeorge Rimar }
8019814d151SGeorge Rimar
80208af54c3SRui Ueyama // Parse --build-id or --build-id=<style>. We handle "tree" as a
80308af54c3SRui Ueyama // synonym for "sha1" because all our hash functions including
804bf6e259bSFangrui Song // --build-id=sha1 are actually tree hashes for performance reasons.
80508af54c3SRui Ueyama static std::pair<BuildIdKind, std::vector<uint8_t>>
getBuildId(opt::InputArgList & args)8063837f427SRui Ueyama getBuildId(opt::InputArgList &args) {
807cbcdb524SFangrui Song auto *arg = args.getLastArg(OPT_build_id);
8083837f427SRui Ueyama if (!arg)
809968fe938SPeter Collingbourne return {BuildIdKind::None, {}};
810968fe938SPeter Collingbourne
8113837f427SRui Ueyama StringRef s = arg->getValue();
8123837f427SRui Ueyama if (s == "fast")
813fa9f699dSRui Ueyama return {BuildIdKind::Fast, {}};
8143837f427SRui Ueyama if (s == "md5")
81508af54c3SRui Ueyama return {BuildIdKind::Md5, {}};
8163837f427SRui Ueyama if (s == "sha1" || s == "tree")
81708af54c3SRui Ueyama return {BuildIdKind::Sha1, {}};
8183837f427SRui Ueyama if (s == "uuid")
81908af54c3SRui Ueyama return {BuildIdKind::Uuid, {}};
8203837f427SRui Ueyama if (s.startswith("0x"))
8213837f427SRui Ueyama return {BuildIdKind::Hexstring, parseHex(s.substr(2))};
82208af54c3SRui Ueyama
8233837f427SRui Ueyama if (s != "none")
8243837f427SRui Ueyama error("unknown --build-id style: " + s);
82508af54c3SRui Ueyama return {BuildIdKind::None, {}};
82608af54c3SRui Ueyama }
82708af54c3SRui Ueyama
getPackDynRelocs(opt::InputArgList & args)8283837f427SRui Ueyama static std::pair<bool, bool> getPackDynRelocs(opt::InputArgList &args) {
8293837f427SRui Ueyama StringRef s = args.getLastArgValue(OPT_pack_dyn_relocs, "none");
8303837f427SRui Ueyama if (s == "android")
83145192b37SRui Ueyama return {true, false};
8323837f427SRui Ueyama if (s == "relr")
83345192b37SRui Ueyama return {false, true};
8343837f427SRui Ueyama if (s == "android+relr")
83545192b37SRui Ueyama return {true, true};
83645192b37SRui Ueyama
8373837f427SRui Ueyama if (s != "none")
838f8ee74fcSFangrui Song error("unknown --pack-dyn-relocs format: " + s);
83945192b37SRui Ueyama return {false, false};
84045192b37SRui Ueyama }
84145192b37SRui Ueyama
readCallGraph(MemoryBufferRef mb)8423837f427SRui Ueyama static void readCallGraph(MemoryBufferRef mb) {
843b842725cSMichael J. Spencer // Build a map from symbol name to section
8443837f427SRui Ueyama DenseMap<StringRef, Symbol *> map;
8459a572164SFangrui Song for (ELFFileBase *file : ctx->objectFiles)
8463837f427SRui Ueyama for (Symbol *sym : file->getSymbols())
8473837f427SRui Ueyama map[sym->getName()] = sym;
848b842725cSMichael J. Spencer
8493837f427SRui Ueyama auto findSection = [&](StringRef name) -> InputSectionBase * {
8503837f427SRui Ueyama Symbol *sym = map.lookup(name);
8513837f427SRui Ueyama if (!sym) {
8523837f427SRui Ueyama if (config->warnSymbolOrdering)
8533837f427SRui Ueyama warn(mb.getBufferIdentifier() + ": no such symbol: " + name);
8542b39ea47SRui Ueyama return nullptr;
8552b39ea47SRui Ueyama }
8563837f427SRui Ueyama maybeWarnUnorderableSymbol(sym);
8572b39ea47SRui Ueyama
8583837f427SRui Ueyama if (Defined *dr = dyn_cast_or_null<Defined>(sym))
8593837f427SRui Ueyama return dyn_cast_or_null<InputSectionBase>(dr->section);
86003b4d0c1SGeorge Rimar return nullptr;
86103b4d0c1SGeorge Rimar };
86203b4d0c1SGeorge Rimar
8633837f427SRui Ueyama for (StringRef line : args::getLines(mb)) {
8643837f427SRui Ueyama SmallVector<StringRef, 3> fields;
8653837f427SRui Ueyama line.split(fields, ' ');
8663837f427SRui Ueyama uint64_t count;
86703b4d0c1SGeorge Rimar
8683837f427SRui Ueyama if (fields.size() != 3 || !to_integer(fields[2], count)) {
8693837f427SRui Ueyama error(mb.getBufferIdentifier() + ": parse error");
8702b39ea47SRui Ueyama return;
8712b39ea47SRui Ueyama }
8722b39ea47SRui Ueyama
8733837f427SRui Ueyama if (InputSectionBase *from = findSection(fields[0]))
8743837f427SRui Ueyama if (InputSectionBase *to = findSection(fields[1]))
8753837f427SRui Ueyama config->callGraphProfile[std::make_pair(from, to)] += count;
876b842725cSMichael J. Spencer }
877b842725cSMichael J. Spencer }
878b842725cSMichael J. Spencer
87924129fbcSAlexander Yermolovich // If SHT_LLVM_CALL_GRAPH_PROFILE and its relocation section exist, returns
88024129fbcSAlexander Yermolovich // true and populates cgProfile and symbolIndices.
88124129fbcSAlexander Yermolovich template <class ELFT>
88224129fbcSAlexander Yermolovich static bool
processCallGraphRelocations(SmallVector<uint32_t,32> & symbolIndices,ArrayRef<typename ELFT::CGProfile> & cgProfile,ObjFile<ELFT> * inputObj)88324129fbcSAlexander Yermolovich processCallGraphRelocations(SmallVector<uint32_t, 32> &symbolIndices,
88424129fbcSAlexander Yermolovich ArrayRef<typename ELFT::CGProfile> &cgProfile,
88524129fbcSAlexander Yermolovich ObjFile<ELFT> *inputObj) {
88624129fbcSAlexander Yermolovich if (inputObj->cgProfileSectionIndex == SHN_UNDEF)
88724129fbcSAlexander Yermolovich return false;
88824129fbcSAlexander Yermolovich
889b5a0f0f3SFangrui Song ArrayRef<Elf_Shdr_Impl<ELFT>> objSections =
890b5a0f0f3SFangrui Song inputObj->template getELFShdrs<ELFT>();
891b5a0f0f3SFangrui Song symbolIndices.clear();
892b5a0f0f3SFangrui Song const ELFFile<ELFT> &obj = inputObj->getObj();
89324129fbcSAlexander Yermolovich cgProfile =
89424129fbcSAlexander Yermolovich check(obj.template getSectionContentsAsArray<typename ELFT::CGProfile>(
89524129fbcSAlexander Yermolovich objSections[inputObj->cgProfileSectionIndex]));
89624129fbcSAlexander Yermolovich
89724129fbcSAlexander Yermolovich for (size_t i = 0, e = objSections.size(); i < e; ++i) {
89824129fbcSAlexander Yermolovich const Elf_Shdr_Impl<ELFT> &sec = objSections[i];
89924129fbcSAlexander Yermolovich if (sec.sh_info == inputObj->cgProfileSectionIndex) {
90024129fbcSAlexander Yermolovich if (sec.sh_type == SHT_RELA) {
90124129fbcSAlexander Yermolovich ArrayRef<typename ELFT::Rela> relas =
90224129fbcSAlexander Yermolovich CHECK(obj.relas(sec), "could not retrieve cg profile rela section");
90324129fbcSAlexander Yermolovich for (const typename ELFT::Rela &rel : relas)
90424129fbcSAlexander Yermolovich symbolIndices.push_back(rel.getSymbol(config->isMips64EL));
90524129fbcSAlexander Yermolovich break;
90624129fbcSAlexander Yermolovich }
90724129fbcSAlexander Yermolovich if (sec.sh_type == SHT_REL) {
90824129fbcSAlexander Yermolovich ArrayRef<typename ELFT::Rel> rels =
90924129fbcSAlexander Yermolovich CHECK(obj.rels(sec), "could not retrieve cg profile rel section");
91024129fbcSAlexander Yermolovich for (const typename ELFT::Rel &rel : rels)
91124129fbcSAlexander Yermolovich symbolIndices.push_back(rel.getSymbol(config->isMips64EL));
91224129fbcSAlexander Yermolovich break;
91324129fbcSAlexander Yermolovich }
91424129fbcSAlexander Yermolovich }
91524129fbcSAlexander Yermolovich }
91624129fbcSAlexander Yermolovich if (symbolIndices.empty())
91724129fbcSAlexander Yermolovich warn("SHT_LLVM_CALL_GRAPH_PROFILE exists, but relocation section doesn't");
91824129fbcSAlexander Yermolovich return !symbolIndices.empty();
91924129fbcSAlexander Yermolovich }
92024129fbcSAlexander Yermolovich
readCallGraphsFromObjectFiles()92124129fbcSAlexander Yermolovich template <class ELFT> static void readCallGraphsFromObjectFiles() {
92224129fbcSAlexander Yermolovich SmallVector<uint32_t, 32> symbolIndices;
92324129fbcSAlexander Yermolovich ArrayRef<typename ELFT::CGProfile> cgProfile;
9249a572164SFangrui Song for (auto file : ctx->objectFiles) {
9253837f427SRui Ueyama auto *obj = cast<ObjFile<ELFT>>(file);
92624129fbcSAlexander Yermolovich if (!processCallGraphRelocations(symbolIndices, cgProfile, obj))
927a224c519SAlexander Yermolovich continue;
92824129fbcSAlexander Yermolovich
92924129fbcSAlexander Yermolovich if (symbolIndices.size() != cgProfile.size() * 2)
930a224c519SAlexander Yermolovich fatal("number of relocations doesn't match Weights");
93124129fbcSAlexander Yermolovich
93224129fbcSAlexander Yermolovich for (uint32_t i = 0, size = cgProfile.size(); i < size; ++i) {
93324129fbcSAlexander Yermolovich const Elf_CGProfile_Impl<ELFT> &cgpe = cgProfile[i];
93424129fbcSAlexander Yermolovich uint32_t fromIndex = symbolIndices[i * 2];
93524129fbcSAlexander Yermolovich uint32_t toIndex = symbolIndices[i * 2 + 1];
936a224c519SAlexander Yermolovich auto *fromSym = dyn_cast<Defined>(&obj->getSymbol(fromIndex));
937a224c519SAlexander Yermolovich auto *toSym = dyn_cast<Defined>(&obj->getSymbol(toIndex));
9383837f427SRui Ueyama if (!fromSym || !toSym)
9398222f902SMichael J. Spencer continue;
9402b39ea47SRui Ueyama
9413837f427SRui Ueyama auto *from = dyn_cast_or_null<InputSectionBase>(fromSym->section);
9423837f427SRui Ueyama auto *to = dyn_cast_or_null<InputSectionBase>(toSym->section);
9433837f427SRui Ueyama if (from && to)
9443837f427SRui Ueyama config->callGraphProfile[{from, to}] += cgpe.cgp_weight;
9458222f902SMichael J. Spencer }
9468222f902SMichael J. Spencer }
9478222f902SMichael J. Spencer }
9488222f902SMichael J. Spencer
getCompressDebugSections(opt::InputArgList & args)9493837f427SRui Ueyama static bool getCompressDebugSections(opt::InputArgList &args) {
9503837f427SRui Ueyama StringRef s = args.getLastArgValue(OPT_compress_debug_sections, "none");
9513837f427SRui Ueyama if (s == "none")
952dbf93397SGeorge Rimar return false;
9533837f427SRui Ueyama if (s != "zlib")
9543837f427SRui Ueyama error("unknown --compress-debug-sections value: " + s);
955ea61750cSCole Kissane if (!compression::zlib::isAvailable())
956543161a1SRui Ueyama error("--compress-debug-sections: zlib is not available");
957543161a1SRui Ueyama return true;
958dbf93397SGeorge Rimar }
959dbf93397SGeorge Rimar
getAliasSpelling(opt::Arg * arg)9609f0f36e0SBob Haarman static StringRef getAliasSpelling(opt::Arg *arg) {
9619f0f36e0SBob Haarman if (const opt::Arg *alias = arg->getAlias())
9629f0f36e0SBob Haarman return alias->getSpelling();
9639f0f36e0SBob Haarman return arg->getSpelling();
9649f0f36e0SBob Haarman }
9659f0f36e0SBob Haarman
getOldNewOptions(opt::InputArgList & args,unsigned id)9663837f427SRui Ueyama static std::pair<StringRef, StringRef> getOldNewOptions(opt::InputArgList &args,
9673837f427SRui Ueyama unsigned id) {
9683837f427SRui Ueyama auto *arg = args.getLastArg(id);
9693837f427SRui Ueyama if (!arg)
9700dd56dcdSRui Ueyama return {"", ""};
9710dd56dcdSRui Ueyama
9723837f427SRui Ueyama StringRef s = arg->getValue();
9733837f427SRui Ueyama std::pair<StringRef, StringRef> ret = s.split(';');
9743837f427SRui Ueyama if (ret.second.empty())
9759f0f36e0SBob Haarman error(getAliasSpelling(arg) + " expects 'old;new' format, but got " + s);
9763837f427SRui Ueyama return ret;
977cb38bf52SGeorge Rimar }
978cb38bf52SGeorge Rimar
979de300e66SJames Henderson // Parse the symbol ordering file and warn for any duplicate entries.
getSymbolOrderingFile(MemoryBufferRef mb)9803837f427SRui Ueyama static std::vector<StringRef> getSymbolOrderingFile(MemoryBufferRef mb) {
9813837f427SRui Ueyama SetVector<StringRef> names;
9823837f427SRui Ueyama for (StringRef s : args::getLines(mb))
9833837f427SRui Ueyama if (!names.insert(s) && config->warnSymbolOrdering)
9843837f427SRui Ueyama warn(mb.getBufferIdentifier() + ": duplicate ordered symbol: " + s);
985de300e66SJames Henderson
9863837f427SRui Ueyama return names.takeVector();
987de300e66SJames Henderson }
988de300e66SJames Henderson
getIsRela(opt::InputArgList & args)989881c5eefSFangrui Song static bool getIsRela(opt::InputArgList &args) {
990881c5eefSFangrui Song // If -z rel or -z rela is specified, use the last option.
991881c5eefSFangrui Song for (auto *arg : args.filtered_reverse(OPT_z)) {
992881c5eefSFangrui Song StringRef s(arg->getValue());
993881c5eefSFangrui Song if (s == "rel")
994881c5eefSFangrui Song return false;
995881c5eefSFangrui Song if (s == "rela")
996881c5eefSFangrui Song return true;
997881c5eefSFangrui Song }
998881c5eefSFangrui Song
999881c5eefSFangrui Song // Otherwise use the psABI defined relocation entry format.
1000881c5eefSFangrui Song uint16_t m = config->emachine;
1001881c5eefSFangrui Song return m == EM_AARCH64 || m == EM_AMDGPU || m == EM_HEXAGON || m == EM_PPC ||
1002881c5eefSFangrui Song m == EM_PPC64 || m == EM_RISCV || m == EM_X86_64;
1003881c5eefSFangrui Song }
1004881c5eefSFangrui Song
parseClangOption(StringRef opt,const Twine & msg)10053837f427SRui Ueyama static void parseClangOption(StringRef opt, const Twine &msg) {
10063837f427SRui Ueyama std::string err;
10073837f427SRui Ueyama raw_string_ostream os(err);
10085aab635eSRui Ueyama
10093837f427SRui Ueyama const char *argv[] = {config->progName.data(), opt.data()};
10103837f427SRui Ueyama if (cl::ParseCommandLineOptions(2, argv, "", &os))
10115aab635eSRui Ueyama return;
10123837f427SRui Ueyama os.flush();
10133837f427SRui Ueyama error(msg + ": " + StringRef(err).trim());
10145aab635eSRui Ueyama }
10155aab635eSRui Ueyama
10162b4e6052SDaniel Kiss // Checks the parameter of the bti-report and cet-report options.
isValidReportString(StringRef arg)10172b4e6052SDaniel Kiss static bool isValidReportString(StringRef arg) {
10182b4e6052SDaniel Kiss return arg == "none" || arg == "warning" || arg == "error";
10192b4e6052SDaniel Kiss }
10202b4e6052SDaniel Kiss
10210dd684ceSRui Ueyama // Initializes Config members by the command line options.
readConfigs(opt::InputArgList & args)10223837f427SRui Ueyama static void readConfigs(opt::InputArgList &args) {
1023136d27abSRui Ueyama errorHandler().verbose = args.hasArg(OPT_verbose);
102487886299SChris Jackson errorHandler().vsDiagnostics =
102587886299SChris Jackson args.hasArg(OPT_visual_studio_diagnostics_format, false);
1026d42b1c05SRui Ueyama
10273837f427SRui Ueyama config->allowMultipleDefinition =
10283837f427SRui Ueyama args.hasFlag(OPT_allow_multiple_definition,
1029bb8d15e4SRui Ueyama OPT_no_allow_multiple_definition, false) ||
10303837f427SRui Ueyama hasZOption(args, "muldefs");
1031786c89feSMitch Phillips config->androidMemtagHeap =
1032786c89feSMitch Phillips args.hasFlag(OPT_android_memtag_heap, OPT_no_android_memtag_heap, false);
1033786c89feSMitch Phillips config->androidMemtagStack = args.hasFlag(OPT_android_memtag_stack,
1034786c89feSMitch Phillips OPT_no_android_memtag_stack, false);
1035786c89feSMitch Phillips config->androidMemtagMode = getMemtagMode(args);
10363837f427SRui Ueyama config->auxiliaryList = args::getStrings(args, OPT_auxiliary);
1037b06426daSFangrui Song if (opt::Arg *arg =
1038b06426daSFangrui Song args.getLastArg(OPT_Bno_symbolic, OPT_Bsymbolic_non_weak_functions,
1039b06426daSFangrui Song OPT_Bsymbolic_functions, OPT_Bsymbolic)) {
1040b06426daSFangrui Song if (arg->getOption().matches(OPT_Bsymbolic_non_weak_functions))
1041b06426daSFangrui Song config->bsymbolic = BsymbolicKind::NonWeakFunctions;
1042b06426daSFangrui Song else if (arg->getOption().matches(OPT_Bsymbolic_functions))
1043b06426daSFangrui Song config->bsymbolic = BsymbolicKind::Functions;
10444adf7a76SFangrui Song else if (arg->getOption().matches(OPT_Bsymbolic))
1045b06426daSFangrui Song config->bsymbolic = BsymbolicKind::All;
10464adf7a76SFangrui Song }
10473837f427SRui Ueyama config->checkSections =
10483837f427SRui Ueyama args.hasFlag(OPT_check_sections, OPT_no_check_sections, true);
10493837f427SRui Ueyama config->chroot = args.getLastArgValue(OPT_chroot);
10503837f427SRui Ueyama config->compressDebugSections = getCompressDebugSections(args);
105189e66a3aSFangrui Song config->cref = args.hasArg(OPT_cref);
105294317878SSriraman Tallam config->optimizeBBJumps =
105394317878SSriraman Tallam args.hasFlag(OPT_optimize_bb_jumps, OPT_no_optimize_bb_jumps, false);
10543837f427SRui Ueyama config->demangle = args.hasFlag(OPT_demangle, OPT_no_demangle, true);
105581eeabbdSPetr Hosek config->dependencyFile = args.getLastArgValue(OPT_dependency_file);
10563837f427SRui Ueyama config->dependentLibraries = args.hasFlag(OPT_dependent_libraries, OPT_no_dependent_libraries, true);
10573837f427SRui Ueyama config->disableVerify = args.hasArg(OPT_disable_verify);
10583837f427SRui Ueyama config->discard = getDiscard(args);
10593837f427SRui Ueyama config->dwoDir = args.getLastArgValue(OPT_plugin_opt_dwo_dir_eq);
10603837f427SRui Ueyama config->dynamicLinker = getDynamicLinker(args);
10613837f427SRui Ueyama config->ehFrameHdr =
10623837f427SRui Ueyama args.hasFlag(OPT_eh_frame_hdr, OPT_no_eh_frame_hdr, false);
10633837f427SRui Ueyama config->emitLLVM = args.hasArg(OPT_plugin_opt_emit_llvm, false);
10643837f427SRui Ueyama config->emitRelocs = args.hasArg(OPT_emit_relocs);
10653837f427SRui Ueyama config->callGraphProfileSort = args.hasFlag(
1066cc18f8aaSFangrui Song OPT_call_graph_profile_sort, OPT_no_call_graph_profile_sort, true);
10673837f427SRui Ueyama config->enableNewDtags =
10683837f427SRui Ueyama args.hasFlag(OPT_enable_new_dtags, OPT_disable_new_dtags, true);
10693837f427SRui Ueyama config->entry = args.getLastArgValue(OPT_entry);
1070cfc32267Sserge-sans-paille
1071cfc32267Sserge-sans-paille errorHandler().errorHandlingScript =
1072cfc32267Sserge-sans-paille args.getLastArgValue(OPT_error_handling_script);
1073cfc32267Sserge-sans-paille
10743837f427SRui Ueyama config->executeOnly =
10753837f427SRui Ueyama args.hasFlag(OPT_execute_only, OPT_no_execute_only, false);
10763837f427SRui Ueyama config->exportDynamic =
10775bc4e15cSFangrui Song args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, false) ||
10785bc4e15cSFangrui Song args.hasArg(OPT_shared);
10793837f427SRui Ueyama config->filterList = args::getStrings(args, OPT_filter);
10803837f427SRui Ueyama config->fini = args.getLastArgValue(OPT_fini, "_fini");
1081c81fe347SEli Friedman config->fixCortexA53Errata843419 = args.hasArg(OPT_fix_cortex_a53_843419) &&
1082c81fe347SEli Friedman !args.hasArg(OPT_relocatable);
1083e727f39eSPeter Smith config->fixCortexA8 =
1084e727f39eSPeter Smith args.hasArg(OPT_fix_cortex_a8) && !args.hasArg(OPT_relocatable);
10858f91f381SSean Fertile config->fortranCommon =
1086c0065f11SFangrui Song args.hasFlag(OPT_fortran_common, OPT_no_fortran_common, false);
10873837f427SRui Ueyama config->gcSections = args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, false);
10883837f427SRui Ueyama config->gnuUnique = args.hasFlag(OPT_gnu_unique, OPT_no_gnu_unique, true);
10893837f427SRui Ueyama config->gdbIndex = args.hasFlag(OPT_gdb_index, OPT_no_gdb_index, false);
10903837f427SRui Ueyama config->icf = getICF(args);
10913837f427SRui Ueyama config->ignoreDataAddressEquality =
10923837f427SRui Ueyama args.hasArg(OPT_ignore_data_address_equality);
10933837f427SRui Ueyama config->ignoreFunctionAddressEquality =
10943837f427SRui Ueyama args.hasArg(OPT_ignore_function_address_equality);
10953837f427SRui Ueyama config->init = args.getLastArgValue(OPT_init, "_init");
10963837f427SRui Ueyama config->ltoAAPipeline = args.getLastArgValue(OPT_lto_aa_pipeline);
10973837f427SRui Ueyama config->ltoCSProfileGenerate = args.hasArg(OPT_lto_cs_profile_generate);
10983837f427SRui Ueyama config->ltoCSProfileFile = args.getLastArgValue(OPT_lto_cs_profile_file);
10998fa16cc6SYolanda Chen config->ltoPGOWarnMismatch = args.hasFlag(OPT_lto_pgo_warn_mismatch,
11008fa16cc6SYolanda Chen OPT_no_lto_pgo_warn_mismatch, true);
11013837f427SRui Ueyama config->ltoDebugPassManager = args.hasArg(OPT_lto_debug_pass_manager);
1102964ef8eeSHongtao Yu config->ltoEmitAsm = args.hasArg(OPT_lto_emit_asm);
11033837f427SRui Ueyama config->ltoNewPmPasses = args.getLastArgValue(OPT_lto_newpm_passes);
11042f63d549STeresa Johnson config->ltoWholeProgramVisibility =
110507f234beSTeresa Johnson args.hasFlag(OPT_lto_whole_program_visibility,
110607f234beSTeresa Johnson OPT_no_lto_whole_program_visibility, false);
11073837f427SRui Ueyama config->ltoo = args::getInteger(args, OPT_lto_O, 2);
11089f0f36e0SBob Haarman config->ltoObjPath = args.getLastArgValue(OPT_lto_obj_path_eq);
11093837f427SRui Ueyama config->ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1);
11103837f427SRui Ueyama config->ltoSampleProfile = args.getLastArgValue(OPT_lto_sample_profile);
111194317878SSriraman Tallam config->ltoBasicBlockSections =
1112ca6b6d40SSriraman Tallam args.getLastArgValue(OPT_lto_basic_block_sections);
1113e0bca46bSSriraman Tallam config->ltoUniqueBasicBlockSectionNames =
1114ca6b6d40SSriraman Tallam args.hasFlag(OPT_lto_unique_basic_block_section_names,
1115ca6b6d40SSriraman Tallam OPT_no_lto_unique_basic_block_section_names, false);
11163837f427SRui Ueyama config->mapFile = args.getLastArgValue(OPT_Map);
11173837f427SRui Ueyama config->mipsGotSize = args::getInteger(args, OPT_mips_got_size, 0xfff0);
11183837f427SRui Ueyama config->mergeArmExidx =
11193837f427SRui Ueyama args.hasFlag(OPT_merge_exidx_entries, OPT_no_merge_exidx_entries, true);
112068142324SNick Terrell config->mmapOutputFile =
112168142324SNick Terrell args.hasFlag(OPT_mmap_output_file, OPT_no_mmap_output_file, true);
11223837f427SRui Ueyama config->nmagic = args.hasFlag(OPT_nmagic, OPT_no_nmagic, false);
11233837f427SRui Ueyama config->noinhibitExec = args.hasArg(OPT_noinhibit_exec);
11243837f427SRui Ueyama config->nostdlib = args.hasArg(OPT_nostdlib);
11253837f427SRui Ueyama config->oFormatBinary = isOutputFormatBinary(args);
11263837f427SRui Ueyama config->omagic = args.hasFlag(OPT_omagic, OPT_no_omagic, false);
1127850d53a1SMatthias Braun config->opaquePointers = args.hasFlag(
1128850d53a1SMatthias Braun OPT_plugin_opt_opaque_pointers, OPT_plugin_opt_no_opaque_pointers, true);
11293837f427SRui Ueyama config->optRemarksFilename = args.getLastArgValue(OPT_opt_remarks_filename);
11307c20e7caSAlex Richardson config->optStatsFilename = args.getLastArgValue(OPT_plugin_opt_stats_file);
11313acda917SWei Wang
11323acda917SWei Wang // Parse remarks hotness threshold. Valid value is either integer or 'auto'.
11333acda917SWei Wang if (auto *arg = args.getLastArg(OPT_opt_remarks_hotness_threshold)) {
11343acda917SWei Wang auto resultOrErr = remarks::parseHotnessThresholdOption(arg->getValue());
11353acda917SWei Wang if (!resultOrErr)
11363acda917SWei Wang error(arg->getSpelling() + ": invalid argument '" + arg->getValue() +
11373acda917SWei Wang "', only integer or 'auto' is supported");
11383acda917SWei Wang else
11393acda917SWei Wang config->optRemarksHotnessThreshold = *resultOrErr;
11403acda917SWei Wang }
11413acda917SWei Wang
11423837f427SRui Ueyama config->optRemarksPasses = args.getLastArgValue(OPT_opt_remarks_passes);
11433837f427SRui Ueyama config->optRemarksWithHotness = args.hasArg(OPT_opt_remarks_with_hotness);
11443837f427SRui Ueyama config->optRemarksFormat = args.getLastArgValue(OPT_opt_remarks_format);
11453837f427SRui Ueyama config->optimize = args::getInteger(args, OPT_O, 1);
11463837f427SRui Ueyama config->orphanHandling = getOrphanHandling(args);
11473837f427SRui Ueyama config->outputFile = args.getLastArgValue(OPT_o);
1148525ffb05SAlex Brachet config->packageMetadata = args.getLastArgValue(OPT_package_metadata);
11493837f427SRui Ueyama config->pie = args.hasFlag(OPT_pie, OPT_no_pie, false);
11503837f427SRui Ueyama config->printIcfSections =
11513837f427SRui Ueyama args.hasFlag(OPT_print_icf_sections, OPT_no_print_icf_sections, false);
11523837f427SRui Ueyama config->printGcSections =
11533837f427SRui Ueyama args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);
1154b912b887SFangrui Song config->printArchiveStats = args.getLastArgValue(OPT_print_archive_stats);
11553837f427SRui Ueyama config->printSymbolOrder =
11563837f427SRui Ueyama args.getLastArgValue(OPT_print_symbol_order);
1157a05384dcSFangrui Song config->relax = args.hasFlag(OPT_relax, OPT_no_relax, true);
11583837f427SRui Ueyama config->rpath = getRpath(args);
11593837f427SRui Ueyama config->relocatable = args.hasArg(OPT_relocatable);
116065001f57SJin Xin Ng
116165001f57SJin Xin Ng if (args.hasArg(OPT_save_temps)) {
116265001f57SJin Xin Ng // --save-temps implies saving all temps.
116365001f57SJin Xin Ng for (const char *s : saveTempsValues)
116465001f57SJin Xin Ng config->saveTempsArgs.insert(s);
116565001f57SJin Xin Ng } else {
116665001f57SJin Xin Ng for (auto *arg : args.filtered(OPT_save_temps_eq)) {
116765001f57SJin Xin Ng StringRef s = arg->getValue();
116865001f57SJin Xin Ng if (llvm::is_contained(saveTempsValues, s))
116965001f57SJin Xin Ng config->saveTempsArgs.insert(s);
117065001f57SJin Xin Ng else
117165001f57SJin Xin Ng error("unknown --save-temps value: " + s);
117265001f57SJin Xin Ng }
117365001f57SJin Xin Ng }
117465001f57SJin Xin Ng
11753837f427SRui Ueyama config->searchPaths = args::getStrings(args, OPT_library_path);
11763837f427SRui Ueyama config->sectionStartMap = getSectionStartMap(args);
11773837f427SRui Ueyama config->shared = args.hasArg(OPT_shared);
1178e96d7b5eSFangrui Song config->singleRoRx = !args.hasFlag(OPT_rosegment, OPT_no_rosegment, true);
11793837f427SRui Ueyama config->soName = args.getLastArgValue(OPT_soname);
11803837f427SRui Ueyama config->sortSection = getSortSection(args);
11813837f427SRui Ueyama config->splitStackAdjustSize = args::getInteger(args, OPT_split_stack_adjust_size, 16384);
11823837f427SRui Ueyama config->strip = getStrip(args);
11833837f427SRui Ueyama config->sysroot = args.getLastArgValue(OPT_sysroot);
11843837f427SRui Ueyama config->target1Rel = args.hasFlag(OPT_target1_rel, OPT_target1_abs, false);
11853837f427SRui Ueyama config->target2 = getTarget2(args);
11863837f427SRui Ueyama config->thinLTOCacheDir = args.getLastArgValue(OPT_thinlto_cache_dir);
11873837f427SRui Ueyama config->thinLTOCachePolicy = CHECK(
11883837f427SRui Ueyama parseCachePruningPolicy(args.getLastArgValue(OPT_thinlto_cache_policy)),
1189ee59e43fSPeter Collingbourne "--thinlto-cache-policy: invalid cache policy");
11909f0f36e0SBob Haarman config->thinLTOEmitImportsFiles = args.hasArg(OPT_thinlto_emit_imports_files);
119122f12733SJin Xin Ng config->thinLTOEmitIndexFiles = args.hasArg(OPT_thinlto_emit_index_files) ||
119222f12733SJin Xin Ng args.hasArg(OPT_thinlto_index_only) ||
119322f12733SJin Xin Ng args.hasArg(OPT_thinlto_index_only_eq);
11949f0f36e0SBob Haarman config->thinLTOIndexOnly = args.hasArg(OPT_thinlto_index_only) ||
11959f0f36e0SBob Haarman args.hasArg(OPT_thinlto_index_only_eq);
11969f0f36e0SBob Haarman config->thinLTOIndexOnlyArg = args.getLastArgValue(OPT_thinlto_index_only_eq);
11973837f427SRui Ueyama config->thinLTOObjectSuffixReplace =
11989f0f36e0SBob Haarman getOldNewOptions(args, OPT_thinlto_object_suffix_replace_eq);
11993837f427SRui Ueyama config->thinLTOPrefixReplace =
12009f0f36e0SBob Haarman getOldNewOptions(args, OPT_thinlto_prefix_replace_eq);
120122f12733SJin Xin Ng if (config->thinLTOEmitIndexFiles && !config->thinLTOIndexOnly) {
120222f12733SJin Xin Ng if (args.hasArg(OPT_thinlto_object_suffix_replace_eq))
120322f12733SJin Xin Ng error("--thinlto-object-suffix-replace is not supported with "
120422f12733SJin Xin Ng "--thinlto-emit-index-files");
120522f12733SJin Xin Ng else if (args.hasArg(OPT_thinlto_prefix_replace_eq))
120622f12733SJin Xin Ng error("--thinlto-prefix-replace is not supported with "
120722f12733SJin Xin Ng "--thinlto-emit-index-files");
120822f12733SJin Xin Ng }
12092638aafeSHongtao Yu config->thinLTOModulesToCompile =
12102638aafeSHongtao Yu args::getStrings(args, OPT_thinlto_single_module_eq);
1211a2c1f7c9SNico Weber config->timeTraceEnabled = args.hasArg(OPT_time_trace_eq);
1212e7cb3744SRussell Gallop config->timeTraceGranularity =
1213e7cb3744SRussell Gallop args::getInteger(args, OPT_time_trace_granularity, 500);
12143837f427SRui Ueyama config->trace = args.hasArg(OPT_trace);
12153837f427SRui Ueyama config->undefined = args::getStrings(args, OPT_undefined);
12163837f427SRui Ueyama config->undefinedVersion =
12173837f427SRui Ueyama args.hasFlag(OPT_undefined_version, OPT_no_undefined_version, true);
12186e2804ceSDavid Bozier config->unique = args.hasArg(OPT_unique);
12193837f427SRui Ueyama config->useAndroidRelrTags = args.hasFlag(
122011479dafSRui Ueyama OPT_use_android_relr_tags, OPT_no_use_android_relr_tags, false);
12213837f427SRui Ueyama config->warnBackrefs =
12223837f427SRui Ueyama args.hasFlag(OPT_warn_backrefs, OPT_no_warn_backrefs, false);
12233837f427SRui Ueyama config->warnCommon = args.hasFlag(OPT_warn_common, OPT_no_warn_common, false);
12243837f427SRui Ueyama config->warnSymbolOrdering =
12253837f427SRui Ueyama args.hasFlag(OPT_warn_symbol_ordering, OPT_no_warn_symbol_ordering, true);
1226a954bb18SFangrui Song config->whyExtract = args.getLastArgValue(OPT_why_extract);
12273837f427SRui Ueyama config->zCombreloc = getZFlag(args, "combreloc", "nocombreloc", true);
12283837f427SRui Ueyama config->zCopyreloc = getZFlag(args, "copyreloc", "nocopyreloc", true);
1229105a2700SFangrui Song config->zForceBti = hasZOption(args, "force-bti");
12307cd429f2SFangrui Song config->zForceIbt = hasZOption(args, "force-ibt");
12313837f427SRui Ueyama config->zGlobal = hasZOption(args, "global");
12322a0fcae3SMichał Górny config->zGnustack = getZGnuStack(args);
12333837f427SRui Ueyama config->zHazardplt = hasZOption(args, "hazardplt");
12343837f427SRui Ueyama config->zIfuncNoplt = hasZOption(args, "ifunc-noplt");
12353837f427SRui Ueyama config->zInitfirst = hasZOption(args, "initfirst");
12363837f427SRui Ueyama config->zInterpose = hasZOption(args, "interpose");
12373837f427SRui Ueyama config->zKeepTextSectionPrefix = getZFlag(
12383837f427SRui Ueyama args, "keep-text-section-prefix", "nokeep-text-section-prefix", false);
12393837f427SRui Ueyama config->zNodefaultlib = hasZOption(args, "nodefaultlib");
12403837f427SRui Ueyama config->zNodelete = hasZOption(args, "nodelete");
12413837f427SRui Ueyama config->zNodlopen = hasZOption(args, "nodlopen");
12423837f427SRui Ueyama config->zNow = getZFlag(args, "now", "lazy", false);
12433837f427SRui Ueyama config->zOrigin = hasZOption(args, "origin");
1244105a2700SFangrui Song config->zPacPlt = hasZOption(args, "pac-plt");
12453837f427SRui Ueyama config->zRelro = getZFlag(args, "relro", "norelro", true);
12463837f427SRui Ueyama config->zRetpolineplt = hasZOption(args, "retpolineplt");
12473837f427SRui Ueyama config->zRodynamic = hasZOption(args, "rodynamic");
124802649506SFangrui Song config->zSeparate = getZSeparate(args);
12497cd429f2SFangrui Song config->zShstk = hasZOption(args, "shstk");
12503837f427SRui Ueyama config->zStackSize = args::getZOptionValue(args, OPT_z, "stack-size", 0);
12514bbcd63eSFangrui Song config->zStartStopGC =
12526d2d3bd0SFangrui Song getZFlag(args, "start-stop-gc", "nostart-stop-gc", true);
1253fffd05d5SPetr Hosek config->zStartStopVisibility = getZStartStopVisibility(args);
12543837f427SRui Ueyama config->zText = getZFlag(args, "text", "notext", true);
12553837f427SRui Ueyama config->zWxneeded = hasZOption(args, "wxneeded");
125655d310adSFangrui Song setUnresolvedSymbolPolicy(args);
12573b4dd68dSFangrui Song config->power10Stubs = args.getLastArgValue(OPT_power10_stubs_eq) != "no";
1258a4a643c6SRui Ueyama
1259eea34aaeSFangrui Song if (opt::Arg *arg = args.getLastArg(OPT_eb, OPT_el)) {
1260eea34aaeSFangrui Song if (arg->getOption().matches(OPT_eb))
1261eea34aaeSFangrui Song config->optEB = true;
1262eea34aaeSFangrui Song else
1263eea34aaeSFangrui Song config->optEL = true;
1264eea34aaeSFangrui Song }
1265eea34aaeSFangrui Song
126616c30c3cSFangrui Song for (opt::Arg *arg : args.filtered(OPT_shuffle_sections)) {
126716c30c3cSFangrui Song constexpr StringRef errPrefix = "--shuffle-sections=: ";
126816c30c3cSFangrui Song std::pair<StringRef, StringRef> kv = StringRef(arg->getValue()).split('=');
126916c30c3cSFangrui Song if (kv.first.empty() || kv.second.empty()) {
127016c30c3cSFangrui Song error(errPrefix + "expected <section_glob>=<seed>, but got '" +
127116c30c3cSFangrui Song arg->getValue() + "'");
127216c30c3cSFangrui Song continue;
127316c30c3cSFangrui Song }
127416c30c3cSFangrui Song // Signed so that <section_glob>=-1 is allowed.
127516c30c3cSFangrui Song int64_t v;
127616c30c3cSFangrui Song if (!to_integer(kv.second, v))
127716c30c3cSFangrui Song error(errPrefix + "expected an integer, but got '" + kv.second + "'");
127816c30c3cSFangrui Song else if (Expected<GlobPattern> pat = GlobPattern::create(kv.first))
127916c30c3cSFangrui Song config->shuffleSections.emplace_back(std::move(*pat), uint32_t(v));
128016c30c3cSFangrui Song else
128116c30c3cSFangrui Song error(errPrefix + toString(pat.takeError()));
128216c30c3cSFangrui Song }
128316c30c3cSFangrui Song
12842b4e6052SDaniel Kiss auto reports = {std::make_pair("bti-report", &config->zBtiReport),
12852b4e6052SDaniel Kiss std::make_pair("cet-report", &config->zCetReport)};
12862b4e6052SDaniel Kiss for (opt::Arg *arg : args.filtered(OPT_z)) {
12872b4e6052SDaniel Kiss std::pair<StringRef, StringRef> option =
12882b4e6052SDaniel Kiss StringRef(arg->getValue()).split('=');
12892b4e6052SDaniel Kiss for (auto reportArg : reports) {
12902b4e6052SDaniel Kiss if (option.first != reportArg.first)
12912b4e6052SDaniel Kiss continue;
12922b4e6052SDaniel Kiss if (!isValidReportString(option.second)) {
12932b4e6052SDaniel Kiss error(Twine("-z ") + reportArg.first + "= parameter " + option.second +
12942b4e6052SDaniel Kiss " is not recognized");
12952b4e6052SDaniel Kiss continue;
12962b4e6052SDaniel Kiss }
12972b4e6052SDaniel Kiss *reportArg.second = option.second;
12982b4e6052SDaniel Kiss }
12992b4e6052SDaniel Kiss }
13002b4e6052SDaniel Kiss
13014ce56b81SFangrui Song for (opt::Arg *arg : args.filtered(OPT_z)) {
13024ce56b81SFangrui Song std::pair<StringRef, StringRef> option =
13034ce56b81SFangrui Song StringRef(arg->getValue()).split('=');
13044ce56b81SFangrui Song if (option.first != "dead-reloc-in-nonalloc")
13054ce56b81SFangrui Song continue;
13064ce56b81SFangrui Song constexpr StringRef errPrefix = "-z dead-reloc-in-nonalloc=: ";
13074ce56b81SFangrui Song std::pair<StringRef, StringRef> kv = option.second.split('=');
13084ce56b81SFangrui Song if (kv.first.empty() || kv.second.empty()) {
13094ce56b81SFangrui Song error(errPrefix + "expected <section_glob>=<value>");
13104ce56b81SFangrui Song continue;
13114ce56b81SFangrui Song }
13124ce56b81SFangrui Song uint64_t v;
13134ce56b81SFangrui Song if (!to_integer(kv.second, v))
13144ce56b81SFangrui Song error(errPrefix + "expected a non-negative integer, but got '" +
13154ce56b81SFangrui Song kv.second + "'");
13164ce56b81SFangrui Song else if (Expected<GlobPattern> pat = GlobPattern::create(kv.first))
13174ce56b81SFangrui Song config->deadRelocInNonAlloc.emplace_back(std::move(*pat), v);
13184ce56b81SFangrui Song else
13194ce56b81SFangrui Song error(errPrefix + toString(pat.takeError()));
13204ce56b81SFangrui Song }
13214ce56b81SFangrui Song
1322259bb61cSFangrui Song cl::ResetAllOptionOccurrences();
1323259bb61cSFangrui Song
132447055bb1SRui Ueyama // Parse LTO options.
13253837f427SRui Ueyama if (auto *arg = args.getLastArg(OPT_plugin_opt_mcpu_eq))
132683d59e05SAlexandre Ganea parseClangOption(saver().save("-mcpu=" + StringRef(arg->getValue())),
13273837f427SRui Ueyama arg->getSpelling());
13280dd56dcdSRui Ueyama
1329cd5d5ce2SFangrui Song for (opt::Arg *arg : args.filtered(OPT_plugin_opt_eq_minus))
1330cd5d5ce2SFangrui Song parseClangOption(std::string("-") + arg->getValue(), arg->getSpelling());
1331cd5d5ce2SFangrui Song
1332cd5d5ce2SFangrui Song // GCC collect2 passes -plugin-opt=path/to/lto-wrapper with an absolute or
1333*abcd0341SBrett Werling // relative path. Just ignore. If not ended with "lto-wrapper" (or
1334*abcd0341SBrett Werling // "lto-wrapper.exe" for GCC cross-compiled for Windows), consider it an
1335cd5d5ce2SFangrui Song // unsupported LLVMgold.so option and error.
1336*abcd0341SBrett Werling for (opt::Arg *arg : args.filtered(OPT_plugin_opt_eq)) {
1337*abcd0341SBrett Werling StringRef v(arg->getValue());
1338*abcd0341SBrett Werling if (!v.endswith("lto-wrapper") && !v.endswith("lto-wrapper.exe"))
1339cd5d5ce2SFangrui Song error(arg->getSpelling() + ": unknown plugin option '" + arg->getValue() +
1340cd5d5ce2SFangrui Song "'");
1341*abcd0341SBrett Werling }
13425aab635eSRui Ueyama
13430c86198bSJakob Koschel config->passPlugins = args::getStrings(args, OPT_load_pass_plugins);
13440c86198bSJakob Koschel
13455aab635eSRui Ueyama // Parse -mllvm options.
13463837f427SRui Ueyama for (auto *arg : args.filtered(OPT_mllvm))
13473837f427SRui Ueyama parseClangOption(arg->getValue(), arg->getSpelling());
1348a1389724SRui Ueyama
1349eb4663d8SFangrui Song // --threads= takes a positive integer and provides the default value for
1350eb4663d8SFangrui Song // --thinlto-jobs=.
1351eb4663d8SFangrui Song if (auto *arg = args.getLastArg(OPT_threads)) {
1352eb4663d8SFangrui Song StringRef v(arg->getValue());
1353eb4663d8SFangrui Song unsigned threads = 0;
1354eb4663d8SFangrui Song if (!llvm::to_integer(v, threads, 0) || threads == 0)
1355eb4663d8SFangrui Song error(arg->getSpelling() + ": expected a positive integer, but got '" +
1356eb4663d8SFangrui Song arg->getValue() + "'");
1357eb4663d8SFangrui Song parallel::strategy = hardware_concurrency(threads);
1358eb4663d8SFangrui Song config->thinLTOJobs = v;
1359eb4663d8SFangrui Song }
1360eb4663d8SFangrui Song if (auto *arg = args.getLastArg(OPT_thinlto_jobs))
1361eb4663d8SFangrui Song config->thinLTOJobs = arg->getValue();
1362eb4663d8SFangrui Song
13633837f427SRui Ueyama if (config->ltoo > 3)
13643837f427SRui Ueyama error("invalid optimization level for LTO: " + Twine(config->ltoo));
13653837f427SRui Ueyama if (config->ltoPartitions == 0)
1366a4a643c6SRui Ueyama error("--lto-partitions: number of threads must be > 0");
136709158252SAlexandre Ganea if (!get_threadpool_strategy(config->thinLTOJobs))
136809158252SAlexandre Ganea error("--thinlto-jobs: invalid job count: " + config->thinLTOJobs);
1369a4a643c6SRui Ueyama
13703837f427SRui Ueyama if (config->splitStackAdjustSize < 0)
13714b5ec7fbSSean Fertile error("--split-stack-adjust-size: size must be >= 0");
13724b5ec7fbSSean Fertile
13734dc2fb12SFangrui Song // The text segment is traditionally the first segment, whose address equals
13744dc2fb12SFangrui Song // the base address. However, lld places the R PT_LOAD first. -Ttext-segment
13754dc2fb12SFangrui Song // is an old-fashioned option that does not play well with lld's layout.
13764dc2fb12SFangrui Song // Suggest --image-base as a likely alternative.
13774dc2fb12SFangrui Song if (args.hasArg(OPT_Ttext_segment))
13784dc2fb12SFangrui Song error("-Ttext-segment is not supported. Use --image-base if you "
13794dc2fb12SFangrui Song "intend to set the base address");
13804dc2fb12SFangrui Song
138194b08e3bSRui Ueyama // Parse ELF{32,64}{LE,BE} and CPU type.
13823837f427SRui Ueyama if (auto *arg = args.getLastArg(OPT_m)) {
13833837f427SRui Ueyama StringRef s = arg->getValue();
13843837f427SRui Ueyama std::tie(config->ekind, config->emachine, config->osabi) =
13853837f427SRui Ueyama parseEmulation(s);
13864750d79aSSimon Atanasyan config->mipsN32Abi =
13874750d79aSSimon Atanasyan (s.startswith("elf32btsmipn32") || s.startswith("elf32ltsmipn32"));
13883837f427SRui Ueyama config->emulation = s;
13899aa5686bSRui Ueyama }
13909aa5686bSRui Ueyama
1391bf6e259bSFangrui Song // Parse --hash-style={sysv,gnu,both}.
13923837f427SRui Ueyama if (auto *arg = args.getLastArg(OPT_hash_style)) {
13933837f427SRui Ueyama StringRef s = arg->getValue();
13943837f427SRui Ueyama if (s == "sysv")
13953837f427SRui Ueyama config->sysvHash = true;
13963837f427SRui Ueyama else if (s == "gnu")
13973837f427SRui Ueyama config->gnuHash = true;
13983837f427SRui Ueyama else if (s == "both")
13993837f427SRui Ueyama config->sysvHash = config->gnuHash = true;
1400d46753e4SGeorge Rimar else
1401bf6e259bSFangrui Song error("unknown --hash-style: " + s);
1402d46753e4SGeorge Rimar }
1403d46753e4SGeorge Rimar
14043837f427SRui Ueyama if (args.hasArg(OPT_print_map))
14053837f427SRui Ueyama config->mapFile = "-";
14061705f99cSRui Ueyama
14074e21c770SPeter Smith // Page alignment can be disabled by the -n (--nmagic) and -N (--omagic).
14084e21c770SPeter Smith // As PT_GNU_RELRO relies on Paging, do not create it when we have disabled
14094e21c770SPeter Smith // it.
14103837f427SRui Ueyama if (config->nmagic || config->omagic)
14113837f427SRui Ueyama config->zRelro = false;
1412d250618cSGeorge Rimar
14133837f427SRui Ueyama std::tie(config->buildId, config->buildIdVector) = getBuildId(args);
14143a41be27SRui Ueyama
14154a8de283SFangrui Song if (getZFlag(args, "pack-relative-relocs", "nopack-relative-relocs", false)) {
14164a8de283SFangrui Song config->relrGlibc = true;
14174a8de283SFangrui Song config->relrPackDynRelocs = true;
14184a8de283SFangrui Song } else {
14193837f427SRui Ueyama std::tie(config->androidPackDynRelocs, config->relrPackDynRelocs) =
14203837f427SRui Ueyama getPackDynRelocs(args);
14214a8de283SFangrui Song }
14225c54f15cSPeter Collingbourne
14233837f427SRui Ueyama if (auto *arg = args.getLastArg(OPT_symbol_ordering_file)){
14243837f427SRui Ueyama if (args.hasArg(OPT_call_graph_ordering_file))
1425a5d8d01dSTiancong Wang error("--symbol-ordering-file and --call-graph-order-file "
1426a5d8d01dSTiancong Wang "may not be used together");
14273837f427SRui Ueyama if (Optional<MemoryBufferRef> buffer = readFile(arg->getValue())){
14283837f427SRui Ueyama config->symbolOrderingFile = getSymbolOrderingFile(*buffer);
1429a5d8d01dSTiancong Wang // Also need to disable CallGraphProfileSort to prevent
1430a5d8d01dSTiancong Wang // LLD order symbols with CGProfile
14313837f427SRui Ueyama config->callGraphProfileSort = false;
1432a5d8d01dSTiancong Wang }
1433a5d8d01dSTiancong Wang }
14341a33c0f2SGeorge Rimar
1435e28a70daSFangrui Song assert(config->versionDefinitions.empty());
1436e28a70daSFangrui Song config->versionDefinitions.push_back(
143700809c88SFangrui Song {"local", (uint16_t)VER_NDX_LOCAL, {}, {}});
143800809c88SFangrui Song config->versionDefinitions.push_back(
143900809c88SFangrui Song {"global", (uint16_t)VER_NDX_GLOBAL, {}, {}});
1440e28a70daSFangrui Song
1441bfe02642SRui Ueyama // If --retain-symbol-file is used, we'll keep only the symbols listed in
14422bb88ab5SGeorge Rimar // the file and discard all others.
14433837f427SRui Ueyama if (auto *arg = args.getLastArg(OPT_retain_symbols_file)) {
144400809c88SFangrui Song config->versionDefinitions[VER_NDX_LOCAL].nonLocalPatterns.push_back(
1445e28a70daSFangrui Song {"*", /*isExternCpp=*/false, /*hasWildcard=*/true});
14463837f427SRui Ueyama if (Optional<MemoryBufferRef> buffer = readFile(arg->getValue()))
14473837f427SRui Ueyama for (StringRef s : args::getLines(*buffer))
144800809c88SFangrui Song config->versionDefinitions[VER_NDX_GLOBAL].nonLocalPatterns.push_back(
1449e28a70daSFangrui Song {s, /*isExternCpp=*/false, /*hasWildcard=*/false});
14502bb88ab5SGeorge Rimar }
14512bb88ab5SGeorge Rimar
145223257880SFangrui Song for (opt::Arg *arg : args.filtered(OPT_warn_backrefs_exclude)) {
145323257880SFangrui Song StringRef pattern(arg->getValue());
145423257880SFangrui Song if (Expected<GlobPattern> pat = GlobPattern::create(pattern))
145523257880SFangrui Song config->warnBackrefsExclude.push_back(std::move(*pat));
145623257880SFangrui Song else
145723257880SFangrui Song error(arg->getSpelling() + ": " + toString(pat.takeError()));
145823257880SFangrui Song }
145923257880SFangrui Song
14601d08a19aSFangrui Song // For -no-pie and -pie, --export-dynamic-symbol specifies defined symbols
14611d08a19aSFangrui Song // which should be exported. For -shared, references to matched non-local
14621d08a19aSFangrui Song // STV_DEFAULT symbols are not bound to definitions within the shared object,
14631d08a19aSFangrui Song // even if other options express a symbolic intention: -Bsymbolic,
14641d08a19aSFangrui Song // -Bsymbolic-functions (if STT_FUNC), --dynamic-list.
14651d08a19aSFangrui Song for (auto *arg : args.filtered(OPT_export_dynamic_symbol))
14661d08a19aSFangrui Song config->dynamicList.push_back(
14671d08a19aSFangrui Song {arg->getValue(), /*isExternCpp=*/false,
14681d08a19aSFangrui Song /*hasWildcard=*/hasWildcard(arg->getValue())});
14691d08a19aSFangrui Song
14701d08a19aSFangrui Song // --export-dynamic-symbol-list specifies a list of --export-dynamic-symbol
14711d08a19aSFangrui Song // patterns. --dynamic-list is --export-dynamic-symbol-list plus -Bsymbolic
14721d08a19aSFangrui Song // like semantics.
1473b06426daSFangrui Song config->symbolic =
1474b06426daSFangrui Song config->bsymbolic == BsymbolicKind::All || args.hasArg(OPT_dynamic_list);
147544361e5bSFangrui Song for (auto *arg :
147644361e5bSFangrui Song args.filtered(OPT_dynamic_list, OPT_export_dynamic_symbol_list))
14773837f427SRui Ueyama if (Optional<MemoryBufferRef> buffer = readFile(arg->getValue()))
14783837f427SRui Ueyama readDynamicList(*buffer);
14798d817f27SRui Ueyama
14803837f427SRui Ueyama for (auto *arg : args.filtered(OPT_version_script))
14813837f427SRui Ueyama if (Optional<std::string> path = searchScript(arg->getValue())) {
14823837f427SRui Ueyama if (Optional<MemoryBufferRef> buffer = readFile(*path))
14833837f427SRui Ueyama readVersionScript(*buffer);
1484c60f85d0SFangrui Song } else {
14853837f427SRui Ueyama error(Twine("cannot find version script ") + arg->getValue());
1486c60f85d0SFangrui Song }
14875d7a3d01SRui Ueyama }
148883f406cfSGeorge Rimar
1489d57e74b7SRui Ueyama // Some Config members do not directly correspond to any particular
1490d57e74b7SRui Ueyama // command line options, but computed based on other Config values.
1491d57e74b7SRui Ueyama // This function initialize such members. See Config.h for the details
1492d57e74b7SRui Ueyama // of these values.
setConfigs(opt::InputArgList & args)14933837f427SRui Ueyama static void setConfigs(opt::InputArgList &args) {
14943837f427SRui Ueyama ELFKind k = config->ekind;
14953837f427SRui Ueyama uint16_t m = config->emachine;
1496d57e74b7SRui Ueyama
14973837f427SRui Ueyama config->copyRelocs = (config->relocatable || config->emitRelocs);
14983837f427SRui Ueyama config->is64 = (k == ELF64LEKind || k == ELF64BEKind);
14993837f427SRui Ueyama config->isLE = (k == ELF32LEKind || k == ELF64LEKind);
15003837f427SRui Ueyama config->endianness = config->isLE ? endianness::little : endianness::big;
15013837f427SRui Ueyama config->isMips64EL = (k == ELF64LEKind && m == EM_MIPS);
15023837f427SRui Ueyama config->isPic = config->pie || config->shared;
15033837f427SRui Ueyama config->picThunk = args.hasArg(OPT_pic_veneer, config->isPic);
15043837f427SRui Ueyama config->wordsize = config->is64 ? 8 : 4;
1505e53890f3SRui Ueyama
1506e53890f3SRui Ueyama // ELF defines two different ways to store relocation addends as shown below:
1507e53890f3SRui Ueyama //
1508881c5eefSFangrui Song // Rel: Addends are stored to the location where relocations are applied. It
1509881c5eefSFangrui Song // cannot pack the full range of addend values for all relocation types, but
1510881c5eefSFangrui Song // this only affects relocation types that we don't support emitting as
1511881c5eefSFangrui Song // dynamic relocations (see getDynRel).
1512e53890f3SRui Ueyama // Rela: Addends are stored as part of relocation entry.
1513e53890f3SRui Ueyama //
1514e53890f3SRui Ueyama // In other words, Rela makes it easy to read addends at the price of extra
1515881c5eefSFangrui Song // 4 or 8 byte for each relocation entry.
1516e53890f3SRui Ueyama //
1517881c5eefSFangrui Song // We pick the format for dynamic relocations according to the psABI for each
1518881c5eefSFangrui Song // processor, but a contrary choice can be made if the dynamic loader
1519881c5eefSFangrui Song // supports.
1520881c5eefSFangrui Song config->isRela = getIsRela(args);
1521e53890f3SRui Ueyama
1522cfb60933SAlexander Richardson // If the output uses REL relocations we must store the dynamic relocation
1523cfb60933SAlexander Richardson // addends to the output sections. We also store addends for RELA relocations
1524cfb60933SAlexander Richardson // if --apply-dynamic-relocs is used.
1525cfb60933SAlexander Richardson // We default to not writing the addends when using RELA relocations since
1526cfb60933SAlexander Richardson // any standard conforming tool can find it in r_addend.
15273837f427SRui Ueyama config->writeAddends = args.hasFlag(OPT_apply_dynamic_relocs,
15287a7a81d9SRafael Espindola OPT_no_apply_dynamic_relocs, false) ||
15293837f427SRui Ueyama !config->isRela;
153035c5e564SAlex Richardson // Validation of dynamic relocation addends is on by default for assertions
153135c5e564SAlex Richardson // builds (for supported targets) and disabled otherwise. Ideally we would
153235c5e564SAlex Richardson // enable the debug checks for all targets, but currently not all targets
153335c5e564SAlex Richardson // have support for reading Elf_Rel addends, so we only enable for a subset.
153435c5e564SAlex Richardson #ifndef NDEBUG
153597fe6375SAlex Richardson bool checkDynamicRelocsDefault = m == EM_ARM || m == EM_386 || m == EM_MIPS ||
153697fe6375SAlex Richardson m == EM_X86_64 || m == EM_RISCV;
153735c5e564SAlex Richardson #else
153835c5e564SAlex Richardson bool checkDynamicRelocsDefault = false;
153935c5e564SAlex Richardson #endif
154035c5e564SAlex Richardson config->checkDynamicRelocs =
154135c5e564SAlex Richardson args.hasFlag(OPT_check_dynamic_relocations,
154235c5e564SAlex Richardson OPT_no_check_dynamic_relocations, checkDynamicRelocsDefault);
15433837f427SRui Ueyama config->tocOptimize =
15443837f427SRui Ueyama args.hasFlag(OPT_toc_optimize, OPT_no_toc_optimize, m == EM_PPC64);
1545cddb0dbcSNemanja Ivanovic config->pcRelOptimize =
1546cddb0dbcSNemanja Ivanovic args.hasFlag(OPT_pcrel_optimize, OPT_no_pcrel_optimize, m == EM_PPC64);
1547d57e74b7SRui Ueyama }
1548d57e74b7SRui Ueyama
isFormatBinary(StringRef s)15493837f427SRui Ueyama static bool isFormatBinary(StringRef s) {
15503837f427SRui Ueyama if (s == "binary")
15510aeb1199SRui Ueyama return true;
15523837f427SRui Ueyama if (s == "elf" || s == "default")
15530aeb1199SRui Ueyama return false;
1554bf6e259bSFangrui Song error("unknown --format value: " + s +
15550aeb1199SRui Ueyama " (supported formats: elf, default, binary)");
15560aeb1199SRui Ueyama return false;
15570aeb1199SRui Ueyama }
15580aeb1199SRui Ueyama
createFiles(opt::InputArgList & args)15593837f427SRui Ueyama void LinkerDriver::createFiles(opt::InputArgList &args) {
1560439341b9SJames Henderson llvm::TimeTraceScope timeScope("Load input files");
1561f75ea0b9SRui Ueyama // For --{push,pop}-state.
15623837f427SRui Ueyama std::vector<std::tuple<bool, bool, bool>> stack;
1563f75ea0b9SRui Ueyama
1564f75ea0b9SRui Ueyama // Iterate over argv to process input files and positional arguments.
1565b358daddSFangrui Song InputFile::isInGroup = false;
15663d854240SFangrui Song bool hasInput = false;
15673837f427SRui Ueyama for (auto *arg : args) {
15683837f427SRui Ueyama switch (arg->getOption().getID()) {
15694f37d575SGeorge Rimar case OPT_library:
15703837f427SRui Ueyama addLibrary(arg->getValue());
15713d854240SFangrui Song hasInput = true;
1572d912ee95SIgor Kudrin break;
1573d912ee95SIgor Kudrin case OPT_INPUT:
157449a3ad21SRui Ueyama addFile(arg->getValue(), /*withLOption=*/false);
15753d854240SFangrui Song hasInput = true;
1576d912ee95SIgor Kudrin break;
15770b89c55aSGeorge Rimar case OPT_defsym: {
15783837f427SRui Ueyama StringRef from;
15793837f427SRui Ueyama StringRef to;
15803837f427SRui Ueyama std::tie(from, to) = StringRef(arg->getValue()).split('=');
15813837f427SRui Ueyama if (from.empty() || to.empty())
15826506907aSFangrui Song error("--defsym: syntax error: " + StringRef(arg->getValue()));
158300d6f4bdSGeorge Rimar else
15846506907aSFangrui Song readDefsym(from, MemoryBufferRef(to, "--defsym"));
15850b89c55aSGeorge Rimar break;
15860b89c55aSGeorge Rimar }
1587a9424f39SMichael J. Spencer case OPT_script:
15883837f427SRui Ueyama if (Optional<std::string> path = searchScript(arg->getValue())) {
15893837f427SRui Ueyama if (Optional<MemoryBufferRef> mb = readFile(*path))
15903837f427SRui Ueyama readLinkerScript(*mb);
1591a9424f39SMichael J. Spencer break;
15921de78471SAlexander Richardson }
15933837f427SRui Ueyama error(Twine("cannot find linker script ") + arg->getValue());
15941de78471SAlexander Richardson break;
159535da9b6eSRui Ueyama case OPT_as_needed:
15963837f427SRui Ueyama config->asNeeded = true;
159735da9b6eSRui Ueyama break;
15980aeb1199SRui Ueyama case OPT_format:
15993837f427SRui Ueyama config->formatBinary = isFormatBinary(arg->getValue());
1600a9424f39SMichael J. Spencer break;
16014f98e0bcSGeorge Rimar case OPT_no_as_needed:
16023837f427SRui Ueyama config->asNeeded = false;
16034f98e0bcSGeorge Rimar break;
1604d912ee95SIgor Kudrin case OPT_Bstatic:
16054e21c770SPeter Smith case OPT_omagic:
16064e21c770SPeter Smith case OPT_nmagic:
16073837f427SRui Ueyama config->isStatic = true;
16084f98e0bcSGeorge Rimar break;
1609d912ee95SIgor Kudrin case OPT_Bdynamic:
16103837f427SRui Ueyama config->isStatic = false;
1611d912ee95SIgor Kudrin break;
16122696bbebSIgor Kudrin case OPT_whole_archive:
16133837f427SRui Ueyama inWholeArchive = true;
16144f98e0bcSGeorge Rimar break;
16152696bbebSIgor Kudrin case OPT_no_whole_archive:
16163837f427SRui Ueyama inWholeArchive = false;
16172696bbebSIgor Kudrin break;
16185a67a6ecSRui Ueyama case OPT_just_symbols:
16193837f427SRui Ueyama if (Optional<MemoryBufferRef> mb = readFile(arg->getValue())) {
1620242316bcSFangrui Song files.push_back(createObjFile(*mb));
16213837f427SRui Ueyama files.back()->justSymbols = true;
16225a67a6ecSRui Ueyama }
16235a67a6ecSRui Ueyama break;
16241d92aa73SRui Ueyama case OPT_start_group:
16253837f427SRui Ueyama if (InputFile::isInGroup)
16261d92aa73SRui Ueyama error("nested --start-group");
16273837f427SRui Ueyama InputFile::isInGroup = true;
16281d92aa73SRui Ueyama break;
16291d92aa73SRui Ueyama case OPT_end_group:
16303837f427SRui Ueyama if (!InputFile::isInGroup)
16311d92aa73SRui Ueyama error("stray --end-group");
16323837f427SRui Ueyama InputFile::isInGroup = false;
16333837f427SRui Ueyama ++InputFile::nextGroupId;
16341d92aa73SRui Ueyama break;
1635f8baa660SRui Ueyama case OPT_start_lib:
16363837f427SRui Ueyama if (inLib)
16372416d7fcSFangrui Song error("nested --start-lib");
16383837f427SRui Ueyama if (InputFile::isInGroup)
16392416d7fcSFangrui Song error("may not nest --start-lib in --start-group");
16403837f427SRui Ueyama inLib = true;
16413837f427SRui Ueyama InputFile::isInGroup = true;
16424f98e0bcSGeorge Rimar break;
1643f8baa660SRui Ueyama case OPT_end_lib:
16443837f427SRui Ueyama if (!inLib)
16452416d7fcSFangrui Song error("stray --end-lib");
16463837f427SRui Ueyama inLib = false;
16473837f427SRui Ueyama InputFile::isInGroup = false;
16483837f427SRui Ueyama ++InputFile::nextGroupId;
1649f8baa660SRui Ueyama break;
1650f75ea0b9SRui Ueyama case OPT_push_state:
16513837f427SRui Ueyama stack.emplace_back(config->asNeeded, config->isStatic, inWholeArchive);
1652f75ea0b9SRui Ueyama break;
1653f75ea0b9SRui Ueyama case OPT_pop_state:
16543837f427SRui Ueyama if (stack.empty()) {
1655f75ea0b9SRui Ueyama error("unbalanced --push-state/--pop-state");
1656f75ea0b9SRui Ueyama break;
1657f75ea0b9SRui Ueyama }
16583837f427SRui Ueyama std::tie(config->asNeeded, config->isStatic, inWholeArchive) = stack.back();
16593837f427SRui Ueyama stack.pop_back();
1660f75ea0b9SRui Ueyama break;
166184487f11SMichael J. Spencer }
1662f5c4aca9SRui Ueyama }
1663f5c4aca9SRui Ueyama
16643d854240SFangrui Song if (files.empty() && !hasInput && errorCount() == 0)
16658088ebe4SRui Ueyama error("no input files");
1666c185c012SRui Ueyama }
16675e64d3fbSRui Ueyama
16685e64d3fbSRui Ueyama // If -m <machine_type> was not given, infer it from object files.
inferMachineType()1669c185c012SRui Ueyama void LinkerDriver::inferMachineType() {
16703837f427SRui Ueyama if (config->ekind != ELFNoneKind)
1671c185c012SRui Ueyama return;
1672c185c012SRui Ueyama
16733837f427SRui Ueyama for (InputFile *f : files) {
16743837f427SRui Ueyama if (f->ekind == ELFNoneKind)
16755e64d3fbSRui Ueyama continue;
16763837f427SRui Ueyama config->ekind = f->ekind;
16773837f427SRui Ueyama config->emachine = f->emachine;
16783837f427SRui Ueyama config->osabi = f->osabi;
16793837f427SRui Ueyama config->mipsN32Abi = config->emachine == EM_MIPS && isMipsN32Abi(f);
1680c185c012SRui Ueyama return;
16815e64d3fbSRui Ueyama }
1682c185c012SRui Ueyama error("target emulation unknown: -m or at least one .o file required");
16833ce825edSRui Ueyama }
16843ce825edSRui Ueyama
1685e4eadb6aSRui Ueyama // Parse -z max-page-size=<value>. The default value is defined by
1686e4eadb6aSRui Ueyama // each target.
getMaxPageSize(opt::InputArgList & args)16873837f427SRui Ueyama static uint64_t getMaxPageSize(opt::InputArgList &args) {
16883837f427SRui Ueyama uint64_t val = args::getZOptionValue(args, OPT_z, "max-page-size",
16893837f427SRui Ueyama target->defaultMaxPageSize);
169085cfd917SFangrui Song if (!isPowerOf2_64(val)) {
1691e4eadb6aSRui Ueyama error("max-page-size: value isn't a power of 2");
169285cfd917SFangrui Song return target->defaultMaxPageSize;
169385cfd917SFangrui Song }
16943837f427SRui Ueyama if (config->nmagic || config->omagic) {
16953837f427SRui Ueyama if (val != target->defaultMaxPageSize)
16964e21c770SPeter Smith warn("-z max-page-size set, but paging disabled by omagic or nmagic");
16974e21c770SPeter Smith return 1;
16984e21c770SPeter Smith }
16993837f427SRui Ueyama return val;
17004e21c770SPeter Smith }
17014e21c770SPeter Smith
17024e21c770SPeter Smith // Parse -z common-page-size=<value>. The default value is defined by
17034e21c770SPeter Smith // each target.
getCommonPageSize(opt::InputArgList & args)17043837f427SRui Ueyama static uint64_t getCommonPageSize(opt::InputArgList &args) {
17053837f427SRui Ueyama uint64_t val = args::getZOptionValue(args, OPT_z, "common-page-size",
17063837f427SRui Ueyama target->defaultCommonPageSize);
170785cfd917SFangrui Song if (!isPowerOf2_64(val)) {
17084e21c770SPeter Smith error("common-page-size: value isn't a power of 2");
170985cfd917SFangrui Song return target->defaultCommonPageSize;
171085cfd917SFangrui Song }
17113837f427SRui Ueyama if (config->nmagic || config->omagic) {
17123837f427SRui Ueyama if (val != target->defaultCommonPageSize)
17134e21c770SPeter Smith warn("-z common-page-size set, but paging disabled by omagic or nmagic");
17144e21c770SPeter Smith return 1;
17154e21c770SPeter Smith }
171647cfe8f3SFangrui Song // commonPageSize can't be larger than maxPageSize.
17173837f427SRui Ueyama if (val > config->maxPageSize)
17183837f427SRui Ueyama val = config->maxPageSize;
17193837f427SRui Ueyama return val;
1720e4eadb6aSRui Ueyama }
1721e4eadb6aSRui Ueyama
1722bf6e259bSFangrui Song // Parses --image-base option.
getImageBase(opt::InputArgList & args)17233837f427SRui Ueyama static Optional<uint64_t> getImageBase(opt::InputArgList &args) {
172447cfe8f3SFangrui Song // Because we are using "Config->maxPageSize" here, this function has to be
1725b5ca92efSJames Henderson // called after the variable is initialized.
17263837f427SRui Ueyama auto *arg = args.getLastArg(OPT_image_base);
17273837f427SRui Ueyama if (!arg)
1728b5ca92efSJames Henderson return None;
1729c5dd543dSRui Ueyama
17303837f427SRui Ueyama StringRef s = arg->getValue();
17313837f427SRui Ueyama uint64_t v;
17323837f427SRui Ueyama if (!to_integer(s, v)) {
17336506907aSFangrui Song error("--image-base: number expected, but got " + s);
1734c5dd543dSRui Ueyama return 0;
1735c5dd543dSRui Ueyama }
17363837f427SRui Ueyama if ((v % config->maxPageSize) != 0)
17376506907aSFangrui Song warn("--image-base: address isn't multiple of page size: " + s);
17383837f427SRui Ueyama return v;
1739c5dd543dSRui Ueyama }
1740c5dd543dSRui Ueyama
1741d1f8b816SRui Ueyama // Parses `--exclude-libs=lib,lib,...`.
1742d1f8b816SRui Ueyama // The library names may be delimited by commas or colons.
getExcludeLibs(opt::InputArgList & args)17433837f427SRui Ueyama static DenseSet<StringRef> getExcludeLibs(opt::InputArgList &args) {
17443837f427SRui Ueyama DenseSet<StringRef> ret;
17453837f427SRui Ueyama for (auto *arg : args.filtered(OPT_exclude_libs)) {
17463837f427SRui Ueyama StringRef s = arg->getValue();
1747d1f8b816SRui Ueyama for (;;) {
17483837f427SRui Ueyama size_t pos = s.find_first_of(",:");
17493837f427SRui Ueyama if (pos == StringRef::npos)
1750d1f8b816SRui Ueyama break;
17513837f427SRui Ueyama ret.insert(s.substr(0, pos));
17523837f427SRui Ueyama s = s.substr(pos + 1);
1753d1f8b816SRui Ueyama }
17543837f427SRui Ueyama ret.insert(s);
1755d1f8b816SRui Ueyama }
17563837f427SRui Ueyama return ret;
1757d1f8b816SRui Ueyama }
1758d1f8b816SRui Ueyama
1759bf6e259bSFangrui Song // Handles the --exclude-libs option. If a static library file is specified
1760bf6e259bSFangrui Song // by the --exclude-libs option, all public symbols from the archive become
1761d1f8b816SRui Ueyama // private unless otherwise specified by version scripts or something.
1762d1f8b816SRui Ueyama // A special library name "ALL" means all archive files.
1763d1f8b816SRui Ueyama //
1764d1f8b816SRui Ueyama // This is not a popular option, but some programs such as bionic libc use it.
excludeLibs(opt::InputArgList & args)17653837f427SRui Ueyama static void excludeLibs(opt::InputArgList &args) {
17663837f427SRui Ueyama DenseSet<StringRef> libs = getExcludeLibs(args);
17673837f427SRui Ueyama bool all = libs.count("ALL");
1768d1f8b816SRui Ueyama
17693837f427SRui Ueyama auto visit = [&](InputFile *file) {
1770132553b8SFangrui Song if (file->archiveName.empty() ||
1771132553b8SFangrui Song !(all || libs.count(path::filename(file->archiveName))))
1772132553b8SFangrui Song return;
1773132553b8SFangrui Song ArrayRef<Symbol *> symbols = file->getSymbols();
1774132553b8SFangrui Song if (isa<ELFFileBase>(file))
1775132553b8SFangrui Song symbols = cast<ELFFileBase>(file)->getGlobalSymbols();
1776132553b8SFangrui Song for (Symbol *sym : symbols)
1777132553b8SFangrui Song if (!sym->isUndefined() && sym->file == file)
17783837f427SRui Ueyama sym->versionId = VER_NDX_LOCAL;
1779a2125b12SYi Kong };
1780a2125b12SYi Kong
17819a572164SFangrui Song for (ELFFileBase *file : ctx->objectFiles)
17823837f427SRui Ueyama visit(file);
1783a2125b12SYi Kong
17849a572164SFangrui Song for (BitcodeFile *file : ctx->bitcodeFiles)
17853837f427SRui Ueyama visit(file);
1786d1f8b816SRui Ueyama }
1787d1f8b816SRui Ueyama
17887bee6e30SFangrui Song // Force Sym to be entered in the output.
handleUndefined(Symbol * sym,const char * option)1789a954bb18SFangrui Song static void handleUndefined(Symbol *sym, const char *option) {
179043f4b037SRui Ueyama // Since a symbol may not be used inside the program, LTO may
1791cc013f62SRui Ueyama // eliminate it. Mark the symbol as "used" to prevent it.
17923837f427SRui Ueyama sym->isUsedInRegularObj = true;
1793cc013f62SRui Ueyama
1794a954bb18SFangrui Song if (!sym->isLazy())
1795a954bb18SFangrui Song return;
179609401dfcSFangrui Song sym->extract();
1797a954bb18SFangrui Song if (!config->whyExtract.empty())
1798e980f16dSFangrui Song ctx->whyExtractRecords.emplace_back(option, sym->file, *sym);
1799cc013f62SRui Ueyama }
1800cc013f62SRui Ueyama
18015976a3f5SNico Weber // As an extension to GNU linkers, lld supports a variant of `-u`
180243f4b037SRui Ueyama // which accepts wildcard patterns. All symbols that match a given
180343f4b037SRui Ueyama // pattern are handled as if they were given by `-u`.
handleUndefinedGlob(StringRef arg)18043837f427SRui Ueyama static void handleUndefinedGlob(StringRef arg) {
18053837f427SRui Ueyama Expected<GlobPattern> pat = GlobPattern::create(arg);
18063837f427SRui Ueyama if (!pat) {
18073837f427SRui Ueyama error("--undefined-glob: " + toString(pat.takeError()));
180843f4b037SRui Ueyama return;
180943f4b037SRui Ueyama }
181043f4b037SRui Ueyama
181109401dfcSFangrui Song // Calling sym->extract() in the loop is not safe because it may add new
181209401dfcSFangrui Song // symbols to the symbol table, invalidating the current iterator.
18134d38d768SFangrui Song SmallVector<Symbol *, 0> syms;
181409401dfcSFangrui Song for (Symbol *sym : symtab->symbols())
1815e9262edfSFangrui Song if (!sym->isPlaceholder() && pat->match(sym->getName()))
18163837f427SRui Ueyama syms.push_back(sym);
181743f4b037SRui Ueyama
18183837f427SRui Ueyama for (Symbol *sym : syms)
1819a954bb18SFangrui Song handleUndefined(sym, "--undefined-glob");
182043f4b037SRui Ueyama }
182143f4b037SRui Ueyama
handleLibcall(StringRef name)18223837f427SRui Ueyama static void handleLibcall(StringRef name) {
18233837f427SRui Ueyama Symbol *sym = symtab->find(name);
18243837f427SRui Ueyama if (!sym || !sym->isLazy())
182598930115SPeter Collingbourne return;
182698930115SPeter Collingbourne
18273837f427SRui Ueyama MemoryBufferRef mb;
18283d854240SFangrui Song mb = cast<LazyObject>(sym)->file->mb;
182998930115SPeter Collingbourne
18303837f427SRui Ueyama if (isBitcode(mb))
183109401dfcSFangrui Song sym->extract();
183298930115SPeter Collingbourne }
183398930115SPeter Collingbourne
writeArchiveStats()1834e980f16dSFangrui Song static void writeArchiveStats() {
18357fd3849bSFangrui Song if (config->printArchiveStats.empty())
18367fd3849bSFangrui Song return;
18377fd3849bSFangrui Song
18387fd3849bSFangrui Song std::error_code ec;
18397fd3849bSFangrui Song raw_fd_ostream os(config->printArchiveStats, ec, sys::fs::OF_None);
18407fd3849bSFangrui Song if (ec) {
18417fd3849bSFangrui Song error("--print-archive-stats=: cannot open " + config->printArchiveStats +
18427fd3849bSFangrui Song ": " + ec.message());
18437fd3849bSFangrui Song return;
18447fd3849bSFangrui Song }
18457fd3849bSFangrui Song
18467fd3849bSFangrui Song os << "members\textracted\tarchive\n";
18477fd3849bSFangrui Song
18487fd3849bSFangrui Song SmallVector<StringRef, 0> archives;
18497fd3849bSFangrui Song DenseMap<CachedHashStringRef, unsigned> all, extracted;
18509a572164SFangrui Song for (ELFFileBase *file : ctx->objectFiles)
18517fd3849bSFangrui Song if (file->archiveName.size())
18527fd3849bSFangrui Song ++extracted[CachedHashStringRef(file->archiveName)];
18539a572164SFangrui Song for (BitcodeFile *file : ctx->bitcodeFiles)
18547fd3849bSFangrui Song if (file->archiveName.size())
18557fd3849bSFangrui Song ++extracted[CachedHashStringRef(file->archiveName)];
1856e980f16dSFangrui Song for (std::pair<StringRef, unsigned> f : driver->archiveFiles) {
18577fd3849bSFangrui Song unsigned &v = extracted[CachedHashString(f.first)];
18587fd3849bSFangrui Song os << f.second << '\t' << v << '\t' << f.first << '\n';
18597fd3849bSFangrui Song // If the archive occurs multiple times, other instances have a count of 0.
18607fd3849bSFangrui Song v = 0;
18617fd3849bSFangrui Song }
18627fd3849bSFangrui Song }
18637fd3849bSFangrui Song
writeWhyExtract()1864e980f16dSFangrui Song static void writeWhyExtract() {
18657fd3849bSFangrui Song if (config->whyExtract.empty())
18667fd3849bSFangrui Song return;
18677fd3849bSFangrui Song
18687fd3849bSFangrui Song std::error_code ec;
18697fd3849bSFangrui Song raw_fd_ostream os(config->whyExtract, ec, sys::fs::OF_None);
18707fd3849bSFangrui Song if (ec) {
18717fd3849bSFangrui Song error("cannot open --why-extract= file " + config->whyExtract + ": " +
18727fd3849bSFangrui Song ec.message());
18737fd3849bSFangrui Song return;
18747fd3849bSFangrui Song }
18757fd3849bSFangrui Song
18767fd3849bSFangrui Song os << "reference\textracted\tsymbol\n";
1877e980f16dSFangrui Song for (auto &entry : ctx->whyExtractRecords) {
18787fd3849bSFangrui Song os << std::get<0>(entry) << '\t' << toString(std::get<1>(entry)) << '\t'
18797fd3849bSFangrui Song << toString(std::get<2>(entry)) << '\n';
18807fd3849bSFangrui Song }
18817fd3849bSFangrui Song }
18827fd3849bSFangrui Song
reportBackrefs()1883e980f16dSFangrui Song static void reportBackrefs() {
1884e980f16dSFangrui Song for (auto &ref : ctx->backwardReferences) {
1885d14d8664SFangrui Song const Symbol &sym = *ref.first;
1886d14d8664SFangrui Song std::string to = toString(ref.second.second);
1887d14d8664SFangrui Song // Some libraries have known problems and can cause noise. Filter them out
1888d14d8664SFangrui Song // with --warn-backrefs-exclude=. The value may look like (for --start-lib)
1889d14d8664SFangrui Song // *.o or (archive member) *.a(*.o).
1890d14d8664SFangrui Song bool exclude = false;
1891d14d8664SFangrui Song for (const llvm::GlobPattern &pat : config->warnBackrefsExclude)
1892d14d8664SFangrui Song if (pat.match(to)) {
1893d14d8664SFangrui Song exclude = true;
1894d14d8664SFangrui Song break;
1895d14d8664SFangrui Song }
1896d14d8664SFangrui Song if (!exclude)
1897d14d8664SFangrui Song warn("backward reference detected: " + sym.getName() + " in " +
1898d14d8664SFangrui Song toString(ref.second.first) + " refers to " + to);
1899d14d8664SFangrui Song }
1900d14d8664SFangrui Song }
1901d14d8664SFangrui Song
190281eeabbdSPetr Hosek // Handle --dependency-file=<path>. If that option is given, lld creates a
190381eeabbdSPetr Hosek // file at a given path with the following contents:
190481eeabbdSPetr Hosek //
190581eeabbdSPetr Hosek // <output-file>: <input-file> ...
190681eeabbdSPetr Hosek //
190781eeabbdSPetr Hosek // <input-file>:
190881eeabbdSPetr Hosek //
190981eeabbdSPetr Hosek // where <output-file> is a pathname of an output file and <input-file>
191081eeabbdSPetr Hosek // ... is a list of pathnames of all input files. `make` command can read a
191181eeabbdSPetr Hosek // file in the above format and interpret it as a dependency info. We write
191281eeabbdSPetr Hosek // phony targets for every <input-file> to avoid an error when that file is
191381eeabbdSPetr Hosek // removed.
191481eeabbdSPetr Hosek //
191581eeabbdSPetr Hosek // This option is useful if you want to make your final executable to depend
191681eeabbdSPetr Hosek // on all input files including system libraries. Here is why.
191781eeabbdSPetr Hosek //
191881eeabbdSPetr Hosek // When you write a Makefile, you usually write it so that the final
191981eeabbdSPetr Hosek // executable depends on all user-generated object files. Normally, you
192081eeabbdSPetr Hosek // don't make your executable to depend on system libraries (such as libc)
192181eeabbdSPetr Hosek // because you don't know the exact paths of libraries, even though system
192281eeabbdSPetr Hosek // libraries that are linked to your executable statically are technically a
192381eeabbdSPetr Hosek // part of your program. By using --dependency-file option, you can make
192481eeabbdSPetr Hosek // lld to dump dependency info so that you can maintain exact dependencies
192581eeabbdSPetr Hosek // easily.
writeDependencyFile()192681eeabbdSPetr Hosek static void writeDependencyFile() {
192781eeabbdSPetr Hosek std::error_code ec;
1928518d955fSDuncan P. N. Exon Smith raw_fd_ostream os(config->dependencyFile, ec, sys::fs::OF_None);
192981eeabbdSPetr Hosek if (ec) {
193081eeabbdSPetr Hosek error("cannot open " + config->dependencyFile + ": " + ec.message());
193181eeabbdSPetr Hosek return;
193281eeabbdSPetr Hosek }
193381eeabbdSPetr Hosek
193481eeabbdSPetr Hosek // We use the same escape rules as Clang/GCC which are accepted by Make/Ninja:
193581eeabbdSPetr Hosek // * A space is escaped by a backslash which itself must be escaped.
193681eeabbdSPetr Hosek // * A hash sign is escaped by a single backslash.
193781eeabbdSPetr Hosek // * $ is escapes as $$.
193881eeabbdSPetr Hosek auto printFilename = [](raw_fd_ostream &os, StringRef filename) {
193981eeabbdSPetr Hosek llvm::SmallString<256> nativePath;
194081eeabbdSPetr Hosek llvm::sys::path::native(filename.str(), nativePath);
194181eeabbdSPetr Hosek llvm::sys::path::remove_dots(nativePath, /*remove_dot_dot=*/true);
194281eeabbdSPetr Hosek for (unsigned i = 0, e = nativePath.size(); i != e; ++i) {
194381eeabbdSPetr Hosek if (nativePath[i] == '#') {
194481eeabbdSPetr Hosek os << '\\';
194581eeabbdSPetr Hosek } else if (nativePath[i] == ' ') {
194681eeabbdSPetr Hosek os << '\\';
194781eeabbdSPetr Hosek unsigned j = i;
194881eeabbdSPetr Hosek while (j > 0 && nativePath[--j] == '\\')
194981eeabbdSPetr Hosek os << '\\';
195081eeabbdSPetr Hosek } else if (nativePath[i] == '$') {
195181eeabbdSPetr Hosek os << '$';
195281eeabbdSPetr Hosek }
195381eeabbdSPetr Hosek os << nativePath[i];
195481eeabbdSPetr Hosek }
195581eeabbdSPetr Hosek };
195681eeabbdSPetr Hosek
195781eeabbdSPetr Hosek os << config->outputFile << ":";
195881eeabbdSPetr Hosek for (StringRef path : config->dependencyFiles) {
195981eeabbdSPetr Hosek os << " \\\n ";
196081eeabbdSPetr Hosek printFilename(os, path);
196181eeabbdSPetr Hosek }
196281eeabbdSPetr Hosek os << "\n";
196381eeabbdSPetr Hosek
196481eeabbdSPetr Hosek for (StringRef path : config->dependencyFiles) {
196581eeabbdSPetr Hosek os << "\n";
196681eeabbdSPetr Hosek printFilename(os, path);
196781eeabbdSPetr Hosek os << ":\n";
196881eeabbdSPetr Hosek }
196981eeabbdSPetr Hosek }
197081eeabbdSPetr Hosek
19715c073a94SRui Ueyama // Replaces common symbols with defined symbols reside in .bss sections.
19725c073a94SRui Ueyama // This function is called after all symbol names are resolved. As a
19735c073a94SRui Ueyama // result, the passes after the symbol resolution won't see any
19745c073a94SRui Ueyama // symbols of type CommonSymbol.
replaceCommonSymbols()19755c073a94SRui Ueyama static void replaceCommonSymbols() {
1976439341b9SJames Henderson llvm::TimeTraceScope timeScope("Replace common symbols");
19779a572164SFangrui Song for (ELFFileBase *file : ctx->objectFiles) {
197840fae4d8SFangrui Song if (!file->hasCommonSyms)
197940fae4d8SFangrui Song continue;
198040fae4d8SFangrui Song for (Symbol *sym : file->getGlobalSymbols()) {
19813837f427SRui Ueyama auto *s = dyn_cast<CommonSymbol>(sym);
19823837f427SRui Ueyama if (!s)
1983a2fc9644SFangrui Song continue;
19845c073a94SRui Ueyama
19853837f427SRui Ueyama auto *bss = make<BssSection>("COMMON", s->size, s->alignment);
19863837f427SRui Ueyama bss->file = s->file;
19873837f427SRui Ueyama inputSections.push_back(bss);
1988977a1a52SFangrui Song s->replace(Defined{s->file, StringRef(), s->binding, s->stOther, s->type,
198949a3ad21SRui Ueyama /*value=*/0, s->size, bss});
1990a2fc9644SFangrui Song }
19915c073a94SRui Ueyama }
199240fae4d8SFangrui Song }
19935c073a94SRui Ueyama
19948b01b638SFangrui Song // If all references to a DSO happen to be weak, the DSO is not added to
19958b01b638SFangrui Song // DT_NEEDED. If that happens, replace ShardSymbol with Undefined to avoid
19968b01b638SFangrui Song // dangling references to an unneeded DSO. Use a weak binding to avoid
19978b01b638SFangrui Song // --no-allow-shlib-undefined diagnostics. Similarly, demote lazy symbols.
demoteSharedAndLazySymbols()19988b01b638SFangrui Song static void demoteSharedAndLazySymbols() {
19998b01b638SFangrui Song llvm::TimeTraceScope timeScope("Demote shared and lazy symbols");
2000a2fc9644SFangrui Song for (Symbol *sym : symtab->symbols()) {
20013837f427SRui Ueyama auto *s = dyn_cast<SharedSymbol>(sym);
200247d18be5SFangrui Song if (!(s && !cast<SharedFile>(s->file)->isNeeded) && !sym->isLazy())
2003a2fc9644SFangrui Song continue;
20047d476192SRui Ueyama
200571ec1e50SFangrui Song bool used = sym->used;
20068b01b638SFangrui Song uint8_t binding = sym->isLazy() ? sym->binding : uint8_t(STB_WEAK);
200771ec1e50SFangrui Song sym->replace(
20088b01b638SFangrui Song Undefined{nullptr, sym->getName(), binding, sym->stOther, sym->type});
200971ec1e50SFangrui Song sym->used = used;
201071ec1e50SFangrui Song sym->versionId = VER_NDX_GLOBAL;
2011a2fc9644SFangrui Song }
201261376d9bSRafael Espindola }
201361376d9bSRafael Espindola
201447cfe8f3SFangrui Song // The section referred to by `s` is considered address-significant. Set the
201547cfe8f3SFangrui Song // keepUnique flag on the section if appropriate.
markAddrsig(Symbol * s)20163837f427SRui Ueyama static void markAddrsig(Symbol *s) {
20173837f427SRui Ueyama if (auto *d = dyn_cast_or_null<Defined>(s))
20183837f427SRui Ueyama if (d->section)
2019a052206cSPeter Collingbourne // We don't need to keep text sections unique under --icf=all even if they
2020a052206cSPeter Collingbourne // are address-significant.
20213837f427SRui Ueyama if (config->icf == ICFLevel::Safe || !(d->section->flags & SHF_EXECINSTR))
20223837f427SRui Ueyama d->section->keepUnique = true;
2023a327a4c3SPeter Collingbourne }
2024a327a4c3SPeter Collingbourne
2025dbef8cc6SPeter Smith // Record sections that define symbols mentioned in --keep-unique <symbol>
2026a327a4c3SPeter Collingbourne // and symbols referred to by address-significance tables. These sections are
2027a327a4c3SPeter Collingbourne // ineligible for ICF.
2028a327a4c3SPeter Collingbourne template <class ELFT>
findKeepUniqueSections(opt::InputArgList & args)20293837f427SRui Ueyama static void findKeepUniqueSections(opt::InputArgList &args) {
20303837f427SRui Ueyama for (auto *arg : args.filtered(OPT_keep_unique)) {
20313837f427SRui Ueyama StringRef name = arg->getValue();
20323837f427SRui Ueyama auto *d = dyn_cast_or_null<Defined>(symtab->find(name));
20333837f427SRui Ueyama if (!d || !d->section) {
20343837f427SRui Ueyama warn("could not find symbol " + name + " to keep unique");
2035a052206cSPeter Collingbourne continue;
2036a052206cSPeter Collingbourne }
20373837f427SRui Ueyama d->section->keepUnique = true;
2038dbef8cc6SPeter Smith }
2039a327a4c3SPeter Collingbourne
2040a052206cSPeter Collingbourne // --icf=all --ignore-data-address-equality means that we can ignore
2041a052206cSPeter Collingbourne // the dynsym and address-significance tables entirely.
20423837f427SRui Ueyama if (config->icf == ICFLevel::All && config->ignoreDataAddressEquality)
2043a052206cSPeter Collingbourne return;
2044a052206cSPeter Collingbourne
2045a327a4c3SPeter Collingbourne // Symbols in the dynsym could be address-significant in other executables
2046a327a4c3SPeter Collingbourne // or DSOs, so we conservatively mark them as address-significant.
2047a2fc9644SFangrui Song for (Symbol *sym : symtab->symbols())
20483837f427SRui Ueyama if (sym->includeInDynsym())
20493837f427SRui Ueyama markAddrsig(sym);
2050a327a4c3SPeter Collingbourne
2051a327a4c3SPeter Collingbourne // Visit the address-significance table in each object file and mark each
2052a327a4c3SPeter Collingbourne // referenced symbol as address-significant.
20539a572164SFangrui Song for (InputFile *f : ctx->objectFiles) {
20543837f427SRui Ueyama auto *obj = cast<ObjFile<ELFT>>(f);
20553837f427SRui Ueyama ArrayRef<Symbol *> syms = obj->getSymbols();
20563837f427SRui Ueyama if (obj->addrsigSec) {
20573837f427SRui Ueyama ArrayRef<uint8_t> contents =
20584845531fSGeorgii Rymar check(obj->getObj().getSectionContents(*obj->addrsigSec));
20593837f427SRui Ueyama const uint8_t *cur = contents.begin();
20603837f427SRui Ueyama while (cur != contents.end()) {
20613837f427SRui Ueyama unsigned size;
20623837f427SRui Ueyama const char *err;
20633837f427SRui Ueyama uint64_t symIndex = decodeULEB128(cur, &size, contents.end(), &err);
20643837f427SRui Ueyama if (err)
20653837f427SRui Ueyama fatal(toString(f) + ": could not decode addrsig section: " + err);
20663837f427SRui Ueyama markAddrsig(syms[symIndex]);
20673837f427SRui Ueyama cur += size;
2068a327a4c3SPeter Collingbourne }
2069a327a4c3SPeter Collingbourne } else {
2070a327a4c3SPeter Collingbourne // If an object file does not have an address-significance table,
2071a327a4c3SPeter Collingbourne // conservatively mark all of its symbols as address-significant.
20723837f427SRui Ueyama for (Symbol *s : syms)
20733837f427SRui Ueyama markAddrsig(s);
2074a327a4c3SPeter Collingbourne }
2075a327a4c3SPeter Collingbourne }
2076dbef8cc6SPeter Smith }
2077dbef8cc6SPeter Smith
2078ba2816beSPeter Collingbourne // This function reads a symbol partition specification section. These sections
2079ba2816beSPeter Collingbourne // are used to control which partition a symbol is allocated to. See
2080ba2816beSPeter Collingbourne // https://lld.llvm.org/Partitions.html for more details on partitions.
2081ba2816beSPeter Collingbourne template <typename ELFT>
readSymbolPartitionSection(InputSectionBase * s)20823837f427SRui Ueyama static void readSymbolPartitionSection(InputSectionBase *s) {
2083ba2816beSPeter Collingbourne // Read the relocation that refers to the partition's entry point symbol.
20843837f427SRui Ueyama Symbol *sym;
2085ecc93ed2SFangrui Song const RelsOrRelas<ELFT> rels = s->template relsOrRelas<ELFT>();
2086ecc93ed2SFangrui Song if (rels.areRelocsRel())
2087ecc93ed2SFangrui Song sym = &s->getFile<ELFT>()->getRelocTargetSym(rels.rels[0]);
2088ba2816beSPeter Collingbourne else
2089ecc93ed2SFangrui Song sym = &s->getFile<ELFT>()->getRelocTargetSym(rels.relas[0]);
20903837f427SRui Ueyama if (!isa<Defined>(sym) || !sym->includeInDynsym())
2091ba2816beSPeter Collingbourne return;
2092ba2816beSPeter Collingbourne
2093ae1ba619SFangrui Song StringRef partName = reinterpret_cast<const char *>(s->rawData.data());
20943837f427SRui Ueyama for (Partition &part : partitions) {
20953837f427SRui Ueyama if (part.name == partName) {
20963837f427SRui Ueyama sym->partition = part.getNumber();
2097ba2816beSPeter Collingbourne return;
2098ba2816beSPeter Collingbourne }
2099ba2816beSPeter Collingbourne }
2100ba2816beSPeter Collingbourne
2101ba2816beSPeter Collingbourne // Forbid partitions from being used on incompatible targets, and forbid them
2102ba2816beSPeter Collingbourne // from being used together with various linker features that assume a single
2103ba2816beSPeter Collingbourne // set of output sections.
21043837f427SRui Ueyama if (script->hasSectionsCommand)
21053837f427SRui Ueyama error(toString(s->file) +
2106ba2816beSPeter Collingbourne ": partitions cannot be used with the SECTIONS command");
21073837f427SRui Ueyama if (script->hasPhdrsCommands())
21083837f427SRui Ueyama error(toString(s->file) +
2109ba2816beSPeter Collingbourne ": partitions cannot be used with the PHDRS command");
21103837f427SRui Ueyama if (!config->sectionStartMap.empty())
21113837f427SRui Ueyama error(toString(s->file) + ": partitions cannot be used with "
2112ba2816beSPeter Collingbourne "--section-start, -Ttext, -Tdata or -Tbss");
21133837f427SRui Ueyama if (config->emachine == EM_MIPS)
21143837f427SRui Ueyama error(toString(s->file) + ": partitions cannot be used on this target");
2115ba2816beSPeter Collingbourne
2116ba2816beSPeter Collingbourne // Impose a limit of no more than 254 partitions. This limit comes from the
2117ba2816beSPeter Collingbourne // sizes of the Partition fields in InputSectionBase and Symbol, as well as
2118ba2816beSPeter Collingbourne // the amount of space devoted to the partition number in RankFlags.
21193837f427SRui Ueyama if (partitions.size() == 254)
2120ba2816beSPeter Collingbourne fatal("may not have more than 254 partitions");
2121ba2816beSPeter Collingbourne
21223837f427SRui Ueyama partitions.emplace_back();
21233837f427SRui Ueyama Partition &newPart = partitions.back();
21243837f427SRui Ueyama newPart.name = partName;
21253837f427SRui Ueyama sym->partition = newPart.getNumber();
2126ba2816beSPeter Collingbourne }
2127ba2816beSPeter Collingbourne
addUnusedUndefined(StringRef name,uint8_t binding=STB_GLOBAL)21287c74ce3cSFangrui Song static Symbol *addUnusedUndefined(StringRef name,
21297c74ce3cSFangrui Song uint8_t binding = STB_GLOBAL) {
21308ca46bbaSFangrui Song return symtab->addSymbol(Undefined{nullptr, name, binding, STV_DEFAULT, 0});
21317bee6e30SFangrui Song }
21327bee6e30SFangrui Song
markBuffersAsDontNeed(bool skipLinkedOutput)2133a96fe1bfSFangrui Song static void markBuffersAsDontNeed(bool skipLinkedOutput) {
2134a96fe1bfSFangrui Song // With --thinlto-index-only, all buffers are nearly unused from now on
2135a96fe1bfSFangrui Song // (except symbol/section names used by infrequent passes). Mark input file
2136a96fe1bfSFangrui Song // buffers as MADV_DONTNEED so that these pages can be reused by the expensive
2137a96fe1bfSFangrui Song // thin link, saving memory.
2138a96fe1bfSFangrui Song if (skipLinkedOutput) {
21399a572164SFangrui Song for (MemoryBuffer &mb : llvm::make_pointee_range(ctx->memoryBuffers))
2140a96fe1bfSFangrui Song mb.dontNeedIfMmap();
2141a96fe1bfSFangrui Song return;
2142a96fe1bfSFangrui Song }
2143a96fe1bfSFangrui Song
2144a96fe1bfSFangrui Song // Otherwise, just mark MemoryBuffers backing BitcodeFiles.
2145a96fe1bfSFangrui Song DenseSet<const char *> bufs;
21469a572164SFangrui Song for (BitcodeFile *file : ctx->bitcodeFiles)
2147a96fe1bfSFangrui Song bufs.insert(file->mb.getBufferStart());
21489a572164SFangrui Song for (BitcodeFile *file : ctx->lazyBitcodeFiles)
2149a96fe1bfSFangrui Song bufs.insert(file->mb.getBufferStart());
21509a572164SFangrui Song for (MemoryBuffer &mb : llvm::make_pointee_range(ctx->memoryBuffers))
2151a96fe1bfSFangrui Song if (bufs.count(mb.getBufferStart()))
2152a96fe1bfSFangrui Song mb.dontNeedIfMmap();
2153a96fe1bfSFangrui Song }
2154a96fe1bfSFangrui Song
21550baaf45bSRui Ueyama // This function is where all the optimizations of link-time
21560baaf45bSRui Ueyama // optimization takes place. When LTO is in use, some input files are
21570baaf45bSRui Ueyama // not in native object file format but in the LLVM bitcode format.
21580baaf45bSRui Ueyama // This function compiles bitcode files into a few big native files
21590baaf45bSRui Ueyama // using LLVM functions and replaces bitcode symbols with the results.
21600baaf45bSRui Ueyama // Because all bitcode files that the program consists of are passed to
21610baaf45bSRui Ueyama // the compiler at once, it can do a whole-program optimization.
2162a96fe1bfSFangrui Song template <class ELFT>
compileBitcodeFiles(bool skipLinkedOutput)2163a96fe1bfSFangrui Song void LinkerDriver::compileBitcodeFiles(bool skipLinkedOutput) {
2164e7cb3744SRussell Gallop llvm::TimeTraceScope timeScope("LTO");
21650baaf45bSRui Ueyama // Compile bitcode files and replace bitcode symbols.
21663837f427SRui Ueyama lto.reset(new BitcodeCompiler);
21679a572164SFangrui Song for (BitcodeFile *file : ctx->bitcodeFiles)
21683837f427SRui Ueyama lto->add(*file);
21690baaf45bSRui Ueyama
21709a572164SFangrui Song if (!ctx->bitcodeFiles.empty())
2171a96fe1bfSFangrui Song markBuffersAsDontNeed(skipLinkedOutput);
2172a96fe1bfSFangrui Song
21733837f427SRui Ueyama for (InputFile *file : lto->compile()) {
21743837f427SRui Ueyama auto *obj = cast<ObjFile<ELFT>>(file);
217549a3ad21SRui Ueyama obj->parse(/*ignoreComdats=*/true);
21764542c18eSFangrui Song
21774542c18eSFangrui Song // Parse '@' in symbol names for non-relocatable output.
21784542c18eSFangrui Song if (!config->relocatable)
21793837f427SRui Ueyama for (Symbol *sym : obj->getGlobalSymbols())
21807924b381SFangrui Song if (sym->hasVersionSuffix)
21813837f427SRui Ueyama sym->parseSymbolVersion();
21829a572164SFangrui Song ctx->objectFiles.push_back(obj);
21830baaf45bSRui Ueyama }
21840baaf45bSRui Ueyama }
21850baaf45bSRui Ueyama
218607b4536bSRui Ueyama // The --wrap option is a feature to rename symbols so that you can write
2187bf6e259bSFangrui Song // wrappers for existing functions. If you pass `--wrap=foo`, all
21889b2b3274SMartin Storsjö // occurrences of symbol `foo` are resolved to `__wrap_foo` (so, you are
21899b2b3274SMartin Storsjö // expected to write `__wrap_foo` function as a wrapper). The original
21909b2b3274SMartin Storsjö // symbol becomes accessible as `__real_foo`, so you can call that from your
219107b4536bSRui Ueyama // wrapper.
219207b4536bSRui Ueyama //
2193bf6e259bSFangrui Song // This data structure is instantiated for each --wrap option.
219407b4536bSRui Ueyama struct WrappedSymbol {
21953837f427SRui Ueyama Symbol *sym;
21963837f427SRui Ueyama Symbol *real;
21973837f427SRui Ueyama Symbol *wrap;
219807b4536bSRui Ueyama };
219907b4536bSRui Ueyama
2200bf6e259bSFangrui Song // Handles --wrap option.
220107b4536bSRui Ueyama //
220207b4536bSRui Ueyama // This function instantiates wrapper symbols. At this point, they seem
220307b4536bSRui Ueyama // like they are not being used at all, so we explicitly set some flags so
220407b4536bSRui Ueyama // that LTO won't eliminate them.
addWrappedSymbols(opt::InputArgList & args)22053837f427SRui Ueyama static std::vector<WrappedSymbol> addWrappedSymbols(opt::InputArgList &args) {
22063837f427SRui Ueyama std::vector<WrappedSymbol> v;
22073837f427SRui Ueyama DenseSet<StringRef> seen;
220807b4536bSRui Ueyama
22093837f427SRui Ueyama for (auto *arg : args.filtered(OPT_wrap)) {
22103837f427SRui Ueyama StringRef name = arg->getValue();
22113837f427SRui Ueyama if (!seen.insert(name).second)
221207b4536bSRui Ueyama continue;
221307b4536bSRui Ueyama
22143837f427SRui Ueyama Symbol *sym = symtab->find(name);
22152a04f5c4SShoaib Meenai if (!sym)
221607b4536bSRui Ueyama continue;
221707b4536bSRui Ueyama
221883d59e05SAlexandre Ganea Symbol *real = addUnusedUndefined(saver().save("__real_" + name));
22197c74ce3cSFangrui Song Symbol *wrap =
222083d59e05SAlexandre Ganea addUnusedUndefined(saver().save("__wrap_" + name), sym->binding);
22213837f427SRui Ueyama v.push_back({sym, real, wrap});
222207b4536bSRui Ueyama
222307b4536bSRui Ueyama // We want to tell LTO not to inline symbols to be overwritten
222407b4536bSRui Ueyama // because LTO doesn't know the final symbol contents after renaming.
22257c675923SFangrui Song real->scriptDefined = true;
22267c675923SFangrui Song sym->scriptDefined = true;
222707b4536bSRui Ueyama
22281af25a98SShoaib Meenai // If a symbol is referenced in any object file, bitcode file or shared
22291af25a98SShoaib Meenai // object, mark its redirection target (foo for __real_foo and __wrap_foo
22301af25a98SShoaib Meenai // for foo) as referenced after redirection, which will be used to tell LTO
22311af25a98SShoaib Meenai // to not eliminate the redirection target. If the object file defining the
22321af25a98SShoaib Meenai // symbol also references it, we cannot easily distinguish the case from
22331af25a98SShoaib Meenai // cases where the symbol is not referenced. Retain the redirection target
22341af25a98SShoaib Meenai // in this case because we choose to wrap symbol references regardless of
22351af25a98SShoaib Meenai // whether the symbol is defined
2236d24b94f0SFangrui Song // (https://sourceware.org/bugzilla/show_bug.cgi?id=26358).
22371af25a98SShoaib Meenai if (real->referenced || real->isDefined())
22381af25a98SShoaib Meenai sym->referencedAfterWrap = true;
2239d24b94f0SFangrui Song if (sym->referenced || sym->isDefined())
22401af25a98SShoaib Meenai wrap->referencedAfterWrap = true;
224107b4536bSRui Ueyama }
22423837f427SRui Ueyama return v;
224307b4536bSRui Ueyama }
224407b4536bSRui Ueyama
2245bf6e259bSFangrui Song // Do renaming for --wrap and foo@v1 by updating pointers to symbols.
224607b4536bSRui Ueyama //
224707b4536bSRui Ueyama // When this function is executed, only InputFiles and symbol table
224807b4536bSRui Ueyama // contain pointers to symbol objects. We visit them to replace pointers,
224907b4536bSRui Ueyama // so that wrapped symbols are swapped as instructed by the command line.
redirectSymbols(ArrayRef<WrappedSymbol> wrapped)2250941e9336SFangrui Song static void redirectSymbols(ArrayRef<WrappedSymbol> wrapped) {
2251941e9336SFangrui Song llvm::TimeTraceScope timeScope("Redirect symbols");
22523837f427SRui Ueyama DenseMap<Symbol *, Symbol *> map;
22533837f427SRui Ueyama for (const WrappedSymbol &w : wrapped) {
22543837f427SRui Ueyama map[w.sym] = w.wrap;
22553837f427SRui Ueyama map[w.real] = w.sym;
225607b4536bSRui Ueyama }
2257941e9336SFangrui Song for (Symbol *sym : symtab->symbols()) {
22587924b381SFangrui Song // Enumerate symbols with a non-default version (foo@v1). hasVersionSuffix
22597924b381SFangrui Song // filters out most symbols but is not sufficient.
22607924b381SFangrui Song if (!sym->hasVersionSuffix)
22617924b381SFangrui Song continue;
2262941e9336SFangrui Song const char *suffix1 = sym->getVersionSuffix();
2263941e9336SFangrui Song if (suffix1[0] != '@' || suffix1[1] == '@')
2264941e9336SFangrui Song continue;
2265941e9336SFangrui Song
226666d44304SFangrui Song // Check the existing symbol foo. We have two special cases to handle:
226766d44304SFangrui Song //
226866d44304SFangrui Song // * There is a definition of foo@v1 and foo@@v1.
226966d44304SFangrui Song // * There is a definition of foo@v1 and foo.
22707924b381SFangrui Song Defined *sym2 = dyn_cast_or_null<Defined>(symtab->find(sym->getName()));
227166d44304SFangrui Song if (!sym2)
2272941e9336SFangrui Song continue;
227366d44304SFangrui Song const char *suffix2 = sym2->getVersionSuffix();
227466d44304SFangrui Song if (suffix2[0] == '@' && suffix2[1] == '@' &&
227566d44304SFangrui Song strcmp(suffix1 + 1, suffix2 + 2) == 0) {
2276941e9336SFangrui Song // foo@v1 and foo@@v1 should be merged, so redirect foo@v1 to foo@@v1.
227766d44304SFangrui Song map.try_emplace(sym, sym2);
2278941e9336SFangrui Song // If both foo@v1 and foo@@v1 are defined and non-weak, report a duplicate
2279941e9336SFangrui Song // definition error.
228088d66f6eSFangrui Song if (sym->isDefined())
228188d66f6eSFangrui Song sym2->checkDuplicate(cast<Defined>(*sym));
228266d44304SFangrui Song sym2->resolve(*sym);
2283941e9336SFangrui Song // Eliminate foo@v1 from the symbol table.
2284941e9336SFangrui Song sym->symbolKind = Symbol::PlaceholderKind;
2285e9262edfSFangrui Song sym->isUsedInRegularObj = false;
228666d44304SFangrui Song } else if (auto *sym1 = dyn_cast<Defined>(sym)) {
228766d44304SFangrui Song if (sym2->versionId > VER_NDX_GLOBAL
228866d44304SFangrui Song ? config->versionDefinitions[sym2->versionId].name == suffix1 + 1
228966d44304SFangrui Song : sym1->section == sym2->section && sym1->value == sym2->value) {
229066d44304SFangrui Song // Due to an assembler design flaw, if foo is defined, .symver foo,
229166d44304SFangrui Song // foo@v1 defines both foo and foo@v1. Unless foo is bound to a
22920a6aad59SFangrui Song // different version, GNU ld makes foo@v1 canonical and eliminates foo.
229366d44304SFangrui Song // Emulate its behavior, otherwise we would have foo or foo@@v1 beside
229466d44304SFangrui Song // foo@v1. foo@v1 and foo combining does not apply if they are not
229566d44304SFangrui Song // defined in the same place.
229666d44304SFangrui Song map.try_emplace(sym2, sym);
229766d44304SFangrui Song sym2->symbolKind = Symbol::PlaceholderKind;
2298e9262edfSFangrui Song sym2->isUsedInRegularObj = false;
229966d44304SFangrui Song }
230066d44304SFangrui Song }
2301941e9336SFangrui Song }
2302941e9336SFangrui Song
2303941e9336SFangrui Song if (map.empty())
2304941e9336SFangrui Song return;
230507b4536bSRui Ueyama
230607b4536bSRui Ueyama // Update pointers in input files.
23079a572164SFangrui Song parallelForEach(ctx->objectFiles, [&](ELFFileBase *file) {
2308e6941800SFangrui Song for (Symbol *&sym : file->getMutableGlobalSymbols())
2309e6941800SFangrui Song if (Symbol *s = map.lookup(sym))
2310e6941800SFangrui Song sym = s;
231107b4536bSRui Ueyama });
231207b4536bSRui Ueyama
231307b4536bSRui Ueyama // Update pointers in the symbol table.
23143837f427SRui Ueyama for (const WrappedSymbol &w : wrapped)
23153837f427SRui Ueyama symtab->wrap(w.sym, w.real, w.wrap);
231607b4536bSRui Ueyama }
231707b4536bSRui Ueyama
checkAndReportMissingFeature(StringRef config,uint32_t features,uint32_t mask,const Twine & report)23182b4e6052SDaniel Kiss static void checkAndReportMissingFeature(StringRef config, uint32_t features,
23192b4e6052SDaniel Kiss uint32_t mask, const Twine &report) {
23202b4e6052SDaniel Kiss if (!(features & mask)) {
23212b4e6052SDaniel Kiss if (config == "error")
23222b4e6052SDaniel Kiss error(report);
23232b4e6052SDaniel Kiss else if (config == "warning")
23242b4e6052SDaniel Kiss warn(report);
23252b4e6052SDaniel Kiss }
23262b4e6052SDaniel Kiss }
23272b4e6052SDaniel Kiss
23282057f836SRui Ueyama // To enable CET (x86's hardware-assited control flow enforcement), each
23292057f836SRui Ueyama // source file must be compiled with -fcf-protection. Object files compiled
23302057f836SRui Ueyama // with the flag contain feature flags indicating that they are compatible
23312057f836SRui Ueyama // with CET. We enable the feature only when all object files are compatible
23322057f836SRui Ueyama // with CET.
23332057f836SRui Ueyama //
2334e208208aSPeter Smith // This is also the case with AARCH64's BTI and PAC which use the similar
2335e208208aSPeter Smith // GNU_PROPERTY_AARCH64_FEATURE_1_AND mechanism.
getAndFeatures()233672a005bfSFangrui Song static uint32_t getAndFeatures() {
23373837f427SRui Ueyama if (config->emachine != EM_386 && config->emachine != EM_X86_64 &&
23383837f427SRui Ueyama config->emachine != EM_AARCH64)
23392057f836SRui Ueyama return 0;
23402057f836SRui Ueyama
23413837f427SRui Ueyama uint32_t ret = -1;
23429a572164SFangrui Song for (ELFFileBase *f : ctx->objectFiles) {
234372a005bfSFangrui Song uint32_t features = f->andFeatures;
23442b4e6052SDaniel Kiss
23452b4e6052SDaniel Kiss checkAndReportMissingFeature(
23462b4e6052SDaniel Kiss config->zBtiReport, features, GNU_PROPERTY_AARCH64_FEATURE_1_BTI,
23472b4e6052SDaniel Kiss toString(f) + ": -z bti-report: file does not have "
23482b4e6052SDaniel Kiss "GNU_PROPERTY_AARCH64_FEATURE_1_BTI property");
23492b4e6052SDaniel Kiss
23502b4e6052SDaniel Kiss checkAndReportMissingFeature(
23512b4e6052SDaniel Kiss config->zCetReport, features, GNU_PROPERTY_X86_FEATURE_1_IBT,
23522b4e6052SDaniel Kiss toString(f) + ": -z cet-report: file does not have "
23532b4e6052SDaniel Kiss "GNU_PROPERTY_X86_FEATURE_1_IBT property");
23542b4e6052SDaniel Kiss
23552b4e6052SDaniel Kiss checkAndReportMissingFeature(
23562b4e6052SDaniel Kiss config->zCetReport, features, GNU_PROPERTY_X86_FEATURE_1_SHSTK,
23572b4e6052SDaniel Kiss toString(f) + ": -z cet-report: file does not have "
23582b4e6052SDaniel Kiss "GNU_PROPERTY_X86_FEATURE_1_SHSTK property");
23592b4e6052SDaniel Kiss
2360105a2700SFangrui Song if (config->zForceBti && !(features & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) {
23612b4e6052SDaniel Kiss features |= GNU_PROPERTY_AARCH64_FEATURE_1_BTI;
23622b4e6052SDaniel Kiss if (config->zBtiReport == "none")
2363b6162622SDaniel Kiss warn(toString(f) + ": -z force-bti: file does not have "
2364b6162622SDaniel Kiss "GNU_PROPERTY_AARCH64_FEATURE_1_BTI property");
23657cd429f2SFangrui Song } else if (config->zForceIbt &&
23667cd429f2SFangrui Song !(features & GNU_PROPERTY_X86_FEATURE_1_IBT)) {
23672b4e6052SDaniel Kiss if (config->zCetReport == "none")
23687cd429f2SFangrui Song warn(toString(f) + ": -z force-ibt: file does not have "
23697cd429f2SFangrui Song "GNU_PROPERTY_X86_FEATURE_1_IBT property");
23707cd429f2SFangrui Song features |= GNU_PROPERTY_X86_FEATURE_1_IBT;
23717cd429f2SFangrui Song }
2372b6162622SDaniel Kiss if (config->zPacPlt && !(features & GNU_PROPERTY_AARCH64_FEATURE_1_PAC)) {
2373b6162622SDaniel Kiss warn(toString(f) + ": -z pac-plt: file does not have "
2374b6162622SDaniel Kiss "GNU_PROPERTY_AARCH64_FEATURE_1_PAC property");
2375b6162622SDaniel Kiss features |= GNU_PROPERTY_AARCH64_FEATURE_1_PAC;
2376b6162622SDaniel Kiss }
23773837f427SRui Ueyama ret &= features;
23782057f836SRui Ueyama }
2379e208208aSPeter Smith
23807cd429f2SFangrui Song // Force enable Shadow Stack.
23817cd429f2SFangrui Song if (config->zShstk)
23827cd429f2SFangrui Song ret |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
2383e208208aSPeter Smith
23843837f427SRui Ueyama return ret;
23852057f836SRui Ueyama }
23862057f836SRui Ueyama
initializeLocalSymbols(ELFFileBase * file)2387a815424cSFangrui Song static void initializeLocalSymbols(ELFFileBase *file) {
2388a815424cSFangrui Song switch (config->ekind) {
2389a815424cSFangrui Song case ELF32LEKind:
2390a815424cSFangrui Song cast<ObjFile<ELF32LE>>(file)->initializeLocalSymbols();
2391a815424cSFangrui Song break;
2392a815424cSFangrui Song case ELF32BEKind:
2393a815424cSFangrui Song cast<ObjFile<ELF32BE>>(file)->initializeLocalSymbols();
2394a815424cSFangrui Song break;
2395a815424cSFangrui Song case ELF64LEKind:
2396a815424cSFangrui Song cast<ObjFile<ELF64LE>>(file)->initializeLocalSymbols();
2397a815424cSFangrui Song break;
2398a815424cSFangrui Song case ELF64BEKind:
2399a815424cSFangrui Song cast<ObjFile<ELF64BE>>(file)->initializeLocalSymbols();
2400a815424cSFangrui Song break;
2401a815424cSFangrui Song default:
2402a815424cSFangrui Song llvm_unreachable("");
2403a815424cSFangrui Song }
2404a815424cSFangrui Song }
2405a815424cSFangrui Song
postParseObjectFile(ELFFileBase * file)240688d66f6eSFangrui Song static void postParseObjectFile(ELFFileBase *file) {
240788d66f6eSFangrui Song switch (config->ekind) {
240888d66f6eSFangrui Song case ELF32LEKind:
240988d66f6eSFangrui Song cast<ObjFile<ELF32LE>>(file)->postParse();
241088d66f6eSFangrui Song break;
241188d66f6eSFangrui Song case ELF32BEKind:
241288d66f6eSFangrui Song cast<ObjFile<ELF32BE>>(file)->postParse();
241388d66f6eSFangrui Song break;
241488d66f6eSFangrui Song case ELF64LEKind:
241588d66f6eSFangrui Song cast<ObjFile<ELF64LE>>(file)->postParse();
241688d66f6eSFangrui Song break;
241788d66f6eSFangrui Song case ELF64BEKind:
241888d66f6eSFangrui Song cast<ObjFile<ELF64BE>>(file)->postParse();
241988d66f6eSFangrui Song break;
242088d66f6eSFangrui Song default:
242188d66f6eSFangrui Song llvm_unreachable("");
242288d66f6eSFangrui Song }
242388d66f6eSFangrui Song }
242488d66f6eSFangrui Song
2425630a382bSRui Ueyama // Do actual linking. Note that when this function is called,
2426630a382bSRui Ueyama // all linker scripts have already been parsed.
link(opt::InputArgList & args)24277518d38fSFangrui Song void LinkerDriver::link(opt::InputArgList &args) {
2428e7cb3744SRussell Gallop llvm::TimeTraceScope timeScope("Link", StringRef("LinkerDriver::Link"));
2429bf6e259bSFangrui Song // If a --hash-style option was not given, set to a default value,
2430d46753e4SGeorge Rimar // which varies depending on the target.
24313837f427SRui Ueyama if (!args.hasArg(OPT_hash_style)) {
24323837f427SRui Ueyama if (config->emachine == EM_MIPS)
24333837f427SRui Ueyama config->sysvHash = true;
2434d46753e4SGeorge Rimar else
24353837f427SRui Ueyama config->sysvHash = config->gnuHash = true;
2436d46753e4SGeorge Rimar }
2437d46753e4SGeorge Rimar
2438630a382bSRui Ueyama // Default output filename is "a.out" by the Unix tradition.
24393837f427SRui Ueyama if (config->outputFile.empty())
24403837f427SRui Ueyama config->outputFile = "a.out";
2441630a382bSRui Ueyama
2442b7a90ef4SJames Henderson // Fail early if the output file or map file is not writable. If a user has a
2443b7a90ef4SJames Henderson // long link, e.g. due to a large LTO link, they do not wish to run it and
2444b7a90ef4SJames Henderson // find that it failed because there was a mistake in their command-line.
2445439341b9SJames Henderson {
2446439341b9SJames Henderson llvm::TimeTraceScope timeScope("Create output files");
24473837f427SRui Ueyama if (auto e = tryCreateFile(config->outputFile))
2448439341b9SJames Henderson error("cannot open output file " + config->outputFile + ": " +
2449439341b9SJames Henderson e.message());
24503837f427SRui Ueyama if (auto e = tryCreateFile(config->mapFile))
24513837f427SRui Ueyama error("cannot open map file " + config->mapFile + ": " + e.message());
2452a954bb18SFangrui Song if (auto e = tryCreateFile(config->whyExtract))
2453a954bb18SFangrui Song error("cannot open --why-extract= file " + config->whyExtract + ": " +
2454a954bb18SFangrui Song e.message());
2455439341b9SJames Henderson }
2456b8a59c8aSBob Haarman if (errorCount())
2457f327999aSRui Ueyama return;
2458f327999aSRui Ueyama
245934bf8677SRui Ueyama // Use default entry point name if no name was given via the command
246034bf8677SRui Ueyama // line nor linker scripts. For some reason, MIPS entry point name is
24614de746f3SRui Ueyama // different from others.
24623837f427SRui Ueyama config->warnMissingEntry =
24633837f427SRui Ueyama (!config->entry.empty() || (!config->shared && !config->relocatable));
24643837f427SRui Ueyama if (config->entry.empty() && !config->relocatable)
24653837f427SRui Ueyama config->entry = (config->emachine == EM_MIPS) ? "__start" : "_start";
24664de746f3SRui Ueyama
246769c778c0SRui Ueyama // Handle --trace-symbol.
24683837f427SRui Ueyama for (auto *arg : args.filtered(OPT_trace_symbol))
24693837f427SRui Ueyama symtab->insert(arg->getValue())->traced = true;
247069c778c0SRui Ueyama
24717bee6e30SFangrui Song // Handle -u/--undefined before input files. If both a.a and b.so define foo,
247209401dfcSFangrui Song // -u foo a.a b.so will extract a.a.
24737bee6e30SFangrui Song for (StringRef name : config->undefined)
2474db1988f0SFangrui Song addUnusedUndefined(name)->referenced = true;
24757bee6e30SFangrui Song
24764de746f3SRui Ueyama // Add all files to the symbol table. This will add almost all
24771d16515fSBen Dunbobbin // symbols that we need to the symbol table. This process might
24781d16515fSBen Dunbobbin // add files to the link, via autolinking, these files are always
24791d16515fSBen Dunbobbin // appended to the Files vector.
2480e7cb3744SRussell Gallop {
2481e7cb3744SRussell Gallop llvm::TimeTraceScope timeScope("Parse input files");
2482439341b9SJames Henderson for (size_t i = 0; i < files.size(); ++i) {
2483439341b9SJames Henderson llvm::TimeTraceScope timeScope("Parse input files", files[i]->getName());
24843837f427SRui Ueyama parseFile(files[i]);
2485e7cb3744SRussell Gallop }
2486439341b9SJames Henderson }
24873967ea05SEugene Leviant
2488e05e2f8bSRafael Espindola // Now that we have every file, we can decide if we will need a
2489e05e2f8bSRafael Espindola // dynamic symbol table.
2490e05e2f8bSRafael Espindola // We need one if we were asked to export dynamic symbols or if we are
2491e05e2f8bSRafael Espindola // producing a shared library.
2492e05e2f8bSRafael Espindola // We also need one if any shared libraries are used and for pie executables
2493e05e2f8bSRafael Espindola // (probably because the dynamic linker needs it).
24943837f427SRui Ueyama config->hasDynSymTab =
24959a572164SFangrui Song !ctx->sharedFiles.empty() || config->isPic || config->exportDynamic;
2496e05e2f8bSRafael Espindola
249751d193f8SGeorge Rimar // Some symbols (such as __ehdr_start) are defined lazily only when there
249851d193f8SGeorge Rimar // are undefined symbols for them, so we add these to trigger that logic.
24997cc32860SShoaib Meenai for (StringRef name : script->referencedSymbols) {
25007cc32860SShoaib Meenai Symbol *sym = addUnusedUndefined(name);
25017cc32860SShoaib Meenai sym->isUsedInRegularObj = true;
25027cc32860SShoaib Meenai sym->referenced = true;
25037cc32860SShoaib Meenai }
250451d193f8SGeorge Rimar
25057bee6e30SFangrui Song // Prevent LTO from removing any definition referenced by -u.
25067bee6e30SFangrui Song for (StringRef name : config->undefined)
25077bee6e30SFangrui Song if (Defined *sym = dyn_cast_or_null<Defined>(symtab->find(name)))
25087bee6e30SFangrui Song sym->isUsedInRegularObj = true;
2509a215e7cbSRui Ueyama
25102da4e521SPeter Collingbourne // If an entry symbol is in a static archive, pull out that file now.
25113837f427SRui Ueyama if (Symbol *sym = symtab->find(config->entry))
2512a954bb18SFangrui Song handleUndefined(sym, "--entry");
251343f4b037SRui Ueyama
251443f4b037SRui Ueyama // Handle the `--undefined-glob <pattern>` options.
25153837f427SRui Ueyama for (StringRef pat : args::getStrings(args, OPT_undefined_glob))
25163837f427SRui Ueyama handleUndefinedGlob(pat);
25173967ea05SEugene Leviant
2518f95273f7SRui Ueyama // Mark -init and -fini symbols so that the LTO doesn't eliminate them.
2519c4fc26b4SIgor Kudrin if (Symbol *sym = dyn_cast_or_null<Defined>(symtab->find(config->init)))
2520f95273f7SRui Ueyama sym->isUsedInRegularObj = true;
2521c4fc26b4SIgor Kudrin if (Symbol *sym = dyn_cast_or_null<Defined>(symtab->find(config->fini)))
2522f95273f7SRui Ueyama sym->isUsedInRegularObj = true;
2523f95273f7SRui Ueyama
25242da4e521SPeter Collingbourne // If any of our inputs are bitcode files, the LTO code generator may create
25252da4e521SPeter Collingbourne // references to certain library functions that might not be explicit in the
25262da4e521SPeter Collingbourne // bitcode file's symbol table. If any of those library functions are defined
25272da4e521SPeter Collingbourne // in a bitcode file in an archive member, we need to arrange to use LTO to
25282da4e521SPeter Collingbourne // compile those archive members by adding them to the link beforehand.
25292da4e521SPeter Collingbourne //
253098930115SPeter Collingbourne // However, adding all libcall symbols to the link can have undesired
253198930115SPeter Collingbourne // consequences. For example, the libgcc implementation of
253298930115SPeter Collingbourne // __sync_val_compare_and_swap_8 on 32-bit ARM pulls in an .init_array entry
253398930115SPeter Collingbourne // that aborts the program if the Linux kernel does not support 64-bit
253498930115SPeter Collingbourne // atomics, which would prevent the program from running even if it does not
253598930115SPeter Collingbourne // use 64-bit atomics.
253698930115SPeter Collingbourne //
253798930115SPeter Collingbourne // Therefore, we only add libcall symbols to the link before LTO if we have
253898930115SPeter Collingbourne // to, i.e. if the symbol's definition is in bitcode. Any other required
253998930115SPeter Collingbourne // libcall symbols will be added to the link after LTO when we add the LTO
254098930115SPeter Collingbourne // object file to the link.
25419a572164SFangrui Song if (!ctx->bitcodeFiles.empty())
2542dd63b9f5SSteven Wu for (auto *s : lto::LTO::getRuntimeLibcallSymbols())
25433837f427SRui Ueyama handleLibcall(s);
25442da4e521SPeter Collingbourne
2545f456c3aeSFangrui Song // Archive members defining __wrap symbols may be extracted.
2546f456c3aeSFangrui Song std::vector<WrappedSymbol> wrapped = addWrappedSymbols(args);
2547f456c3aeSFangrui Song
254888d66f6eSFangrui Song // No more lazy bitcode can be extracted at this point. Do post parse work
254988d66f6eSFangrui Song // like checking duplicate symbols.
25509a572164SFangrui Song parallelForEach(ctx->objectFiles, initializeLocalSymbols);
25519a572164SFangrui Song parallelForEach(ctx->objectFiles, postParseObjectFile);
25529a572164SFangrui Song parallelForEach(ctx->bitcodeFiles,
25539a572164SFangrui Song [](BitcodeFile *file) { file->postParse(); });
25547c7702b3SFangrui Song for (auto &it : ctx->nonPrevailingSyms) {
25557c7702b3SFangrui Song Symbol &sym = *it.first;
25567c7702b3SFangrui Song sym.replace(Undefined{sym.file, sym.getName(), sym.binding, sym.stOther,
25577c7702b3SFangrui Song sym.type, it.second});
25587c7702b3SFangrui Song cast<Undefined>(sym).nonPrevailing = true;
25597c7702b3SFangrui Song }
25607c7702b3SFangrui Song ctx->nonPrevailingSyms.clear();
25617c7702b3SFangrui Song for (const DuplicateSymbol &d : ctx->duplicates)
25627c7702b3SFangrui Song reportDuplicate(*d.sym, d.file, d.section, d.value);
25637c7702b3SFangrui Song ctx->duplicates.clear();
256488d66f6eSFangrui Song
25654de746f3SRui Ueyama // Return if there were name resolution errors.
2566b8a59c8aSBob Haarman if (errorCount())
25674de746f3SRui Ueyama return;
25683ce825edSRui Ueyama
25693345c9acSIgor Kudrin // We want to declare linker script's symbols early,
25703345c9acSIgor Kudrin // so that we can version them.
25713345c9acSIgor Kudrin // They also might be exported if referenced by DSOs.
25723837f427SRui Ueyama script->declareSymbols();
25733345c9acSIgor Kudrin
2574ac2224c0SFangrui Song // Handle --exclude-libs. This is before scanVersionScript() due to a
2575ac2224c0SFangrui Song // workaround for Android ndk: for a defined versioned symbol in an archive
2576ac2224c0SFangrui Song // without a version node in the version script, Android does not expect a
2577ac2224c0SFangrui Song // 'has undefined version' error in -shared --exclude-libs=ALL mode (PR36295).
2578ac2224c0SFangrui Song // GNU ld errors in this case.
25793837f427SRui Ueyama if (args.hasArg(OPT_exclude_libs))
25803837f427SRui Ueyama excludeLibs(args);
2581d1f8b816SRui Ueyama
258247cfe8f3SFangrui Song // Create elfHeader early. We need a dummy section in
258363fcc5ccSRafael Espindola // addReservedSymbols to mark the created symbols as not absolute.
25843837f427SRui Ueyama Out::elfHeader = make<OutputSection>("", 0, SHF_ALLOC);
258563fcc5ccSRafael Espindola
258663fcc5ccSRafael Espindola // We need to create some reserved symbols such as _end. Create them.
25873837f427SRui Ueyama if (!config->relocatable)
25889a84f6b9SRafael Espindola addReservedSymbols();
258963fcc5ccSRafael Espindola
2590d1f8b816SRui Ueyama // Apply version scripts.
259144a84712SRui Ueyama //
259244a84712SRui Ueyama // For a relocatable output, version scripts don't make sense, and
259344a84712SRui Ueyama // parsing a symbol version string (e.g. dropping "@ver1" from a symbol
259444a84712SRui Ueyama // name "foo@ver1") rather do harm, so we don't call this if -r is given.
2595439341b9SJames Henderson if (!config->relocatable) {
2596439341b9SJames Henderson llvm::TimeTraceScope timeScope("Process symbol versions");
25973837f427SRui Ueyama symtab->scanVersionScript();
2598439341b9SJames Henderson }
25993a35c454SPeter Collingbourne
2600a96fe1bfSFangrui Song // Skip the normal linked output if some LTO options are specified.
2601a96fe1bfSFangrui Song //
2602a96fe1bfSFangrui Song // For --thinlto-index-only, index file creation is performed in
2603a96fe1bfSFangrui Song // compileBitcodeFiles, so we are done afterwards. --plugin-opt=emit-llvm and
2604a96fe1bfSFangrui Song // --plugin-opt=emit-asm create output files in bitcode or assembly code,
2605a96fe1bfSFangrui Song // respectively. When only certain thinLTO modules are specified for
2606a96fe1bfSFangrui Song // compilation, the intermediate object file are the expected output.
2607a96fe1bfSFangrui Song const bool skipLinkedOutput = config->thinLTOIndexOnly || config->emitLLVM ||
2608a96fe1bfSFangrui Song config->ltoEmitAsm ||
2609a96fe1bfSFangrui Song !config->thinLTOModulesToCompile.empty();
2610a96fe1bfSFangrui Song
2611554adb2eSRui Ueyama // Do link-time optimization if given files are LLVM bitcode files.
2612554adb2eSRui Ueyama // This compiles bitcode files into real object files.
261398930115SPeter Collingbourne //
261498930115SPeter Collingbourne // With this the symbol table should be complete. After this, no new names
261598930115SPeter Collingbourne // except a few linker-synthesized ones will be added to the symbol table.
26169a572164SFangrui Song const size_t numObjsBeforeLTO = ctx->objectFiles.size();
26177518d38fSFangrui Song invokeELFT(compileBitcodeFiles, skipLinkedOutput);
261803c825c2SFangrui Song
26197fd3849bSFangrui Song // Symbol resolution finished. Report backward reference problems,
26207fd3849bSFangrui Song // --print-archive-stats=, and --why-extract=.
262103c825c2SFangrui Song reportBackrefs();
26227fd3849bSFangrui Song writeArchiveStats();
26237fd3849bSFangrui Song writeWhyExtract();
2624b8a59c8aSBob Haarman if (errorCount())
2625d26c4a14SDavide Italiano return;
26269f77ef0cSRafael Espindola
2627a96fe1bfSFangrui Song // Bail out if normal linked output is skipped due to LTO.
2628a96fe1bfSFangrui Song if (skipLinkedOutput)
26299f499909SRui Ueyama return;
26309f499909SRui Ueyama
263188d66f6eSFangrui Song // compileBitcodeFiles may have produced lto.tmp object files. After this, no
263288d66f6eSFangrui Song // more file will be added.
26339a572164SFangrui Song auto newObjectFiles = makeArrayRef(ctx->objectFiles).slice(numObjsBeforeLTO);
2634a815424cSFangrui Song parallelForEach(newObjectFiles, initializeLocalSymbols);
263588d66f6eSFangrui Song parallelForEach(newObjectFiles, postParseObjectFile);
26367c7702b3SFangrui Song for (const DuplicateSymbol &d : ctx->duplicates)
26377c7702b3SFangrui Song reportDuplicate(*d.sym, d.file, d.section, d.value);
263888d66f6eSFangrui Song
2639abc388edSFangrui Song // Handle --exclude-libs again because lto.tmp may reference additional
2640abc388edSFangrui Song // libcalls symbols defined in an excluded archive. This may override
2641abc388edSFangrui Song // versionId set by scanVersionScript().
2642abc388edSFangrui Song if (args.hasArg(OPT_exclude_libs))
2643abc388edSFangrui Song excludeLibs(args);
2644abc388edSFangrui Song
2645bf6e259bSFangrui Song // Apply symbol renames for --wrap and combine foo@v1 and foo@@v1.
2646941e9336SFangrui Song redirectSymbols(wrapped);
26479703ad22SGeorge Rimar
2648abc388edSFangrui Song // Replace common symbols with regular symbols.
2649abc388edSFangrui Song replaceCommonSymbols();
2650abc388edSFangrui Song
2651439341b9SJames Henderson {
2652439341b9SJames Henderson llvm::TimeTraceScope timeScope("Aggregate sections");
26538c6a5aafSRui Ueyama // Now that we have a complete list of input files.
26548c6a5aafSRui Ueyama // Beyond this point, no new files are added.
26558c6a5aafSRui Ueyama // Aggregate all input sections into one place.
26569a572164SFangrui Song for (InputFile *f : ctx->objectFiles)
26573837f427SRui Ueyama for (InputSectionBase *s : f->getSections())
26583837f427SRui Ueyama if (s && s != &InputSection::discarded)
26593837f427SRui Ueyama inputSections.push_back(s);
26609a572164SFangrui Song for (BinaryFile *f : ctx->binaryFiles)
26613837f427SRui Ueyama for (InputSectionBase *s : f->getSections())
26623837f427SRui Ueyama inputSections.push_back(cast<InputSection>(s));
2663439341b9SJames Henderson }
26648c6a5aafSRui Ueyama
2665439341b9SJames Henderson {
2666439341b9SJames Henderson llvm::TimeTraceScope timeScope("Strip sections");
26671a590232SFangrui Song if (ctx->hasSympart.load(std::memory_order_relaxed)) {
26683837f427SRui Ueyama llvm::erase_if(inputSections, [](InputSectionBase *s) {
26691a590232SFangrui Song if (s->type != SHT_LLVM_SYMPART)
26701a590232SFangrui Song return false;
26717518d38fSFangrui Song invokeELFT(readSymbolPartitionSection, s);
2672ba2816beSPeter Collingbourne return true;
26731a590232SFangrui Song });
2674ba2816beSPeter Collingbourne }
2675ddd24249SGeorge Rimar // We do not want to emit debug sections if --strip-all
2676bf6e259bSFangrui Song // or --strip-debug are given.
26771a590232SFangrui Song if (config->strip != StripPolicy::None) {
26781a590232SFangrui Song llvm::erase_if(inputSections, [](InputSectionBase *s) {
26796c732461SFangrui Song if (isDebugSection(*s))
26806c732461SFangrui Song return true;
26816c732461SFangrui Song if (auto *isec = dyn_cast<InputSection>(s))
26826c732461SFangrui Song if (InputSectionBase *rel = isec->getRelocatedSection())
26836c732461SFangrui Song if (isDebugSection(*rel))
26846c732461SFangrui Song return true;
26856c732461SFangrui Song
26866c732461SFangrui Song return false;
26875ff1eb64SBob Haarman });
2688439341b9SJames Henderson }
26891a590232SFangrui Song }
2690f28825bcSRui Ueyama
269181eeabbdSPetr Hosek // Since we now have a complete set of input files, we can create
269281eeabbdSPetr Hosek // a .d file to record build dependencies.
269381eeabbdSPetr Hosek if (!config->dependencyFile.empty())
269481eeabbdSPetr Hosek writeDependencyFile();
269581eeabbdSPetr Hosek
269602828985SPeter Collingbourne // Now that the number of partitions is fixed, save a pointer to the main
269702828985SPeter Collingbourne // partition.
26983837f427SRui Ueyama mainPart = &partitions[0];
269902828985SPeter Collingbourne
27002057f836SRui Ueyama // Read .note.gnu.property sections from input object files which
27012057f836SRui Ueyama // contain a hint to tweak linker's and loader's behaviors.
270272a005bfSFangrui Song config->andFeatures = getAndFeatures();
27032057f836SRui Ueyama
2704e208208aSPeter Smith // The Target instance handles target-specific stuff, such as applying
2705e208208aSPeter Smith // relocations or writing a PLT section. It also contains target-dependent
2706e208208aSPeter Smith // values such as a default image base address.
27073837f427SRui Ueyama target = getTarget();
2708e208208aSPeter Smith
27093837f427SRui Ueyama config->eflags = target->calcEFlags();
271047cfe8f3SFangrui Song // maxPageSize (sometimes called abi page size) is the maximum page size that
27114e21c770SPeter Smith // the output can be run on. For example if the OS can use 4k or 64k page
271247cfe8f3SFangrui Song // sizes then maxPageSize must be 64k for the output to be useable on both.
27134e21c770SPeter Smith // All important alignment decisions must use this value.
27143837f427SRui Ueyama config->maxPageSize = getMaxPageSize(args);
271547cfe8f3SFangrui Song // commonPageSize is the most common page size that the output will be run on.
27164e21c770SPeter Smith // For example if an OS can use 4k or 64k page sizes and 4k is more common
271747cfe8f3SFangrui Song // than 64k then commonPageSize is set to 4k. commonPageSize can be used for
27184e21c770SPeter Smith // optimizations such as DATA_SEGMENT_ALIGN in linker scripts. LLD's use of it
27194e21c770SPeter Smith // is limited to writing trap instructions on the last executable segment.
27203837f427SRui Ueyama config->commonPageSize = getCommonPageSize(args);
27214e21c770SPeter Smith
27223837f427SRui Ueyama config->imageBase = getImageBase(args);
2723649e4d32SSimon Atanasyan
27243837f427SRui Ueyama if (config->emachine == EM_ARM) {
272557eb0469SPeter Smith // FIXME: These warnings can be removed when lld only uses these features
272657eb0469SPeter Smith // when the input objects have been compiled with an architecture that
272757eb0469SPeter Smith // supports them.
27283837f427SRui Ueyama if (config->armHasBlx == false)
272957eb0469SPeter Smith warn("lld uses blx instruction, no object with architecture supporting "
27309db06423SRui Ueyama "feature detected");
273157eb0469SPeter Smith }
273257eb0469SPeter Smith
2733e47bbd28SFangrui Song // This adds a .comment section containing a version string.
27343837f427SRui Ueyama if (!config->relocatable)
27353837f427SRui Ueyama inputSections.push_back(createCommentSection());
2736dc7936ecSPeter Collingbourne
27376d6ec1b8SRussell Gallop // Split SHF_MERGE and .eh_frame sections into pieces in preparation for garbage collection.
27387518d38fSFangrui Song invokeELFT(splitSections);
27396d6ec1b8SRussell Gallop
27406d6ec1b8SRussell Gallop // Garbage collection and removal of shared symbols from unused shared objects.
27417518d38fSFangrui Song invokeELFT(markLive);
27428b01b638SFangrui Song demoteSharedAndLazySymbols();
27435d9f419aSFangrui Song
27445d9f419aSFangrui Song // Make copies of any input sections that need to be copied into each
27455d9f419aSFangrui Song // partition.
27465d9f419aSFangrui Song copySectionsIntoPartitions();
27475d9f419aSFangrui Song
27485d9f419aSFangrui Song // Create synthesized sections such as .got and .plt. This is called before
27495d9f419aSFangrui Song // processSectionCommands() so that they can be placed by SECTIONS commands.
27507518d38fSFangrui Song invokeELFT(createSyntheticSections);
27515d9f419aSFangrui Song
27525d9f419aSFangrui Song // Some input sections that are used for exception handling need to be moved
27535d9f419aSFangrui Song // into synthetic sections. Do that now so that they aren't assigned to
27545d9f419aSFangrui Song // output sections in the usual way.
27555d9f419aSFangrui Song if (!config->relocatable)
27565d9f419aSFangrui Song combineEhSections();
27575d9f419aSFangrui Song
2758439341b9SJames Henderson {
2759439341b9SJames Henderson llvm::TimeTraceScope timeScope("Assign sections");
2760439341b9SJames Henderson
27615d9f419aSFangrui Song // Create output sections described by SECTIONS commands.
27625d9f419aSFangrui Song script->processSectionCommands();
27635d9f419aSFangrui Song
2764439341b9SJames Henderson // Linker scripts control how input sections are assigned to output
2765439341b9SJames Henderson // sections. Input sections that were not handled by scripts are called
2766439341b9SJames Henderson // "orphans", and they are assigned to output sections by the default rule.
2767439341b9SJames Henderson // Process that.
27688d30c1dcSFangrui Song script->addOrphanSections();
2769439341b9SJames Henderson }
2770439341b9SJames Henderson
2771439341b9SJames Henderson {
2772439341b9SJames Henderson llvm::TimeTraceScope timeScope("Merge/finalize input sections");
27738d30c1dcSFangrui Song
2774e47bbd28SFangrui Song // Migrate InputSectionDescription::sectionBases to sections. This includes
2775e47bbd28SFangrui Song // merging MergeInputSections into a single MergeSyntheticSection. From this
2776e47bbd28SFangrui Song // point onwards InputSectionDescription::sections should be used instead of
2777e47bbd28SFangrui Song // sectionBases.
27787051aeefSFangrui Song for (SectionCommand *cmd : script->sectionCommands)
27796c814931SFangrui Song if (auto *osd = dyn_cast<OutputDesc>(cmd))
27806c814931SFangrui Song osd->osec.finalizeInputSections();
2781439341b9SJames Henderson llvm::erase_if(inputSections, [](InputSectionBase *s) {
2782439341b9SJames Henderson return isa<MergeInputSection>(s);
2783439341b9SJames Henderson });
2784439341b9SJames Henderson }
2785e47bbd28SFangrui Song
27865d9f419aSFangrui Song // Two input sections with different output sections should not be folded.
27875d9f419aSFangrui Song // ICF runs after processSectionCommands() so that we know the output sections.
27883837f427SRui Ueyama if (config->icf != ICFLevel::None) {
27897518d38fSFangrui Song invokeELFT(findKeepUniqueSections, args);
27907518d38fSFangrui Song invokeELFT(doIcf);
2791dbef8cc6SPeter Smith }
2792b91bf1a9SRui Ueyama
2793b842725cSMichael J. Spencer // Read the callgraph now that we know what was gced or icfed
27943837f427SRui Ueyama if (config->callGraphProfileSort) {
27953837f427SRui Ueyama if (auto *arg = args.getLastArg(OPT_call_graph_ordering_file))
27963837f427SRui Ueyama if (Optional<MemoryBufferRef> buffer = readFile(arg->getValue()))
27973837f427SRui Ueyama readCallGraph(*buffer);
27987518d38fSFangrui Song invokeELFT(readCallGraphsFromObjectFiles);
2799cc18f8aaSFangrui Song }
2800b842725cSMichael J. Spencer
2801a75b7a48SRui Ueyama // Write the result to the file.
28027518d38fSFangrui Song invokeELFT(writeResult);
28034b7c2fc6SRafael Espindola }
2804