diff options
Diffstat (limited to 'ELF/Driver.cpp')
| -rw-r--r-- | ELF/Driver.cpp | 82 |
1 files changed, 35 insertions, 47 deletions
diff --git a/ELF/Driver.cpp b/ELF/Driver.cpp index f3943b5cf6559..f24c941fe7733 100644 --- a/ELF/Driver.cpp +++ b/ELF/Driver.cpp @@ -36,6 +36,7 @@ #include "ScriptParser.h" #include "Strings.h" #include "SymbolTable.h" +#include "SyntheticSections.h" #include "Target.h" #include "Threads.h" #include "Writer.h" @@ -43,7 +44,6 @@ #include "lld/Driver/Driver.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/Object/Decompressor.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compression.h" #include "llvm/Support/Path.h" @@ -99,7 +99,7 @@ static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef Emul) { std::pair<ELFKind, uint16_t> Ret = StringSwitch<std::pair<ELFKind, uint16_t>>(S) .Cases("aarch64elf", "aarch64linux", {ELF64LEKind, EM_AARCH64}) - .Case("armelf_linux_eabi", {ELF32LEKind, EM_ARM}) + .Cases("armelf", "armelf_linux_eabi", {ELF32LEKind, EM_ARM}) .Case("elf32_x86_64", {ELF32LEKind, EM_X86_64}) .Cases("elf32btsmip", "elf32btsmipn32", {ELF32BEKind, EM_MIPS}) .Cases("elf32ltsmip", "elf32ltsmipn32", {ELF32LEKind, EM_MIPS}) @@ -273,13 +273,6 @@ static void checkOptions(opt::InputArgList &Args) { } } -static StringRef getString(opt::InputArgList &Args, unsigned Key, - StringRef Default = "") { - if (auto *Arg = Args.getLastArg(Key)) - return Arg->getValue(); - return Default; -} - static int getInteger(opt::InputArgList &Args, unsigned Key, int Default) { int V = Default; if (auto *Arg = Args.getLastArg(Key)) { @@ -306,13 +299,11 @@ static bool hasZOption(opt::InputArgList &Args, StringRef Key) { static uint64_t getZOptionValue(opt::InputArgList &Args, StringRef Key, uint64_t Default) { for (auto *Arg : Args.filtered(OPT_z)) { - StringRef Value = Arg->getValue(); - size_t Pos = Value.find("="); - if (Pos != StringRef::npos && Key == Value.substr(0, Pos)) { - Value = Value.substr(Pos + 1); + std::pair<StringRef, StringRef> KV = StringRef(Arg->getValue()).split('='); + if (KV.first == Key) { uint64_t Result; - if (!to_integer(Value, Result)) - error("invalid " + Key + ": " + Value); + if (!to_integer(KV.second, Result)) + error("invalid " + Key + ": " + KV.second); return Result; } } @@ -463,7 +454,7 @@ static UnresolvedPolicy getUnresolvedSymbolPolicy(opt::InputArgList &Args) { } static Target2Policy getTarget2(opt::InputArgList &Args) { - StringRef S = getString(Args, OPT_target2, "got-rel"); + StringRef S = Args.getLastArgValue(OPT_target2, "got-rel"); if (S == "rel") return Target2Policy::Rel; if (S == "abs") @@ -546,7 +537,7 @@ static StringMap<uint64_t> getSectionStartMap(opt::InputArgList &Args) { } static SortSectionPolicy getSortSection(opt::InputArgList &Args) { - StringRef S = getString(Args, OPT_sort_section); + StringRef S = Args.getLastArgValue(OPT_sort_section); if (S == "alignment") return SortSectionPolicy::Alignment; if (S == "name") @@ -557,7 +548,7 @@ static SortSectionPolicy getSortSection(opt::InputArgList &Args) { } static std::pair<bool, bool> getHashStyle(opt::InputArgList &Args) { - StringRef S = getString(Args, OPT_hash_style, "sysv"); + StringRef S = Args.getLastArgValue(OPT_hash_style, "sysv"); if (S == "sysv") return {true, false}; if (S == "gnu") @@ -608,7 +599,7 @@ static std::vector<StringRef> getLines(MemoryBufferRef MB) { } static bool getCompressDebugSections(opt::InputArgList &Args) { - StringRef S = getString(Args, OPT_compress_debug_sections, "none"); + StringRef S = Args.getLastArgValue(OPT_compress_debug_sections, "none"); if (S == "none") return false; if (S != "zlib") @@ -634,30 +625,30 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { Config->EhFrameHdr = Args.hasArg(OPT_eh_frame_hdr); Config->EmitRelocs = Args.hasArg(OPT_emit_relocs); Config->EnableNewDtags = !Args.hasArg(OPT_disable_new_dtags); - Config->Entry = getString(Args, OPT_entry); + Config->Entry = Args.getLastArgValue(OPT_entry); Config->ExportDynamic = getArg(Args, OPT_export_dynamic, OPT_no_export_dynamic, false); Config->FatalWarnings = getArg(Args, OPT_fatal_warnings, OPT_no_fatal_warnings, false); - Config->Fini = getString(Args, OPT_fini, "_fini"); + Config->Fini = Args.getLastArgValue(OPT_fini, "_fini"); Config->GcSections = getArg(Args, OPT_gc_sections, OPT_no_gc_sections, false); Config->GdbIndex = Args.hasArg(OPT_gdb_index); Config->ICF = Args.hasArg(OPT_icf); - Config->Init = getString(Args, OPT_init, "_init"); - Config->LTOAAPipeline = getString(Args, OPT_lto_aa_pipeline); - Config->LTONewPmPasses = getString(Args, OPT_lto_newpm_passes); + Config->Init = Args.getLastArgValue(OPT_init, "_init"); + Config->LTOAAPipeline = Args.getLastArgValue(OPT_lto_aa_pipeline); + Config->LTONewPmPasses = Args.getLastArgValue(OPT_lto_newpm_passes); Config->LTOO = getInteger(Args, OPT_lto_O, 2); Config->LTOPartitions = getInteger(Args, OPT_lto_partitions, 1); - Config->MapFile = getString(Args, OPT_Map); + Config->MapFile = Args.getLastArgValue(OPT_Map); Config->NoGnuUnique = Args.hasArg(OPT_no_gnu_unique); Config->NoUndefinedVersion = Args.hasArg(OPT_no_undefined_version); Config->Nostdlib = Args.hasArg(OPT_nostdlib); Config->OFormatBinary = isOutputFormatBinary(Args); Config->Omagic = Args.hasArg(OPT_omagic); - Config->OptRemarksFilename = getString(Args, OPT_opt_remarks_filename); + Config->OptRemarksFilename = Args.getLastArgValue(OPT_opt_remarks_filename); Config->OptRemarksWithHotness = Args.hasArg(OPT_opt_remarks_with_hotness); Config->Optimize = getInteger(Args, OPT_O, 1); - Config->OutputFile = getString(Args, OPT_o); + Config->OutputFile = Args.getLastArgValue(OPT_o); Config->Pie = getArg(Args, OPT_pie, OPT_nopie, false); Config->PrintGcSections = Args.hasArg(OPT_print_gc_sections); Config->Rpath = getRpath(Args); @@ -667,16 +658,16 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { Config->SectionStartMap = getSectionStartMap(Args); Config->Shared = Args.hasArg(OPT_shared); Config->SingleRoRx = Args.hasArg(OPT_no_rosegment); - Config->SoName = getString(Args, OPT_soname); + Config->SoName = Args.getLastArgValue(OPT_soname); Config->SortSection = getSortSection(Args); Config->Strip = getStrip(Args); - Config->Sysroot = getString(Args, OPT_sysroot); + Config->Sysroot = Args.getLastArgValue(OPT_sysroot); Config->Target1Rel = getArg(Args, OPT_target1_rel, OPT_target1_abs, false); Config->Target2 = getTarget2(Args); - Config->ThinLTOCacheDir = getString(Args, OPT_thinlto_cache_dir); - Config->ThinLTOCachePolicy = - check(parseCachePruningPolicy(getString(Args, OPT_thinlto_cache_policy)), - "--thinlto-cache-policy: invalid cache policy"); + Config->ThinLTOCacheDir = Args.getLastArgValue(OPT_thinlto_cache_dir); + Config->ThinLTOCachePolicy = check( + parseCachePruningPolicy(Args.getLastArgValue(OPT_thinlto_cache_policy)), + "--thinlto-cache-policy: invalid cache policy"); Config->ThinLTOJobs = getInteger(Args, OPT_thinlto_jobs, -1u); Config->Threads = getArg(Args, OPT_threads, OPT_no_threads, true); Config->Trace = Args.hasArg(OPT_trace); @@ -698,7 +689,8 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { Config->ZWxneeded = hasZOption(Args, "wxneeded"); if (Config->LTOO > 3) - error("invalid optimization level for LTO: " + getString(Args, OPT_lto_O)); + error("invalid optimization level for LTO: " + + Args.getLastArgValue(OPT_lto_O)); if (Config->LTOPartitions == 0) error("--lto-partitions: number of threads must be > 0"); if (Config->ThinLTOJobs == 0) @@ -1001,24 +993,20 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { for (InputSectionBase *S : F->getSections()) InputSections.push_back(cast<InputSection>(S)); - // Do size optimizations: garbage collection and identical code folding. + // This adds a .comment section containing a version string. We have to add it + // before decompressAndMergeSections because the .comment section is a + // mergeable section. + if (!Config->Relocatable) + InputSections.push_back(createCommentSection<ELFT>()); + + // Do size optimizations: garbage collection, merging of SHF_MERGE sections + // and identical code folding. if (Config->GcSections) markLive<ELFT>(); + decompressAndMergeSections(); if (Config->ICF) doIcf<ELFT>(); - // MergeInputSection::splitIntoPieces needs to be called before - // any call of MergeInputSection::getOffset. Do that. - parallelForEach(InputSections.begin(), InputSections.end(), - [](InputSectionBase *S) { - if (!S->Live) - return; - if (Decompressor::isCompressedELFSection(S->Flags, S->Name)) - S->uncompress(); - if (auto *MS = dyn_cast<MergeInputSection>(S)) - MS->splitIntoPieces(); - }); - // Write the result to the file. writeResult<ELFT>(); } |
