Mercurial > hg > CbC > CbC_llvm
diff lld/ELF/Driver.cpp @ 173:0572611fdcc8 llvm10 llvm12
reorgnization done
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 25 May 2020 11:55:54 +0900 |
parents | 1d019706d866 |
children | 2e18cbf3894f |
line wrap: on
line diff
--- a/lld/ELF/Driver.cpp Mon May 25 11:50:15 2020 +0900 +++ b/lld/ELF/Driver.cpp Mon May 25 11:55:54 2020 +0900 @@ -43,7 +43,6 @@ #include "lld/Common/Memory.h" #include "lld/Common/Strings.h" #include "lld/Common/TargetOptionsCommandFlags.h" -#include "lld/Common/Threads.h" #include "lld/Common/Version.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/StringExtras.h" @@ -53,6 +52,7 @@ #include "llvm/Support/Compression.h" #include "llvm/Support/GlobPattern.h" #include "llvm/Support/LEB128.h" +#include "llvm/Support/Parallel.h" #include "llvm/Support/Path.h" #include "llvm/Support/TarWriter.h" #include "llvm/Support/TargetSelect.h" @@ -66,18 +66,17 @@ using namespace llvm::object; using namespace llvm::sys; using namespace llvm::support; +using namespace lld; +using namespace lld::elf; -namespace lld { -namespace elf { - -Configuration *config; -LinkerDriver *driver; +Configuration *elf::config; +LinkerDriver *elf::driver; static void setConfigs(opt::InputArgList &args); static void readConfigs(opt::InputArgList &args); -bool link(ArrayRef<const char *> args, bool canExitEarly, raw_ostream &stdoutOS, - raw_ostream &stderrOS) { +bool elf::link(ArrayRef<const char *> args, bool canExitEarly, + raw_ostream &stdoutOS, raw_ostream &stderrOS) { lld::stdoutOS = &stdoutOS; lld::stderrOS = &stderrOS; @@ -90,10 +89,13 @@ inputSections.clear(); outputSections.clear(); + archiveFiles.clear(); binaryFiles.clear(); bitcodeFiles.clear(); + lazyObjFiles.clear(); objectFiles.clear(); sharedFiles.clear(); + backwardReferences.clear(); config = make<Configuration>(); driver = make<LinkerDriver>(); @@ -148,6 +150,7 @@ .Cases("elf_amd64", "elf_x86_64", {ELF64LEKind, EM_X86_64}) .Case("elf_i386", {ELF32LEKind, EM_386}) .Case("elf_iamcu", {ELF32LEKind, EM_IAMCU}) + .Case("elf64_sparc", {ELF64BEKind, EM_SPARCV9}) .Default({ELFNoneKind, EM_NONE}); if (ret.first == ELFNoneKind) @@ -351,9 +354,9 @@ error("-z force-ibt may not be used with -z retpolineplt"); if (config->emachine != EM_AARCH64) { - if (config->pacPlt) + if (config->zPacPlt) error("-z pac-plt only supported on AArch64"); - if (config->forceBTI) + if (config->zForceBti) error("-z force-bti only supported on AArch64"); } } @@ -530,17 +533,14 @@ } if (config->timeTraceEnabled) { - // Write the result of the time trace profiler. - std::string path = args.getLastArgValue(OPT_time_trace_file_eq).str(); - if (path.empty()) - path = (config->outputFile + ".time-trace").str(); - std::error_code ec; - raw_fd_ostream os(path, ec, sys::fs::OF_Text); - if (ec) { - error("cannot open " + path + ": " + ec.message()); + if (auto E = timeTraceProfilerWrite(args.getLastArgValue(OPT_time_trace_file_eq).str(), + config->outputFile)) { + handleAllErrors(std::move(E), [&](const StringError &SE) { + error(SE.getMessage()); + }); return; } - timeTraceProfilerWrite(os); + timeTraceProfilerCleanup(); } } @@ -610,9 +610,6 @@ } static DiscardPolicy getDiscard(opt::InputArgList &args) { - if (args.hasArg(OPT_relocatable)) - return DiscardPolicy::None; - auto *arg = args.getLastArg(OPT_discard_all, OPT_discard_locals, OPT_discard_none); if (!arg) @@ -863,7 +860,6 @@ args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false); errorHandler().vsDiagnostics = args.hasArg(OPT_visual_studio_diagnostics_format, false); - threadsEnabled = args.hasFlag(OPT_threads, OPT_no_threads, true); config->allowMultipleDefinition = args.hasFlag(OPT_allow_multiple_definition, @@ -882,6 +878,8 @@ config->cref = args.hasFlag(OPT_cref, OPT_no_cref, false); config->defineCommon = args.hasFlag(OPT_define_common, OPT_no_define_common, !args.hasArg(OPT_relocatable)); + config->optimizeBBJumps = + args.hasFlag(OPT_optimize_bb_jumps, OPT_no_optimize_bb_jumps, false); config->demangle = args.hasFlag(OPT_demangle, OPT_no_demangle, true); config->dependentLibraries = args.hasFlag(OPT_dependent_libraries, OPT_no_dependent_libraries, true); config->disableVerify = args.hasArg(OPT_disable_verify); @@ -907,7 +905,6 @@ !args.hasArg(OPT_relocatable); config->fixCortexA8 = args.hasArg(OPT_fix_cortex_a8) && !args.hasArg(OPT_relocatable); - config->forceBTI = hasZOption(args, "force-bti"); config->gcSections = args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, false); config->gnuUnique = args.hasFlag(OPT_gnu_unique, OPT_no_gnu_unique, true); config->gdbIndex = args.hasFlag(OPT_gdb_index, OPT_no_gdb_index, false); @@ -921,6 +918,7 @@ config->ltoCSProfileGenerate = args.hasArg(OPT_lto_cs_profile_generate); config->ltoCSProfileFile = args.getLastArgValue(OPT_lto_cs_profile_file); config->ltoDebugPassManager = args.hasArg(OPT_lto_debug_pass_manager); + config->ltoEmitAsm = args.hasArg(OPT_lto_emit_asm); config->ltoNewPassManager = args.hasArg(OPT_lto_new_pass_manager); config->ltoNewPmPasses = args.getLastArgValue(OPT_lto_newpm_passes); config->ltoWholeProgramVisibility = @@ -929,6 +927,11 @@ config->ltoObjPath = args.getLastArgValue(OPT_lto_obj_path_eq); config->ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1); config->ltoSampleProfile = args.getLastArgValue(OPT_lto_sample_profile); + config->ltoBasicBlockSections = + args.getLastArgValue(OPT_lto_basicblock_sections); + config->ltoUniqueBBSectionNames = + args.hasFlag(OPT_lto_unique_bb_section_names, + OPT_no_lto_unique_bb_section_names, false); config->mapFile = args.getLastArgValue(OPT_Map); config->mipsGotSize = args::getInteger(args, OPT_mips_got_size, 0xfff0); config->mergeArmExidx = @@ -947,21 +950,23 @@ config->optimize = args::getInteger(args, OPT_O, 1); config->orphanHandling = getOrphanHandling(args); config->outputFile = args.getLastArgValue(OPT_o); - config->pacPlt = hasZOption(args, "pac-plt"); config->pie = args.hasFlag(OPT_pie, OPT_no_pie, false); config->printIcfSections = args.hasFlag(OPT_print_icf_sections, OPT_no_print_icf_sections, false); config->printGcSections = args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false); + config->printArchiveStats = args.getLastArgValue(OPT_print_archive_stats); config->printSymbolOrder = args.getLastArgValue(OPT_print_symbol_order); config->rpath = getRpath(args); config->relocatable = args.hasArg(OPT_relocatable); config->saveTemps = args.hasArg(OPT_save_temps); + if (args.hasArg(OPT_shuffle_sections)) + config->shuffleSectionSeed = args::getInteger(args, OPT_shuffle_sections, 0); config->searchPaths = args::getStrings(args, OPT_library_path); config->sectionStartMap = getSectionStartMap(args); config->shared = args.hasArg(OPT_shared); - config->singleRoRx = args.hasArg(OPT_no_rosegment); + config->singleRoRx = !args.hasFlag(OPT_rosegment, OPT_no_rosegment, true); config->soName = args.getLastArgValue(OPT_soname); config->sortSection = getSortSection(args); config->splitStackAdjustSize = args::getInteger(args, OPT_split_stack_adjust_size, 16384); @@ -977,7 +982,6 @@ config->thinLTOIndexOnly = args.hasArg(OPT_thinlto_index_only) || args.hasArg(OPT_thinlto_index_only_eq); config->thinLTOIndexOnlyArg = args.getLastArgValue(OPT_thinlto_index_only_eq); - config->thinLTOJobs = args::getInteger(args, OPT_thinlto_jobs, -1u); config->thinLTOObjectSuffixReplace = getOldNewOptions(args, OPT_thinlto_object_suffix_replace_eq); config->thinLTOPrefixReplace = @@ -989,6 +993,7 @@ config->undefined = args::getStrings(args, OPT_undefined); config->undefinedVersion = args.hasFlag(OPT_undefined_version, OPT_no_undefined_version, true); + config->unique = args.hasArg(OPT_unique); config->useAndroidRelrTags = args.hasFlag( OPT_use_android_relr_tags, OPT_no_use_android_relr_tags, false); config->unresolvedSymbols = getUnresolvedSymbolPolicy(args); @@ -1001,6 +1006,7 @@ args.hasFlag(OPT_warn_symbol_ordering, OPT_no_warn_symbol_ordering, true); config->zCombreloc = getZFlag(args, "combreloc", "nocombreloc", true); config->zCopyreloc = getZFlag(args, "copyreloc", "nocopyreloc", true); + config->zForceBti = hasZOption(args, "force-bti"); config->zForceIbt = hasZOption(args, "force-ibt"); config->zGlobal = hasZOption(args, "global"); config->zGnustack = getZGnuStack(args); @@ -1015,6 +1021,7 @@ config->zNodlopen = hasZOption(args, "nodlopen"); config->zNow = getZFlag(args, "now", "lazy", false); config->zOrigin = hasZOption(args, "origin"); + config->zPacPlt = hasZOption(args, "pac-plt"); config->zRelro = getZFlag(args, "relro", "norelro", true); config->zRetpolineplt = hasZOption(args, "retpolineplt"); config->zRodynamic = hasZOption(args, "rodynamic"); @@ -1029,19 +1036,41 @@ parseClangOption(saver.save("-mcpu=" + StringRef(arg->getValue())), arg->getSpelling()); - for (auto *arg : args.filtered(OPT_plugin_opt)) - parseClangOption(arg->getValue(), arg->getSpelling()); + for (opt::Arg *arg : args.filtered(OPT_plugin_opt_eq_minus)) + parseClangOption(std::string("-") + arg->getValue(), arg->getSpelling()); + + // GCC collect2 passes -plugin-opt=path/to/lto-wrapper with an absolute or + // relative path. Just ignore. If not ended with "lto-wrapper", consider it an + // unsupported LLVMgold.so option and error. + for (opt::Arg *arg : args.filtered(OPT_plugin_opt_eq)) + if (!StringRef(arg->getValue()).endswith("lto-wrapper")) + error(arg->getSpelling() + ": unknown plugin option '" + arg->getValue() + + "'"); // Parse -mllvm options. for (auto *arg : args.filtered(OPT_mllvm)) parseClangOption(arg->getValue(), arg->getSpelling()); + // --threads= takes a positive integer and provides the default value for + // --thinlto-jobs=. + if (auto *arg = args.getLastArg(OPT_threads)) { + StringRef v(arg->getValue()); + unsigned threads = 0; + if (!llvm::to_integer(v, threads, 0) || threads == 0) + error(arg->getSpelling() + ": expected a positive integer, but got '" + + arg->getValue() + "'"); + parallel::strategy = hardware_concurrency(threads); + config->thinLTOJobs = v; + } + if (auto *arg = args.getLastArg(OPT_thinlto_jobs)) + config->thinLTOJobs = arg->getValue(); + if (config->ltoo > 3) error("invalid optimization level for LTO: " + Twine(config->ltoo)); if (config->ltoPartitions == 0) error("--lto-partitions: number of threads must be > 0"); - if (config->thinLTOJobs == 0) - error("--thinlto-jobs: number of threads must be > 0"); + if (!get_threadpool_strategy(config->thinLTOJobs)) + error("--thinlto-jobs: invalid job count: " + config->thinLTOJobs); if (config->splitStackAdjustSize < 0) error("--split-stack-adjust-size: size must be >= 0"); @@ -1119,6 +1148,14 @@ {s, /*isExternCpp=*/false, /*hasWildcard=*/false}); } + for (opt::Arg *arg : args.filtered(OPT_warn_backrefs_exclude)) { + StringRef pattern(arg->getValue()); + if (Expected<GlobPattern> pat = GlobPattern::create(pattern)) + config->warnBackrefsExclude.push_back(std::move(*pat)); + else + error(arg->getSpelling() + ": " + toString(pat.takeError())); + } + // Parses -dynamic-list and -export-dynamic-symbol. They make some // symbols private. Note that -export-dynamic takes precedence over them // as it says all symbols should be exported. @@ -1428,6 +1465,10 @@ // eliminate it. Mark the symbol as "used" to prevent it. sym->isUsedInRegularObj = true; + // GNU linkers allow -u foo -ldef -lref. We should not treat it as a backward + // reference. + backwardReferences.erase(sym); + if (sym->isLazy()) sym->fetch(); } @@ -1735,8 +1776,9 @@ uint32_t ret = -1; for (InputFile *f : objectFiles) { uint32_t features = cast<ObjFile<ELFT>>(f)->andFeatures; - if (config->forceBTI && !(features & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) { - warn(toString(f) + ": -z force-bti: file does not have BTI property"); + if (config->zForceBti && !(features & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) { + warn(toString(f) + ": -z force-bti: file does not have " + "GNU_PROPERTY_AARCH64_FEATURE_1_BTI property"); features |= GNU_PROPERTY_AARCH64_FEATURE_1_BTI; } else if (config->zForceIbt && !(features & GNU_PROPERTY_X86_FEATURE_1_IBT)) { @@ -1744,13 +1786,14 @@ "GNU_PROPERTY_X86_FEATURE_1_IBT property"); features |= GNU_PROPERTY_X86_FEATURE_1_IBT; } + if (config->zPacPlt && !(features & GNU_PROPERTY_AARCH64_FEATURE_1_PAC)) { + warn(toString(f) + ": -z pac-plt: file does not have " + "GNU_PROPERTY_AARCH64_FEATURE_1_PAC property"); + features |= GNU_PROPERTY_AARCH64_FEATURE_1_PAC; + } ret &= features; } - // Force enable pointer authentication Plt, we don't warn in this case as - // this does not require support in the object for correctness. - if (config->pacPlt) - ret |= GNU_PROPERTY_AARCH64_FEATURE_1_PAC; // Force enable Shadow Stack. if (config->zShstk) ret |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; @@ -1900,19 +1943,19 @@ // With this the symbol table should be complete. After this, no new names // except a few linker-synthesized ones will be added to the symbol table. compileBitcodeFiles<ELFT>(); + + // Symbol resolution finished. Report backward reference problems. + reportBackrefs(); if (errorCount()) return; // If -thinlto-index-only is given, we should create only "index // files" and not object files. Index file creation is already done // in addCombinedLTOObject, so we are done if that's the case. - if (config->thinLTOIndexOnly) - return; - - // Likewise, --plugin-opt=emit-llvm is an option to make LTO create - // an output file in bitcode and exit, so that you can just get a - // combined bitcode file. - if (config->emitLLVM) + // Likewise, --plugin-opt=emit-llvm and --plugin-opt=emit-asm are the + // options to create output files in bitcode or assembly code + // repsectively. No object files are generated. + if (config->thinLTOIndexOnly || config->emitLLVM || config->ltoEmitAsm) return; // Apply symbol renames for -wrap. @@ -1938,8 +1981,17 @@ // We do not want to emit debug sections if --strip-all // or -strip-debug are given. - return config->strip != StripPolicy::None && - (s->name.startswith(".debug") || s->name.startswith(".zdebug")); + if (config->strip == StripPolicy::None) + return false; + + if (isDebugSection(*s)) + return true; + if (auto *isec = dyn_cast<InputSection>(s)) + if (InputSectionBase *rel = isec->getRelocatedSection()) + if (isDebugSection(*rel)) + return true; + + return false; }); // Now that the number of partitions is fixed, save a pointer to the main @@ -2043,6 +2095,3 @@ // Write the result to the file. writeResult<ELFT>(); } - -} // namespace elf -} // namespace lld