llvm-project
2029 строк · 75.1 Кб
1//===- Driver.cpp ---------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "Driver.h"10#include "Config.h"11#include "ICF.h"12#include "InputFiles.h"13#include "LTO.h"14#include "MarkLive.h"15#include "ObjC.h"16#include "OutputSection.h"17#include "OutputSegment.h"18#include "SectionPriorities.h"19#include "SymbolTable.h"20#include "Symbols.h"21#include "SyntheticSections.h"22#include "Target.h"23#include "UnwindInfoSection.h"24#include "Writer.h"25
26#include "lld/Common/Args.h"27#include "lld/Common/CommonLinkerContext.h"28#include "lld/Common/Driver.h"29#include "lld/Common/ErrorHandler.h"30#include "lld/Common/LLVM.h"31#include "lld/Common/Memory.h"32#include "lld/Common/Reproduce.h"33#include "lld/Common/Version.h"34#include "llvm/ADT/DenseSet.h"35#include "llvm/ADT/StringExtras.h"36#include "llvm/ADT/StringRef.h"37#include "llvm/BinaryFormat/MachO.h"38#include "llvm/BinaryFormat/Magic.h"39#include "llvm/Config/llvm-config.h"40#include "llvm/LTO/LTO.h"41#include "llvm/Object/Archive.h"42#include "llvm/Option/ArgList.h"43#include "llvm/Support/CommandLine.h"44#include "llvm/Support/FileSystem.h"45#include "llvm/Support/MemoryBuffer.h"46#include "llvm/Support/Parallel.h"47#include "llvm/Support/Path.h"48#include "llvm/Support/TarWriter.h"49#include "llvm/Support/TargetSelect.h"50#include "llvm/Support/TimeProfiler.h"51#include "llvm/TargetParser/Host.h"52#include "llvm/TextAPI/PackedVersion.h"53
54#include <algorithm>55
56using namespace llvm;57using namespace llvm::MachO;58using namespace llvm::object;59using namespace llvm::opt;60using namespace llvm::sys;61using namespace lld;62using namespace lld::macho;63
64std::unique_ptr<Configuration> macho::config;65std::unique_ptr<DependencyTracker> macho::depTracker;66
67static HeaderFileType getOutputType(const InputArgList &args) {68// TODO: -r, -dylinker, -preload...69Arg *outputArg = args.getLastArg(OPT_bundle, OPT_dylib, OPT_execute);70if (outputArg == nullptr)71return MH_EXECUTE;72
73switch (outputArg->getOption().getID()) {74case OPT_bundle:75return MH_BUNDLE;76case OPT_dylib:77return MH_DYLIB;78case OPT_execute:79return MH_EXECUTE;80default:81llvm_unreachable("internal error");82}83}
84
85static DenseMap<CachedHashStringRef, StringRef> resolvedLibraries;86static std::optional<StringRef> findLibrary(StringRef name) {87CachedHashStringRef key(name);88auto entry = resolvedLibraries.find(key);89if (entry != resolvedLibraries.end())90return entry->second;91
92auto doFind = [&] {93// Special case for Csu support files required for Mac OS X 10.7 and older94// (crt1.o)95if (name.ends_with(".o"))96return findPathCombination(name, config->librarySearchPaths, {""});97if (config->searchDylibsFirst) {98if (std::optional<StringRef> path =99findPathCombination("lib" + name, config->librarySearchPaths,100{".tbd", ".dylib", ".so"}))101return path;102return findPathCombination("lib" + name, config->librarySearchPaths,103{".a"});104}105return findPathCombination("lib" + name, config->librarySearchPaths,106{".tbd", ".dylib", ".so", ".a"});107};108
109std::optional<StringRef> path = doFind();110if (path)111resolvedLibraries[key] = *path;112
113return path;114}
115
116static DenseMap<CachedHashStringRef, StringRef> resolvedFrameworks;117static std::optional<StringRef> findFramework(StringRef name) {118CachedHashStringRef key(name);119auto entry = resolvedFrameworks.find(key);120if (entry != resolvedFrameworks.end())121return entry->second;122
123SmallString<260> symlink;124StringRef suffix;125std::tie(name, suffix) = name.split(",");126for (StringRef dir : config->frameworkSearchPaths) {127symlink = dir;128path::append(symlink, name + ".framework", name);129
130if (!suffix.empty()) {131// NOTE: we must resolve the symlink before trying the suffixes, because132// there are no symlinks for the suffixed paths.133SmallString<260> location;134if (!fs::real_path(symlink, location)) {135// only append suffix if realpath() succeeds136Twine suffixed = location + suffix;137if (fs::exists(suffixed))138return resolvedFrameworks[key] = saver().save(suffixed.str());139}140// Suffix lookup failed, fall through to the no-suffix case.141}142
143if (std::optional<StringRef> path = resolveDylibPath(symlink.str()))144return resolvedFrameworks[key] = *path;145}146return {};147}
148
149static bool warnIfNotDirectory(StringRef option, StringRef path) {150if (!fs::exists(path)) {151warn("directory not found for option -" + option + path);152return false;153} else if (!fs::is_directory(path)) {154warn("option -" + option + path + " references a non-directory path");155return false;156}157return true;158}
159
160static std::vector<StringRef>161getSearchPaths(unsigned optionCode, InputArgList &args,162const std::vector<StringRef> &roots,163const SmallVector<StringRef, 2> &systemPaths) {164std::vector<StringRef> paths;165StringRef optionLetter{optionCode == OPT_F ? "F" : "L"};166for (StringRef path : args::getStrings(args, optionCode)) {167// NOTE: only absolute paths are re-rooted to syslibroot(s)168bool found = false;169if (path::is_absolute(path, path::Style::posix)) {170for (StringRef root : roots) {171SmallString<261> buffer(root);172path::append(buffer, path);173// Do not warn about paths that are computed via the syslib roots174if (fs::is_directory(buffer)) {175paths.push_back(saver().save(buffer.str()));176found = true;177}178}179}180if (!found && warnIfNotDirectory(optionLetter, path))181paths.push_back(path);182}183
184// `-Z` suppresses the standard "system" search paths.185if (args.hasArg(OPT_Z))186return paths;187
188for (const StringRef &path : systemPaths) {189for (const StringRef &root : roots) {190SmallString<261> buffer(root);191path::append(buffer, path);192if (fs::is_directory(buffer))193paths.push_back(saver().save(buffer.str()));194}195}196return paths;197}
198
199static std::vector<StringRef> getSystemLibraryRoots(InputArgList &args) {200std::vector<StringRef> roots;201for (const Arg *arg : args.filtered(OPT_syslibroot))202roots.push_back(arg->getValue());203// NOTE: the final `-syslibroot` being `/` will ignore all roots204if (!roots.empty() && roots.back() == "/")205roots.clear();206// NOTE: roots can never be empty - add an empty root to simplify the library207// and framework search path computation.208if (roots.empty())209roots.emplace_back("");210return roots;211}
212
213static std::vector<StringRef>214getLibrarySearchPaths(InputArgList &args, const std::vector<StringRef> &roots) {215return getSearchPaths(OPT_L, args, roots, {"/usr/lib", "/usr/local/lib"});216}
217
218static std::vector<StringRef>219getFrameworkSearchPaths(InputArgList &args,220const std::vector<StringRef> &roots) {221return getSearchPaths(OPT_F, args, roots,222{"/Library/Frameworks", "/System/Library/Frameworks"});223}
224
225static llvm::CachePruningPolicy getLTOCachePolicy(InputArgList &args) {226SmallString<128> ltoPolicy;227auto add = [<oPolicy](Twine val) {228if (!ltoPolicy.empty())229ltoPolicy += ":";230val.toVector(ltoPolicy);231};232for (const Arg *arg :233args.filtered(OPT_thinlto_cache_policy_eq, OPT_prune_interval_lto,234OPT_prune_after_lto, OPT_max_relative_cache_size_lto)) {235switch (arg->getOption().getID()) {236case OPT_thinlto_cache_policy_eq:237add(arg->getValue());238break;239case OPT_prune_interval_lto:240if (!strcmp("-1", arg->getValue()))241add("prune_interval=87600h"); // 10 years242else243add(Twine("prune_interval=") + arg->getValue() + "s");244break;245case OPT_prune_after_lto:246add(Twine("prune_after=") + arg->getValue() + "s");247break;248case OPT_max_relative_cache_size_lto:249add(Twine("cache_size=") + arg->getValue() + "%");250break;251}252}253return CHECK(parseCachePruningPolicy(ltoPolicy), "invalid LTO cache policy");254}
255
256// What caused a given library to be loaded. Only relevant for archives.
257// Note that this does not tell us *how* we should load the library, i.e.
258// whether we should do it lazily or eagerly (AKA force loading). The "how" is
259// decided within addFile().
260enum class LoadType {261CommandLine, // Library was passed as a regular CLI argument262CommandLineForce, // Library was passed via `-force_load`263LCLinkerOption, // Library was passed via LC_LINKER_OPTIONS264};265
266struct ArchiveFileInfo {267ArchiveFile *file;268bool isCommandLineLoad;269};270
271static DenseMap<StringRef, ArchiveFileInfo> loadedArchives;272
273static InputFile *addFile(StringRef path, LoadType loadType,274bool isLazy = false, bool isExplicit = true,275bool isBundleLoader = false,276bool isForceHidden = false) {277std::optional<MemoryBufferRef> buffer = readFile(path);278if (!buffer)279return nullptr;280MemoryBufferRef mbref = *buffer;281InputFile *newFile = nullptr;282
283file_magic magic = identify_magic(mbref.getBuffer());284switch (magic) {285case file_magic::archive: {286bool isCommandLineLoad = loadType != LoadType::LCLinkerOption;287// Avoid loading archives twice. If the archives are being force-loaded,288// loading them twice would create duplicate symbol errors. In the289// non-force-loading case, this is just a minor performance optimization.290// We don't take a reference to cachedFile here because the291// loadArchiveMember() call below may recursively call addFile() and292// invalidate this reference.293auto entry = loadedArchives.find(path);294
295ArchiveFile *file;296if (entry == loadedArchives.end()) {297// No cached archive, we need to create a new one298std::unique_ptr<object::Archive> archive = CHECK(299object::Archive::create(mbref), path + ": failed to parse archive");300
301if (!archive->isEmpty() && !archive->hasSymbolTable())302error(path + ": archive has no index; run ranlib to add one");303file = make<ArchiveFile>(std::move(archive), isForceHidden);304} else {305file = entry->second.file;306// Command-line loads take precedence. If file is previously loaded via307// command line, or is loaded via LC_LINKER_OPTION and being loaded via308// LC_LINKER_OPTION again, using the cached archive is enough.309if (entry->second.isCommandLineLoad || !isCommandLineLoad)310return file;311}312
313bool isLCLinkerForceLoad = loadType == LoadType::LCLinkerOption &&314config->forceLoadSwift &&315path::filename(path).starts_with("libswift");316if ((isCommandLineLoad && config->allLoad) ||317loadType == LoadType::CommandLineForce || isLCLinkerForceLoad) {318if (readFile(path)) {319Error e = Error::success();320for (const object::Archive::Child &c : file->getArchive().children(e)) {321StringRef reason;322switch (loadType) {323case LoadType::LCLinkerOption:324reason = "LC_LINKER_OPTION";325break;326case LoadType::CommandLineForce:327reason = "-force_load";328break;329case LoadType::CommandLine:330reason = "-all_load";331break;332}333if (Error e = file->fetch(c, reason))334error(toString(file) + ": " + reason +335" failed to load archive member: " + toString(std::move(e)));336}337if (e)338error(toString(file) +339": Archive::children failed: " + toString(std::move(e)));340}341} else if (isCommandLineLoad && config->forceLoadObjC) {342for (const object::Archive::Symbol &sym : file->getArchive().symbols())343if (sym.getName().starts_with(objc::symbol_names::klass))344file->fetch(sym);345
346// TODO: no need to look for ObjC sections for a given archive member if347// we already found that it contains an ObjC symbol.348if (readFile(path)) {349Error e = Error::success();350for (const object::Archive::Child &c : file->getArchive().children(e)) {351Expected<MemoryBufferRef> mb = c.getMemoryBufferRef();352if (!mb || !hasObjCSection(*mb))353continue;354if (Error e = file->fetch(c, "-ObjC"))355error(toString(file) + ": -ObjC failed to load archive member: " +356toString(std::move(e)));357}358if (e)359error(toString(file) +360": Archive::children failed: " + toString(std::move(e)));361}362}363
364file->addLazySymbols();365loadedArchives[path] = ArchiveFileInfo{file, isCommandLineLoad};366newFile = file;367break;368}369case file_magic::macho_object:370newFile = make<ObjFile>(mbref, getModTime(path), "", isLazy);371break;372case file_magic::macho_dynamically_linked_shared_lib:373case file_magic::macho_dynamically_linked_shared_lib_stub:374case file_magic::tapi_file:375if (DylibFile *dylibFile =376loadDylib(mbref, nullptr, /*isBundleLoader=*/false, isExplicit))377newFile = dylibFile;378break;379case file_magic::bitcode:380newFile = make<BitcodeFile>(mbref, "", 0, isLazy);381break;382case file_magic::macho_executable:383case file_magic::macho_bundle:384// We only allow executable and bundle type here if it is used385// as a bundle loader.386if (!isBundleLoader)387error(path + ": unhandled file type");388if (DylibFile *dylibFile = loadDylib(mbref, nullptr, isBundleLoader))389newFile = dylibFile;390break;391default:392error(path + ": unhandled file type");393}394if (newFile && !isa<DylibFile>(newFile)) {395if ((isa<ObjFile>(newFile) || isa<BitcodeFile>(newFile)) && newFile->lazy &&396config->forceLoadObjC) {397for (Symbol *sym : newFile->symbols)398if (sym && sym->getName().starts_with(objc::symbol_names::klass)) {399extract(*newFile, "-ObjC");400break;401}402if (newFile->lazy && hasObjCSection(mbref))403extract(*newFile, "-ObjC");404}405
406// printArchiveMemberLoad() prints both .a and .o names, so no need to407// print the .a name here. Similarly skip lazy files.408if (config->printEachFile && magic != file_magic::archive && !isLazy)409message(toString(newFile));410inputFiles.insert(newFile);411}412return newFile;413}
414
415static std::vector<StringRef> missingAutolinkWarnings;416static void addLibrary(StringRef name, bool isNeeded, bool isWeak,417bool isReexport, bool isHidden, bool isExplicit,418LoadType loadType) {419if (std::optional<StringRef> path = findLibrary(name)) {420if (auto *dylibFile = dyn_cast_or_null<DylibFile>(421addFile(*path, loadType, /*isLazy=*/false, isExplicit,422/*isBundleLoader=*/false, isHidden))) {423if (isNeeded)424dylibFile->forceNeeded = true;425if (isWeak)426dylibFile->forceWeakImport = true;427if (isReexport) {428config->hasReexports = true;429dylibFile->reexport = true;430}431}432return;433}434if (loadType == LoadType::LCLinkerOption) {435missingAutolinkWarnings.push_back(436saver().save("auto-linked library not found for -l" + name));437return;438}439error("library not found for -l" + name);440}
441
442static DenseSet<StringRef> loadedObjectFrameworks;443static void addFramework(StringRef name, bool isNeeded, bool isWeak,444bool isReexport, bool isExplicit, LoadType loadType) {445if (std::optional<StringRef> path = findFramework(name)) {446if (loadedObjectFrameworks.contains(*path))447return;448
449InputFile *file =450addFile(*path, loadType, /*isLazy=*/false, isExplicit, false);451if (auto *dylibFile = dyn_cast_or_null<DylibFile>(file)) {452if (isNeeded)453dylibFile->forceNeeded = true;454if (isWeak)455dylibFile->forceWeakImport = true;456if (isReexport) {457config->hasReexports = true;458dylibFile->reexport = true;459}460} else if (isa_and_nonnull<ObjFile>(file) ||461isa_and_nonnull<BitcodeFile>(file)) {462// Cache frameworks containing object or bitcode files to avoid duplicate463// symbols. Frameworks containing static archives are cached separately464// in addFile() to share caching with libraries, and frameworks465// containing dylibs should allow overwriting of attributes such as466// forceNeeded by subsequent loads467loadedObjectFrameworks.insert(*path);468}469return;470}471if (loadType == LoadType::LCLinkerOption) {472missingAutolinkWarnings.push_back(473saver().save("auto-linked framework not found for -framework " + name));474return;475}476error("framework not found for -framework " + name);477}
478
479// Parses LC_LINKER_OPTION contents, which can add additional command line
480// flags. This directly parses the flags instead of using the standard argument
481// parser to improve performance.
482void macho::parseLCLinkerOption(483llvm::SmallVectorImpl<StringRef> &LCLinkerOptions, InputFile *f,484unsigned argc, StringRef data) {485if (config->ignoreAutoLink)486return;487
488SmallVector<StringRef, 4> argv;489size_t offset = 0;490for (unsigned i = 0; i < argc && offset < data.size(); ++i) {491argv.push_back(data.data() + offset);492offset += strlen(data.data() + offset) + 1;493}494if (argv.size() != argc || offset > data.size())495fatal(toString(f) + ": invalid LC_LINKER_OPTION");496
497unsigned i = 0;498StringRef arg = argv[i];499if (arg.consume_front("-l")) {500if (config->ignoreAutoLinkOptions.contains(arg))501return;502} else if (arg == "-framework") {503StringRef name = argv[++i];504if (config->ignoreAutoLinkOptions.contains(name))505return;506} else {507error(arg + " is not allowed in LC_LINKER_OPTION");508}509
510LCLinkerOptions.append(argv);511}
512
513void macho::resolveLCLinkerOptions() {514while (!unprocessedLCLinkerOptions.empty()) {515SmallVector<StringRef> LCLinkerOptions(unprocessedLCLinkerOptions);516unprocessedLCLinkerOptions.clear();517
518for (unsigned i = 0; i < LCLinkerOptions.size(); ++i) {519StringRef arg = LCLinkerOptions[i];520if (arg.consume_front("-l")) {521assert(!config->ignoreAutoLinkOptions.contains(arg));522addLibrary(arg, /*isNeeded=*/false, /*isWeak=*/false,523/*isReexport=*/false, /*isHidden=*/false,524/*isExplicit=*/false, LoadType::LCLinkerOption);525} else if (arg == "-framework") {526StringRef name = LCLinkerOptions[++i];527assert(!config->ignoreAutoLinkOptions.contains(name));528addFramework(name, /*isNeeded=*/false, /*isWeak=*/false,529/*isReexport=*/false, /*isExplicit=*/false,530LoadType::LCLinkerOption);531} else {532error(arg + " is not allowed in LC_LINKER_OPTION");533}534}535}536}
537
538static void addFileList(StringRef path, bool isLazy) {539std::optional<MemoryBufferRef> buffer = readFile(path);540if (!buffer)541return;542MemoryBufferRef mbref = *buffer;543for (StringRef path : args::getLines(mbref))544addFile(rerootPath(path), LoadType::CommandLine, isLazy);545}
546
547// We expect sub-library names of the form "libfoo", which will match a dylib
548// with a path of .*/libfoo.{dylib, tbd}.
549// XXX ld64 seems to ignore the extension entirely when matching sub-libraries;
550// I'm not sure what the use case for that is.
551static bool markReexport(StringRef searchName, ArrayRef<StringRef> extensions) {552for (InputFile *file : inputFiles) {553if (auto *dylibFile = dyn_cast<DylibFile>(file)) {554StringRef filename = path::filename(dylibFile->getName());555if (filename.consume_front(searchName) &&556(filename.empty() || llvm::is_contained(extensions, filename))) {557dylibFile->reexport = true;558return true;559}560}561}562return false;563}
564
565// This function is called on startup. We need this for LTO since
566// LTO calls LLVM functions to compile bitcode files to native code.
567// Technically this can be delayed until we read bitcode files, but
568// we don't bother to do lazily because the initialization is fast.
569static void initLLVM() {570InitializeAllTargets();571InitializeAllTargetMCs();572InitializeAllAsmPrinters();573InitializeAllAsmParsers();574}
575
576static bool compileBitcodeFiles() {577TimeTraceScope timeScope("LTO");578auto *lto = make<BitcodeCompiler>();579for (InputFile *file : inputFiles)580if (auto *bitcodeFile = dyn_cast<BitcodeFile>(file))581if (!file->lazy)582lto->add(*bitcodeFile);583
584std::vector<ObjFile *> compiled = lto->compile();585for (ObjFile *file : compiled)586inputFiles.insert(file);587
588return !compiled.empty();589}
590
591// Replaces common symbols with defined symbols residing in __common sections.
592// This function must be called after all symbol names are resolved (i.e. after
593// all InputFiles have been loaded.) As a result, later operations won't see
594// any CommonSymbols.
595static void replaceCommonSymbols() {596TimeTraceScope timeScope("Replace common symbols");597ConcatOutputSection *osec = nullptr;598for (Symbol *sym : symtab->getSymbols()) {599auto *common = dyn_cast<CommonSymbol>(sym);600if (common == nullptr)601continue;602
603// Casting to size_t will truncate large values on 32-bit architectures,604// but it's not really worth supporting the linking of 64-bit programs on605// 32-bit archs.606ArrayRef<uint8_t> data = {nullptr, static_cast<size_t>(common->size)};607// FIXME avoid creating one Section per symbol?608auto *section =609make<Section>(common->getFile(), segment_names::data,610section_names::common, S_ZEROFILL, /*addr=*/0);611auto *isec = make<ConcatInputSection>(*section, data, common->align);612if (!osec)613osec = ConcatOutputSection::getOrCreateForInput(isec);614isec->parent = osec;615addInputSection(isec);616
617// FIXME: CommonSymbol should store isReferencedDynamically, noDeadStrip618// and pass them on here.619replaceSymbol<Defined>(620sym, sym->getName(), common->getFile(), isec, /*value=*/0, common->size,621/*isWeakDef=*/false, /*isExternal=*/true, common->privateExtern,622/*includeInSymtab=*/true, /*isReferencedDynamically=*/false,623/*noDeadStrip=*/false);624}625}
626
627static void initializeSectionRenameMap() {628if (config->dataConst) {629SmallVector<StringRef> v{section_names::got,630section_names::authGot,631section_names::authPtr,632section_names::nonLazySymbolPtr,633section_names::const_,634section_names::cfString,635section_names::moduleInitFunc,636section_names::moduleTermFunc,637section_names::objcClassList,638section_names::objcNonLazyClassList,639section_names::objcCatList,640section_names::objcNonLazyCatList,641section_names::objcProtoList,642section_names::objCImageInfo};643for (StringRef s : v)644config->sectionRenameMap[{segment_names::data, s}] = {645segment_names::dataConst, s};646}647config->sectionRenameMap[{segment_names::text, section_names::staticInit}] = {648segment_names::text, section_names::text};649config->sectionRenameMap[{segment_names::import, section_names::pointers}] = {650config->dataConst ? segment_names::dataConst : segment_names::data,651section_names::nonLazySymbolPtr};652}
653
654static inline char toLowerDash(char x) {655if (x >= 'A' && x <= 'Z')656return x - 'A' + 'a';657else if (x == ' ')658return '-';659return x;660}
661
662static std::string lowerDash(StringRef s) {663return std::string(map_iterator(s.begin(), toLowerDash),664map_iterator(s.end(), toLowerDash));665}
666
667struct PlatformVersion {668PlatformType platform = PLATFORM_UNKNOWN;669llvm::VersionTuple minimum;670llvm::VersionTuple sdk;671};672
673static PlatformVersion parsePlatformVersion(const Arg *arg) {674assert(arg->getOption().getID() == OPT_platform_version);675StringRef platformStr = arg->getValue(0);676StringRef minVersionStr = arg->getValue(1);677StringRef sdkVersionStr = arg->getValue(2);678
679PlatformVersion platformVersion;680
681// TODO(compnerd) see if we can generate this case list via XMACROS682platformVersion.platform =683StringSwitch<PlatformType>(lowerDash(platformStr))684.Cases("macos", "1", PLATFORM_MACOS)685.Cases("ios", "2", PLATFORM_IOS)686.Cases("tvos", "3", PLATFORM_TVOS)687.Cases("watchos", "4", PLATFORM_WATCHOS)688.Cases("bridgeos", "5", PLATFORM_BRIDGEOS)689.Cases("mac-catalyst", "6", PLATFORM_MACCATALYST)690.Cases("ios-simulator", "7", PLATFORM_IOSSIMULATOR)691.Cases("tvos-simulator", "8", PLATFORM_TVOSSIMULATOR)692.Cases("watchos-simulator", "9", PLATFORM_WATCHOSSIMULATOR)693.Cases("driverkit", "10", PLATFORM_DRIVERKIT)694.Cases("xros", "11", PLATFORM_XROS)695.Cases("xros-simulator", "12", PLATFORM_XROS_SIMULATOR)696.Default(PLATFORM_UNKNOWN);697if (platformVersion.platform == PLATFORM_UNKNOWN)698error(Twine("malformed platform: ") + platformStr);699// TODO: check validity of version strings, which varies by platform700// NOTE: ld64 accepts version strings with 5 components701// llvm::VersionTuple accepts no more than 4 components702// Has Apple ever published version strings with 5 components?703if (platformVersion.minimum.tryParse(minVersionStr))704error(Twine("malformed minimum version: ") + minVersionStr);705if (platformVersion.sdk.tryParse(sdkVersionStr))706error(Twine("malformed sdk version: ") + sdkVersionStr);707return platformVersion;708}
709
710// Has the side-effect of setting Config::platformInfo and
711// potentially Config::secondaryPlatformInfo.
712static void setPlatformVersions(StringRef archName, const ArgList &args) {713std::map<PlatformType, PlatformVersion> platformVersions;714const PlatformVersion *lastVersionInfo = nullptr;715for (const Arg *arg : args.filtered(OPT_platform_version)) {716PlatformVersion version = parsePlatformVersion(arg);717
718// For each platform, the last flag wins:719// `-platform_version macos 2 3 -platform_version macos 4 5` has the same720// effect as just passing `-platform_version macos 4 5`.721// FIXME: ld64 warns on multiple flags for one platform. Should we?722platformVersions[version.platform] = version;723lastVersionInfo = &platformVersions[version.platform];724}725
726if (platformVersions.empty()) {727error("must specify -platform_version");728return;729}730if (platformVersions.size() > 2) {731error("must specify -platform_version at most twice");732return;733}734if (platformVersions.size() == 2) {735bool isZipperedCatalyst = platformVersions.count(PLATFORM_MACOS) &&736platformVersions.count(PLATFORM_MACCATALYST);737
738if (!isZipperedCatalyst) {739error("lld supports writing zippered outputs only for "740"macos and mac-catalyst");741} else if (config->outputType != MH_DYLIB &&742config->outputType != MH_BUNDLE) {743error("writing zippered outputs only valid for -dylib and -bundle");744}745
746config->platformInfo = {747MachO::Target(getArchitectureFromName(archName), PLATFORM_MACOS,748platformVersions[PLATFORM_MACOS].minimum),749platformVersions[PLATFORM_MACOS].sdk};750config->secondaryPlatformInfo = {751MachO::Target(getArchitectureFromName(archName), PLATFORM_MACCATALYST,752platformVersions[PLATFORM_MACCATALYST].minimum),753platformVersions[PLATFORM_MACCATALYST].sdk};754return;755}756
757config->platformInfo = {MachO::Target(getArchitectureFromName(archName),758lastVersionInfo->platform,759lastVersionInfo->minimum),760lastVersionInfo->sdk};761}
762
763// Has the side-effect of setting Config::target.
764static TargetInfo *createTargetInfo(InputArgList &args) {765StringRef archName = args.getLastArgValue(OPT_arch);766if (archName.empty()) {767error("must specify -arch");768return nullptr;769}770
771setPlatformVersions(archName, args);772auto [cpuType, cpuSubtype] = getCPUTypeFromArchitecture(config->arch());773switch (cpuType) {774case CPU_TYPE_X86_64:775return createX86_64TargetInfo();776case CPU_TYPE_ARM64:777return createARM64TargetInfo();778case CPU_TYPE_ARM64_32:779return createARM64_32TargetInfo();780default:781error("missing or unsupported -arch " + archName);782return nullptr;783}784}
785
786static UndefinedSymbolTreatment787getUndefinedSymbolTreatment(const ArgList &args) {788StringRef treatmentStr = args.getLastArgValue(OPT_undefined);789auto treatment =790StringSwitch<UndefinedSymbolTreatment>(treatmentStr)791.Cases("error", "", UndefinedSymbolTreatment::error)792.Case("warning", UndefinedSymbolTreatment::warning)793.Case("suppress", UndefinedSymbolTreatment::suppress)794.Case("dynamic_lookup", UndefinedSymbolTreatment::dynamic_lookup)795.Default(UndefinedSymbolTreatment::unknown);796if (treatment == UndefinedSymbolTreatment::unknown) {797warn(Twine("unknown -undefined TREATMENT '") + treatmentStr +798"', defaulting to 'error'");799treatment = UndefinedSymbolTreatment::error;800} else if (config->namespaceKind == NamespaceKind::twolevel &&801(treatment == UndefinedSymbolTreatment::warning ||802treatment == UndefinedSymbolTreatment::suppress)) {803if (treatment == UndefinedSymbolTreatment::warning)804fatal("'-undefined warning' only valid with '-flat_namespace'");805else806fatal("'-undefined suppress' only valid with '-flat_namespace'");807treatment = UndefinedSymbolTreatment::error;808}809return treatment;810}
811
812static ICFLevel getICFLevel(const ArgList &args) {813StringRef icfLevelStr = args.getLastArgValue(OPT_icf_eq);814auto icfLevel = StringSwitch<ICFLevel>(icfLevelStr)815.Cases("none", "", ICFLevel::none)816.Case("safe", ICFLevel::safe)817.Case("all", ICFLevel::all)818.Default(ICFLevel::unknown);819if (icfLevel == ICFLevel::unknown) {820warn(Twine("unknown --icf=OPTION `") + icfLevelStr +821"', defaulting to `none'");822icfLevel = ICFLevel::none;823}824return icfLevel;825}
826
827static ObjCStubsMode getObjCStubsMode(const ArgList &args) {828const Arg *arg = args.getLastArg(OPT_objc_stubs_fast, OPT_objc_stubs_small);829if (!arg)830return ObjCStubsMode::fast;831
832if (arg->getOption().getID() == OPT_objc_stubs_small) {833if (is_contained({AK_arm64e, AK_arm64}, config->arch()))834return ObjCStubsMode::small;835else836warn("-objc_stubs_small is not yet implemented, defaulting to "837"-objc_stubs_fast");838}839return ObjCStubsMode::fast;840}
841
842static void warnIfDeprecatedOption(const Option &opt) {843if (!opt.getGroup().isValid())844return;845if (opt.getGroup().getID() == OPT_grp_deprecated) {846warn("Option `" + opt.getPrefixedName() + "' is deprecated in ld64:");847warn(opt.getHelpText());848}849}
850
851static void warnIfUnimplementedOption(const Option &opt) {852if (!opt.getGroup().isValid() || !opt.hasFlag(DriverFlag::HelpHidden))853return;854switch (opt.getGroup().getID()) {855case OPT_grp_deprecated:856// warn about deprecated options elsewhere857break;858case OPT_grp_undocumented:859warn("Option `" + opt.getPrefixedName() +860"' is undocumented. Should lld implement it?");861break;862case OPT_grp_obsolete:863warn("Option `" + opt.getPrefixedName() +864"' is obsolete. Please modernize your usage.");865break;866case OPT_grp_ignored:867warn("Option `" + opt.getPrefixedName() + "' is ignored.");868break;869case OPT_grp_ignored_silently:870break;871default:872warn("Option `" + opt.getPrefixedName() +873"' is not yet implemented. Stay tuned...");874break;875}876}
877
878static const char *getReproduceOption(InputArgList &args) {879if (const Arg *arg = args.getLastArg(OPT_reproduce))880return arg->getValue();881return getenv("LLD_REPRODUCE");882}
883
884// Parse options of the form "old;new".
885static std::pair<StringRef, StringRef> getOldNewOptions(opt::InputArgList &args,886unsigned id) {887auto *arg = args.getLastArg(id);888if (!arg)889return {"", ""};890
891StringRef s = arg->getValue();892std::pair<StringRef, StringRef> ret = s.split(';');893if (ret.second.empty())894error(arg->getSpelling() + " expects 'old;new' format, but got " + s);895return ret;896}
897
898// Parse options of the form "old;new[;extra]".
899static std::tuple<StringRef, StringRef, StringRef>900getOldNewOptionsExtra(opt::InputArgList &args, unsigned id) {901auto [oldDir, second] = getOldNewOptions(args, id);902auto [newDir, extraDir] = second.split(';');903return {oldDir, newDir, extraDir};904}
905
906static void parseClangOption(StringRef opt, const Twine &msg) {907std::string err;908raw_string_ostream os(err);909
910const char *argv[] = {"lld", opt.data()};911if (cl::ParseCommandLineOptions(2, argv, "", &os))912return;913os.flush();914error(msg + ": " + StringRef(err).trim());915}
916
917static uint32_t parseDylibVersion(const ArgList &args, unsigned id) {918const Arg *arg = args.getLastArg(id);919if (!arg)920return 0;921
922if (config->outputType != MH_DYLIB) {923error(arg->getAsString(args) + ": only valid with -dylib");924return 0;925}926
927PackedVersion version;928if (!version.parse32(arg->getValue())) {929error(arg->getAsString(args) + ": malformed version");930return 0;931}932
933return version.rawValue();934}
935
936static uint32_t parseProtection(StringRef protStr) {937uint32_t prot = 0;938for (char c : protStr) {939switch (c) {940case 'r':941prot |= VM_PROT_READ;942break;943case 'w':944prot |= VM_PROT_WRITE;945break;946case 'x':947prot |= VM_PROT_EXECUTE;948break;949case '-':950break;951default:952error("unknown -segprot letter '" + Twine(c) + "' in " + protStr);953return 0;954}955}956return prot;957}
958
959static std::vector<SectionAlign> parseSectAlign(const opt::InputArgList &args) {960std::vector<SectionAlign> sectAligns;961for (const Arg *arg : args.filtered(OPT_sectalign)) {962StringRef segName = arg->getValue(0);963StringRef sectName = arg->getValue(1);964StringRef alignStr = arg->getValue(2);965alignStr.consume_front_insensitive("0x");966uint32_t align;967if (alignStr.getAsInteger(16, align)) {968error("-sectalign: failed to parse '" + StringRef(arg->getValue(2)) +969"' as number");970continue;971}972if (!isPowerOf2_32(align)) {973error("-sectalign: '" + StringRef(arg->getValue(2)) +974"' (in base 16) not a power of two");975continue;976}977sectAligns.push_back({segName, sectName, align});978}979return sectAligns;980}
981
982PlatformType macho::removeSimulator(PlatformType platform) {983switch (platform) {984case PLATFORM_IOSSIMULATOR:985return PLATFORM_IOS;986case PLATFORM_TVOSSIMULATOR:987return PLATFORM_TVOS;988case PLATFORM_WATCHOSSIMULATOR:989return PLATFORM_WATCHOS;990case PLATFORM_XROS_SIMULATOR:991return PLATFORM_XROS;992default:993return platform;994}995}
996
997static bool supportsNoPie() {998return !(config->arch() == AK_arm64 || config->arch() == AK_arm64e ||999config->arch() == AK_arm64_32);1000}
1001
1002static bool shouldAdhocSignByDefault(Architecture arch, PlatformType platform) {1003if (arch != AK_arm64 && arch != AK_arm64e)1004return false;1005
1006return platform == PLATFORM_MACOS || platform == PLATFORM_IOSSIMULATOR ||1007platform == PLATFORM_TVOSSIMULATOR ||1008platform == PLATFORM_WATCHOSSIMULATOR ||1009platform == PLATFORM_XROS_SIMULATOR;1010}
1011
1012static bool dataConstDefault(const InputArgList &args) {1013static const std::array<std::pair<PlatformType, VersionTuple>, 6> minVersion =1014{{{PLATFORM_MACOS, VersionTuple(10, 15)},1015{PLATFORM_IOS, VersionTuple(13, 0)},1016{PLATFORM_TVOS, VersionTuple(13, 0)},1017{PLATFORM_WATCHOS, VersionTuple(6, 0)},1018{PLATFORM_XROS, VersionTuple(1, 0)},1019{PLATFORM_BRIDGEOS, VersionTuple(4, 0)}}};1020PlatformType platform = removeSimulator(config->platformInfo.target.Platform);1021auto it = llvm::find_if(minVersion,1022[&](const auto &p) { return p.first == platform; });1023if (it != minVersion.end())1024if (config->platformInfo.target.MinDeployment < it->second)1025return false;1026
1027switch (config->outputType) {1028case MH_EXECUTE:1029return !(args.hasArg(OPT_no_pie) && supportsNoPie());1030case MH_BUNDLE:1031// FIXME: return false when -final_name ...1032// has prefix "/System/Library/UserEventPlugins/"1033// or matches "/usr/libexec/locationd" "/usr/libexec/terminusd"1034return true;1035case MH_DYLIB:1036return true;1037case MH_OBJECT:1038return false;1039default:1040llvm_unreachable(1041"unsupported output type for determining data-const default");1042}1043return false;1044}
1045
1046static bool shouldEmitChainedFixups(const InputArgList &args) {1047const Arg *arg = args.getLastArg(OPT_fixup_chains, OPT_no_fixup_chains);1048if (arg && arg->getOption().matches(OPT_no_fixup_chains))1049return false;1050
1051bool isRequested = arg != nullptr;1052
1053// Version numbers taken from the Xcode 13.3 release notes.1054static const std::array<std::pair<PlatformType, VersionTuple>, 5> minVersion =1055{{{PLATFORM_MACOS, VersionTuple(11, 0)},1056{PLATFORM_IOS, VersionTuple(13, 4)},1057{PLATFORM_TVOS, VersionTuple(14, 0)},1058{PLATFORM_WATCHOS, VersionTuple(7, 0)},1059{PLATFORM_XROS, VersionTuple(1, 0)}}};1060PlatformType platform = removeSimulator(config->platformInfo.target.Platform);1061auto it = llvm::find_if(minVersion,1062[&](const auto &p) { return p.first == platform; });1063if (it != minVersion.end() &&1064it->second > config->platformInfo.target.MinDeployment) {1065if (!isRequested)1066return false;1067
1068warn("-fixup_chains requires " + getPlatformName(config->platform()) + " " +1069it->second.getAsString() + ", which is newer than target minimum of " +1070config->platformInfo.target.MinDeployment.getAsString());1071}1072
1073if (!is_contained({AK_x86_64, AK_x86_64h, AK_arm64}, config->arch())) {1074if (isRequested)1075error("-fixup_chains is only supported on x86_64 and arm64 targets");1076return false;1077}1078
1079if (!config->isPic) {1080if (isRequested)1081error("-fixup_chains is incompatible with -no_pie");1082return false;1083}1084
1085// TODO: Enable by default once stable.1086return isRequested;1087}
1088
1089static bool shouldEmitRelativeMethodLists(const InputArgList &args) {1090const Arg *arg = args.getLastArg(OPT_objc_relative_method_lists,1091OPT_no_objc_relative_method_lists);1092if (arg && arg->getOption().getID() == OPT_objc_relative_method_lists)1093return true;1094if (arg && arg->getOption().getID() == OPT_no_objc_relative_method_lists)1095return false;1096
1097// TODO: If no flag is specified, don't default to false, but instead:1098// - default false on < ios141099// - default true on >= ios141100// For now, until this feature is confirmed stable, default to false if no1101// flag is explicitly specified1102return false;1103}
1104
1105void SymbolPatterns::clear() {1106literals.clear();1107globs.clear();1108}
1109
1110void SymbolPatterns::insert(StringRef symbolName) {1111if (symbolName.find_first_of("*?[]") == StringRef::npos)1112literals.insert(CachedHashStringRef(symbolName));1113else if (Expected<GlobPattern> pattern = GlobPattern::create(symbolName))1114globs.emplace_back(*pattern);1115else1116error("invalid symbol-name pattern: " + symbolName);1117}
1118
1119bool SymbolPatterns::matchLiteral(StringRef symbolName) const {1120return literals.contains(CachedHashStringRef(symbolName));1121}
1122
1123bool SymbolPatterns::matchGlob(StringRef symbolName) const {1124for (const GlobPattern &glob : globs)1125if (glob.match(symbolName))1126return true;1127return false;1128}
1129
1130bool SymbolPatterns::match(StringRef symbolName) const {1131return matchLiteral(symbolName) || matchGlob(symbolName);1132}
1133
1134static void parseSymbolPatternsFile(const Arg *arg,1135SymbolPatterns &symbolPatterns) {1136StringRef path = arg->getValue();1137std::optional<MemoryBufferRef> buffer = readFile(path);1138if (!buffer) {1139error("Could not read symbol file: " + path);1140return;1141}1142MemoryBufferRef mbref = *buffer;1143for (StringRef line : args::getLines(mbref)) {1144line = line.take_until([](char c) { return c == '#'; }).trim();1145if (!line.empty())1146symbolPatterns.insert(line);1147}1148}
1149
1150static void handleSymbolPatterns(InputArgList &args,1151SymbolPatterns &symbolPatterns,1152unsigned singleOptionCode,1153unsigned listFileOptionCode) {1154for (const Arg *arg : args.filtered(singleOptionCode))1155symbolPatterns.insert(arg->getValue());1156for (const Arg *arg : args.filtered(listFileOptionCode))1157parseSymbolPatternsFile(arg, symbolPatterns);1158}
1159
1160static void createFiles(const InputArgList &args) {1161TimeTraceScope timeScope("Load input files");1162// This loop should be reserved for options whose exact ordering matters.1163// Other options should be handled via filtered() and/or getLastArg().1164bool isLazy = false;1165// If we've processed an opening --start-lib, without a matching --end-lib1166bool inLib = false;1167for (const Arg *arg : args) {1168const Option &opt = arg->getOption();1169warnIfDeprecatedOption(opt);1170warnIfUnimplementedOption(opt);1171
1172switch (opt.getID()) {1173case OPT_INPUT:1174addFile(rerootPath(arg->getValue()), LoadType::CommandLine, isLazy);1175break;1176case OPT_needed_library:1177if (auto *dylibFile = dyn_cast_or_null<DylibFile>(1178addFile(rerootPath(arg->getValue()), LoadType::CommandLine)))1179dylibFile->forceNeeded = true;1180break;1181case OPT_reexport_library:1182if (auto *dylibFile = dyn_cast_or_null<DylibFile>(1183addFile(rerootPath(arg->getValue()), LoadType::CommandLine))) {1184config->hasReexports = true;1185dylibFile->reexport = true;1186}1187break;1188case OPT_weak_library:1189if (auto *dylibFile = dyn_cast_or_null<DylibFile>(1190addFile(rerootPath(arg->getValue()), LoadType::CommandLine)))1191dylibFile->forceWeakImport = true;1192break;1193case OPT_filelist:1194addFileList(arg->getValue(), isLazy);1195break;1196case OPT_force_load:1197addFile(rerootPath(arg->getValue()), LoadType::CommandLineForce);1198break;1199case OPT_load_hidden:1200addFile(rerootPath(arg->getValue()), LoadType::CommandLine,1201/*isLazy=*/false, /*isExplicit=*/true, /*isBundleLoader=*/false,1202/*isForceHidden=*/true);1203break;1204case OPT_l:1205case OPT_needed_l:1206case OPT_reexport_l:1207case OPT_weak_l:1208case OPT_hidden_l:1209addLibrary(arg->getValue(), opt.getID() == OPT_needed_l,1210opt.getID() == OPT_weak_l, opt.getID() == OPT_reexport_l,1211opt.getID() == OPT_hidden_l,1212/*isExplicit=*/true, LoadType::CommandLine);1213break;1214case OPT_framework:1215case OPT_needed_framework:1216case OPT_reexport_framework:1217case OPT_weak_framework:1218addFramework(arg->getValue(), opt.getID() == OPT_needed_framework,1219opt.getID() == OPT_weak_framework,1220opt.getID() == OPT_reexport_framework, /*isExplicit=*/true,1221LoadType::CommandLine);1222break;1223case OPT_start_lib:1224if (inLib)1225error("nested --start-lib");1226inLib = true;1227if (!config->allLoad)1228isLazy = true;1229break;1230case OPT_end_lib:1231if (!inLib)1232error("stray --end-lib");1233inLib = false;1234isLazy = false;1235break;1236default:1237break;1238}1239}1240}
1241
1242static void gatherInputSections() {1243TimeTraceScope timeScope("Gathering input sections");1244for (const InputFile *file : inputFiles) {1245for (const Section *section : file->sections) {1246// Compact unwind entries require special handling elsewhere. (In1247// contrast, EH frames are handled like regular ConcatInputSections.)1248if (section->name == section_names::compactUnwind)1249continue;1250for (const Subsection &subsection : section->subsections)1251addInputSection(subsection.isec);1252}1253if (!file->objCImageInfo.empty())1254in.objCImageInfo->addFile(file);1255}1256}
1257
1258static void foldIdenticalLiterals() {1259TimeTraceScope timeScope("Fold identical literals");1260// We always create a cStringSection, regardless of whether dedupLiterals is1261// true. If it isn't, we simply create a non-deduplicating CStringSection.1262// Either way, we must unconditionally finalize it here.1263in.cStringSection->finalizeContents();1264in.objcMethnameSection->finalizeContents();1265in.wordLiteralSection->finalizeContents();1266}
1267
1268static void addSynthenticMethnames() {1269std::string &data = *make<std::string>();1270llvm::raw_string_ostream os(data);1271for (Symbol *sym : symtab->getSymbols())1272if (isa<Undefined>(sym))1273if (ObjCStubsSection::isObjCStubSymbol(sym))1274os << ObjCStubsSection::getMethname(sym) << '\0';1275
1276if (data.empty())1277return;1278
1279const auto *buf = reinterpret_cast<const uint8_t *>(data.c_str());1280Section §ion = *make<Section>(/*file=*/nullptr, segment_names::text,1281section_names::objcMethname,1282S_CSTRING_LITERALS, /*addr=*/0);1283
1284auto *isec =1285make<CStringInputSection>(section, ArrayRef<uint8_t>{buf, data.size()},1286/*align=*/1, /*dedupLiterals=*/true);1287isec->splitIntoPieces();1288for (auto &piece : isec->pieces)1289piece.live = true;1290section.subsections.push_back({0, isec});1291in.objcMethnameSection->addInput(isec);1292in.objcMethnameSection->isec->markLive(0);1293}
1294
1295static void referenceStubBinder() {1296bool needsStubHelper = config->outputType == MH_DYLIB ||1297config->outputType == MH_EXECUTE ||1298config->outputType == MH_BUNDLE;1299if (!needsStubHelper || !symtab->find("dyld_stub_binder"))1300return;1301
1302// dyld_stub_binder is used by dyld to resolve lazy bindings. This code here1303// adds a opportunistic reference to dyld_stub_binder if it happens to exist.1304// dyld_stub_binder is in libSystem.dylib, which is usually linked in. This1305// isn't needed for correctness, but the presence of that symbol suppresses1306// "no symbols" diagnostics from `nm`.1307// StubHelperSection::setUp() adds a reference and errors out if1308// dyld_stub_binder doesn't exist in case it is actually needed.1309symtab->addUndefined("dyld_stub_binder", /*file=*/nullptr, /*isWeak=*/false);1310}
1311
1312static void createAliases() {1313for (const auto &pair : config->aliasedSymbols) {1314if (const auto &sym = symtab->find(pair.first)) {1315if (const auto &defined = dyn_cast<Defined>(sym)) {1316symtab->aliasDefined(defined, pair.second, defined->getFile())1317->noDeadStrip = true;1318} else {1319error("TODO: support aliasing to symbols of kind " +1320Twine(sym->kind()));1321}1322} else {1323warn("undefined base symbol '" + pair.first + "' for alias '" +1324pair.second + "'\n");1325}1326}1327
1328for (const InputFile *file : inputFiles) {1329if (auto *objFile = dyn_cast<ObjFile>(file)) {1330for (const AliasSymbol *alias : objFile->aliases) {1331if (const auto &aliased = symtab->find(alias->getAliasedName())) {1332if (const auto &defined = dyn_cast<Defined>(aliased)) {1333symtab->aliasDefined(defined, alias->getName(), alias->getFile(),1334alias->privateExtern);1335} else {1336// Common, dylib, and undefined symbols are all valid alias1337// referents (undefineds can become valid Defined symbols later on1338// in the link.)1339error("TODO: support aliasing to symbols of kind " +1340Twine(aliased->kind()));1341}1342} else {1343// This shouldn't happen since MC generates undefined symbols to1344// represent the alias referents. Thus we fatal() instead of just1345// warning here.1346fatal("unable to find alias referent " + alias->getAliasedName() +1347" for " + alias->getName());1348}1349}1350}1351}1352}
1353
1354static void handleExplicitExports() {1355static constexpr int kMaxWarnings = 3;1356if (config->hasExplicitExports) {1357std::atomic<uint64_t> warningsCount{0};1358parallelForEach(symtab->getSymbols(), [&warningsCount](Symbol *sym) {1359if (auto *defined = dyn_cast<Defined>(sym)) {1360if (config->exportedSymbols.match(sym->getName())) {1361if (defined->privateExtern) {1362if (defined->weakDefCanBeHidden) {1363// weak_def_can_be_hidden symbols behave similarly to1364// private_extern symbols in most cases, except for when1365// it is explicitly exported.1366// The former can be exported but the latter cannot.1367defined->privateExtern = false;1368} else {1369// Only print the first 3 warnings verbosely, and1370// shorten the rest to avoid crowding logs.1371if (warningsCount.fetch_add(1, std::memory_order_relaxed) <1372kMaxWarnings)1373warn("cannot export hidden symbol " + toString(*defined) +1374"\n>>> defined in " + toString(defined->getFile()));1375}1376}1377} else {1378defined->privateExtern = true;1379}1380} else if (auto *dysym = dyn_cast<DylibSymbol>(sym)) {1381dysym->shouldReexport = config->exportedSymbols.match(sym->getName());1382}1383});1384if (warningsCount > kMaxWarnings)1385warn("<... " + Twine(warningsCount - kMaxWarnings) +1386" more similar warnings...>");1387} else if (!config->unexportedSymbols.empty()) {1388parallelForEach(symtab->getSymbols(), [](Symbol *sym) {1389if (auto *defined = dyn_cast<Defined>(sym))1390if (config->unexportedSymbols.match(defined->getName()))1391defined->privateExtern = true;1392});1393}1394}
1395
1396static void eraseInitializerSymbols() {1397for (ConcatInputSection *isec : in.initOffsets->inputs())1398for (Defined *sym : isec->symbols)1399sym->used = false;1400}
1401
1402namespace lld {1403namespace macho {1404bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,1405llvm::raw_ostream &stderrOS, bool exitEarly, bool disableOutput) {1406// This driver-specific context will be freed later by lldMain().1407auto *ctx = new CommonLinkerContext;1408
1409ctx->e.initialize(stdoutOS, stderrOS, exitEarly, disableOutput);1410ctx->e.cleanupCallback = []() {1411resolvedFrameworks.clear();1412resolvedLibraries.clear();1413cachedReads.clear();1414concatOutputSections.clear();1415inputFiles.clear();1416inputSections.clear();1417inputSectionsOrder = 0;1418loadedArchives.clear();1419loadedObjectFrameworks.clear();1420missingAutolinkWarnings.clear();1421syntheticSections.clear();1422thunkMap.clear();1423unprocessedLCLinkerOptions.clear();1424ObjCSelRefsHelper::cleanup();1425
1426firstTLVDataSection = nullptr;1427tar = nullptr;1428memset(&in, 0, sizeof(in));1429
1430resetLoadedDylibs();1431resetOutputSegments();1432resetWriter();1433InputFile::resetIdCount();1434
1435objc::doCleanup();1436};1437
1438ctx->e.logName = args::getFilenameWithoutExe(argsArr[0]);1439
1440MachOOptTable parser;1441InputArgList args = parser.parse(argsArr.slice(1));1442
1443ctx->e.errorLimitExceededMsg = "too many errors emitted, stopping now "1444"(use --error-limit=0 to see all errors)";1445ctx->e.errorLimit = args::getInteger(args, OPT_error_limit_eq, 20);1446ctx->e.verbose = args.hasArg(OPT_verbose);1447
1448if (args.hasArg(OPT_help_hidden)) {1449parser.printHelp(argsArr[0], /*showHidden=*/true);1450return true;1451}1452if (args.hasArg(OPT_help)) {1453parser.printHelp(argsArr[0], /*showHidden=*/false);1454return true;1455}1456if (args.hasArg(OPT_version)) {1457message(getLLDVersion());1458return true;1459}1460
1461config = std::make_unique<Configuration>();1462symtab = std::make_unique<SymbolTable>();1463config->outputType = getOutputType(args);1464target = createTargetInfo(args);1465depTracker = std::make_unique<DependencyTracker>(1466args.getLastArgValue(OPT_dependency_info));1467
1468config->ltoo = args::getInteger(args, OPT_lto_O, 2);1469if (config->ltoo > 3)1470error("--lto-O: invalid optimization level: " + Twine(config->ltoo));1471unsigned ltoCgo =1472args::getInteger(args, OPT_lto_CGO, args::getCGOptLevel(config->ltoo));1473if (auto level = CodeGenOpt::getLevel(ltoCgo))1474config->ltoCgo = *level;1475else1476error("--lto-CGO: invalid codegen optimization level: " + Twine(ltoCgo));1477
1478if (errorCount())1479return false;1480
1481if (args.hasArg(OPT_pagezero_size)) {1482uint64_t pagezeroSize = args::getHex(args, OPT_pagezero_size, 0);1483
1484// ld64 does something really weird. It attempts to realign the value to the1485// page size, but assumes the page size is 4K. This doesn't work with most1486// of Apple's ARM64 devices, which use a page size of 16K. This means that1487// it will first 4K align it by rounding down, then round up to 16K. This1488// probably only happened because no one using this arg with anything other1489// then 0, so no one checked if it did what is what it says it does.1490
1491// So we are not copying this weird behavior and doing the it in a logical1492// way, by always rounding down to page size.1493if (!isAligned(Align(target->getPageSize()), pagezeroSize)) {1494pagezeroSize -= pagezeroSize % target->getPageSize();1495warn("__PAGEZERO size is not page aligned, rounding down to 0x" +1496Twine::utohexstr(pagezeroSize));1497}1498
1499target->pageZeroSize = pagezeroSize;1500}1501
1502config->osoPrefix = args.getLastArgValue(OPT_oso_prefix);1503if (!config->osoPrefix.empty()) {1504// Expand special characters, such as ".", "..", or "~", if present.1505// Note: LD64 only expands "." and not other special characters.1506// That seems silly to imitate so we will not try to follow it, but rather1507// just use real_path() to do it.1508
1509// The max path length is 4096, in theory. However that seems quite long1510// and seems unlikely that any one would want to strip everything from the1511// path. Hence we've picked a reasonably large number here.1512SmallString<1024> expanded;1513if (!fs::real_path(config->osoPrefix, expanded,1514/*expand_tilde=*/true)) {1515// Note: LD64 expands "." to be `<current_dir>/`1516// (ie., it has a slash suffix) whereas real_path() doesn't.1517// So we have to append '/' to be consistent.1518StringRef sep = sys::path::get_separator();1519// real_path removes trailing slashes as part of the normalization, but1520// these are meaningful for our text based stripping1521if (config->osoPrefix == "." || config->osoPrefix.ends_with(sep))1522expanded += sep;1523config->osoPrefix = saver().save(expanded.str());1524}1525}1526
1527bool pie = args.hasFlag(OPT_pie, OPT_no_pie, true);1528if (!supportsNoPie() && !pie) {1529warn("-no_pie ignored for arm64");1530pie = true;1531}1532
1533config->isPic = config->outputType == MH_DYLIB ||1534config->outputType == MH_BUNDLE ||1535(config->outputType == MH_EXECUTE && pie);1536
1537// Must be set before any InputSections and Symbols are created.1538config->deadStrip = args.hasArg(OPT_dead_strip);1539
1540config->systemLibraryRoots = getSystemLibraryRoots(args);1541if (const char *path = getReproduceOption(args)) {1542// Note that --reproduce is a debug option so you can ignore it1543// if you are trying to understand the whole picture of the code.1544Expected<std::unique_ptr<TarWriter>> errOrWriter =1545TarWriter::create(path, path::stem(path));1546if (errOrWriter) {1547tar = std::move(*errOrWriter);1548tar->append("response.txt", createResponseFile(args));1549tar->append("version.txt", getLLDVersion() + "\n");1550} else {1551error("--reproduce: " + toString(errOrWriter.takeError()));1552}1553}1554
1555if (auto *arg = args.getLastArg(OPT_threads_eq)) {1556StringRef v(arg->getValue());1557unsigned threads = 0;1558if (!llvm::to_integer(v, threads, 0) || threads == 0)1559error(arg->getSpelling() + ": expected a positive integer, but got '" +1560arg->getValue() + "'");1561parallel::strategy = hardware_concurrency(threads);1562config->thinLTOJobs = v;1563}1564if (auto *arg = args.getLastArg(OPT_thinlto_jobs_eq))1565config->thinLTOJobs = arg->getValue();1566if (!get_threadpool_strategy(config->thinLTOJobs))1567error("--thinlto-jobs: invalid job count: " + config->thinLTOJobs);1568
1569for (const Arg *arg : args.filtered(OPT_u)) {1570config->explicitUndefineds.push_back(symtab->addUndefined(1571arg->getValue(), /*file=*/nullptr, /*isWeakRef=*/false));1572}1573
1574for (const Arg *arg : args.filtered(OPT_U))1575config->explicitDynamicLookups.insert(arg->getValue());1576
1577config->mapFile = args.getLastArgValue(OPT_map);1578config->optimize = args::getInteger(args, OPT_O, 1);1579config->outputFile = args.getLastArgValue(OPT_o, "a.out");1580config->finalOutput =1581args.getLastArgValue(OPT_final_output, config->outputFile);1582config->astPaths = args.getAllArgValues(OPT_add_ast_path);1583config->headerPad = args::getHex(args, OPT_headerpad, /*Default=*/32);1584config->headerPadMaxInstallNames =1585args.hasArg(OPT_headerpad_max_install_names);1586config->printDylibSearch =1587args.hasArg(OPT_print_dylib_search) || getenv("RC_TRACE_DYLIB_SEARCHING");1588config->printEachFile = args.hasArg(OPT_t);1589config->printWhyLoad = args.hasArg(OPT_why_load);1590config->omitDebugInfo = args.hasArg(OPT_S);1591config->errorForArchMismatch = args.hasArg(OPT_arch_errors_fatal);1592if (const Arg *arg = args.getLastArg(OPT_bundle_loader)) {1593if (config->outputType != MH_BUNDLE)1594error("-bundle_loader can only be used with MachO bundle output");1595addFile(arg->getValue(), LoadType::CommandLine, /*isLazy=*/false,1596/*isExplicit=*/false, /*isBundleLoader=*/true);1597}1598for (auto *arg : args.filtered(OPT_dyld_env)) {1599StringRef envPair(arg->getValue());1600if (!envPair.contains('='))1601error("-dyld_env's argument is malformed. Expected "1602"-dyld_env <ENV_VAR>=<VALUE>, got `" +1603envPair + "`");1604config->dyldEnvs.push_back(envPair);1605}1606if (!config->dyldEnvs.empty() && config->outputType != MH_EXECUTE)1607error("-dyld_env can only be used when creating executable output");1608
1609if (const Arg *arg = args.getLastArg(OPT_umbrella)) {1610if (config->outputType != MH_DYLIB)1611warn("-umbrella used, but not creating dylib");1612config->umbrella = arg->getValue();1613}1614config->ltoObjPath = args.getLastArgValue(OPT_object_path_lto);1615config->thinLTOCacheDir = args.getLastArgValue(OPT_cache_path_lto);1616config->thinLTOCachePolicy = getLTOCachePolicy(args);1617config->thinLTOEmitImportsFiles = args.hasArg(OPT_thinlto_emit_imports_files);1618config->thinLTOEmitIndexFiles = args.hasArg(OPT_thinlto_emit_index_files) ||1619args.hasArg(OPT_thinlto_index_only) ||1620args.hasArg(OPT_thinlto_index_only_eq);1621config->thinLTOIndexOnly = args.hasArg(OPT_thinlto_index_only) ||1622args.hasArg(OPT_thinlto_index_only_eq);1623config->thinLTOIndexOnlyArg = args.getLastArgValue(OPT_thinlto_index_only_eq);1624config->thinLTOObjectSuffixReplace =1625getOldNewOptions(args, OPT_thinlto_object_suffix_replace_eq);1626std::tie(config->thinLTOPrefixReplaceOld, config->thinLTOPrefixReplaceNew,1627config->thinLTOPrefixReplaceNativeObject) =1628getOldNewOptionsExtra(args, OPT_thinlto_prefix_replace_eq);1629if (config->thinLTOEmitIndexFiles && !config->thinLTOIndexOnly) {1630if (args.hasArg(OPT_thinlto_object_suffix_replace_eq))1631error("--thinlto-object-suffix-replace is not supported with "1632"--thinlto-emit-index-files");1633else if (args.hasArg(OPT_thinlto_prefix_replace_eq))1634error("--thinlto-prefix-replace is not supported with "1635"--thinlto-emit-index-files");1636}1637if (!config->thinLTOPrefixReplaceNativeObject.empty() &&1638config->thinLTOIndexOnlyArg.empty()) {1639error("--thinlto-prefix-replace=old_dir;new_dir;obj_dir must be used with "1640"--thinlto-index-only=");1641}1642config->runtimePaths = args::getStrings(args, OPT_rpath);1643config->allLoad = args.hasFlag(OPT_all_load, OPT_noall_load, false);1644config->archMultiple = args.hasArg(OPT_arch_multiple);1645config->applicationExtension = args.hasFlag(1646OPT_application_extension, OPT_no_application_extension, false);1647config->exportDynamic = args.hasArg(OPT_export_dynamic);1648config->forceLoadObjC = args.hasArg(OPT_ObjC);1649config->forceLoadSwift = args.hasArg(OPT_force_load_swift_libs);1650config->deadStripDylibs = args.hasArg(OPT_dead_strip_dylibs);1651config->demangle = args.hasArg(OPT_demangle);1652config->implicitDylibs = !args.hasArg(OPT_no_implicit_dylibs);1653config->emitFunctionStarts =1654args.hasFlag(OPT_function_starts, OPT_no_function_starts, true);1655config->emitDataInCodeInfo =1656args.hasFlag(OPT_data_in_code_info, OPT_no_data_in_code_info, true);1657config->emitChainedFixups = shouldEmitChainedFixups(args);1658config->emitInitOffsets =1659config->emitChainedFixups || args.hasArg(OPT_init_offsets);1660config->emitRelativeMethodLists = shouldEmitRelativeMethodLists(args);1661config->icfLevel = getICFLevel(args);1662config->keepICFStabs = args.hasArg(OPT_keep_icf_stabs);1663config->dedupStrings =1664args.hasFlag(OPT_deduplicate_strings, OPT_no_deduplicate_strings, true);1665config->deadStripDuplicates = args.hasArg(OPT_dead_strip_duplicates);1666config->warnDylibInstallName = args.hasFlag(1667OPT_warn_dylib_install_name, OPT_no_warn_dylib_install_name, false);1668config->ignoreOptimizationHints = args.hasArg(OPT_ignore_optimization_hints);1669config->callGraphProfileSort = args.hasFlag(1670OPT_call_graph_profile_sort, OPT_no_call_graph_profile_sort, true);1671config->printSymbolOrder = args.getLastArgValue(OPT_print_symbol_order_eq);1672config->forceExactCpuSubtypeMatch =1673getenv("LD_DYLIB_CPU_SUBTYPES_MUST_MATCH");1674config->objcStubsMode = getObjCStubsMode(args);1675config->ignoreAutoLink = args.hasArg(OPT_ignore_auto_link);1676for (const Arg *arg : args.filtered(OPT_ignore_auto_link_option))1677config->ignoreAutoLinkOptions.insert(arg->getValue());1678config->strictAutoLink = args.hasArg(OPT_strict_auto_link);1679config->ltoDebugPassManager = args.hasArg(OPT_lto_debug_pass_manager);1680config->csProfileGenerate = args.hasArg(OPT_cs_profile_generate);1681config->csProfilePath = args.getLastArgValue(OPT_cs_profile_path);1682config->pgoWarnMismatch =1683args.hasFlag(OPT_pgo_warn_mismatch, OPT_no_pgo_warn_mismatch, true);1684config->generateUuid = !args.hasArg(OPT_no_uuid);1685
1686for (const Arg *arg : args.filtered(OPT_alias)) {1687config->aliasedSymbols.push_back(1688std::make_pair(arg->getValue(0), arg->getValue(1)));1689}1690
1691if (const char *zero = getenv("ZERO_AR_DATE"))1692config->zeroModTime = strcmp(zero, "0") != 0;1693if (args.getLastArg(OPT_reproducible))1694config->zeroModTime = true;1695
1696std::array<PlatformType, 4> encryptablePlatforms{1697PLATFORM_IOS, PLATFORM_WATCHOS, PLATFORM_TVOS, PLATFORM_XROS};1698config->emitEncryptionInfo =1699args.hasFlag(OPT_encryptable, OPT_no_encryption,1700is_contained(encryptablePlatforms, config->platform()));1701
1702if (const Arg *arg = args.getLastArg(OPT_install_name)) {1703if (config->warnDylibInstallName && config->outputType != MH_DYLIB)1704warn(1705arg->getAsString(args) +1706": ignored, only has effect with -dylib [--warn-dylib-install-name]");1707else1708config->installName = arg->getValue();1709} else if (config->outputType == MH_DYLIB) {1710config->installName = config->finalOutput;1711}1712
1713if (args.hasArg(OPT_mark_dead_strippable_dylib)) {1714if (config->outputType != MH_DYLIB)1715warn("-mark_dead_strippable_dylib: ignored, only has effect with -dylib");1716else1717config->markDeadStrippableDylib = true;1718}1719
1720if (const Arg *arg = args.getLastArg(OPT_static, OPT_dynamic))1721config->staticLink = (arg->getOption().getID() == OPT_static);1722
1723if (const Arg *arg =1724args.getLastArg(OPT_flat_namespace, OPT_twolevel_namespace))1725config->namespaceKind = arg->getOption().getID() == OPT_twolevel_namespace1726? NamespaceKind::twolevel1727: NamespaceKind::flat;1728
1729config->undefinedSymbolTreatment = getUndefinedSymbolTreatment(args);1730
1731if (config->outputType == MH_EXECUTE)1732config->entry = symtab->addUndefined(args.getLastArgValue(OPT_e, "_main"),1733/*file=*/nullptr,1734/*isWeakRef=*/false);1735
1736config->librarySearchPaths =1737getLibrarySearchPaths(args, config->systemLibraryRoots);1738config->frameworkSearchPaths =1739getFrameworkSearchPaths(args, config->systemLibraryRoots);1740if (const Arg *arg =1741args.getLastArg(OPT_search_paths_first, OPT_search_dylibs_first))1742config->searchDylibsFirst =1743arg->getOption().getID() == OPT_search_dylibs_first;1744
1745config->dylibCompatibilityVersion =1746parseDylibVersion(args, OPT_compatibility_version);1747config->dylibCurrentVersion = parseDylibVersion(args, OPT_current_version);1748
1749config->dataConst =1750args.hasFlag(OPT_data_const, OPT_no_data_const, dataConstDefault(args));1751// Populate config->sectionRenameMap with builtin default renames.1752// Options -rename_section and -rename_segment are able to override.1753initializeSectionRenameMap();1754// Reject every special character except '.' and '$'1755// TODO(gkm): verify that this is the proper set of invalid chars1756StringRef invalidNameChars("!\"#%&'()*+,-/:;<=>?@[\\]^`{|}~");1757auto validName = [invalidNameChars](StringRef s) {1758if (s.find_first_of(invalidNameChars) != StringRef::npos)1759error("invalid name for segment or section: " + s);1760return s;1761};1762for (const Arg *arg : args.filtered(OPT_rename_section)) {1763config->sectionRenameMap[{validName(arg->getValue(0)),1764validName(arg->getValue(1))}] = {1765validName(arg->getValue(2)), validName(arg->getValue(3))};1766}1767for (const Arg *arg : args.filtered(OPT_rename_segment)) {1768config->segmentRenameMap[validName(arg->getValue(0))] =1769validName(arg->getValue(1));1770}1771
1772config->sectionAlignments = parseSectAlign(args);1773
1774for (const Arg *arg : args.filtered(OPT_segprot)) {1775StringRef segName = arg->getValue(0);1776uint32_t maxProt = parseProtection(arg->getValue(1));1777uint32_t initProt = parseProtection(arg->getValue(2));1778if (maxProt != initProt && config->arch() != AK_i386)1779error("invalid argument '" + arg->getAsString(args) +1780"': max and init must be the same for non-i386 archs");1781if (segName == segment_names::linkEdit)1782error("-segprot cannot be used to change __LINKEDIT's protections");1783config->segmentProtections.push_back({segName, maxProt, initProt});1784}1785
1786config->hasExplicitExports =1787args.hasArg(OPT_no_exported_symbols) ||1788args.hasArgNoClaim(OPT_exported_symbol, OPT_exported_symbols_list);1789handleSymbolPatterns(args, config->exportedSymbols, OPT_exported_symbol,1790OPT_exported_symbols_list);1791handleSymbolPatterns(args, config->unexportedSymbols, OPT_unexported_symbol,1792OPT_unexported_symbols_list);1793if (config->hasExplicitExports && !config->unexportedSymbols.empty())1794error("cannot use both -exported_symbol* and -unexported_symbol* options");1795
1796if (args.hasArg(OPT_no_exported_symbols) && !config->exportedSymbols.empty())1797error("cannot use both -exported_symbol* and -no_exported_symbols options");1798
1799// Imitating LD64's:1800// -non_global_symbols_no_strip_list and -non_global_symbols_strip_list can't1801// both be present.1802// But -x can be used with either of these two, in which case, the last arg1803// takes effect.1804// (TODO: This is kind of confusing - considering disallowing using them1805// together for a more straightforward behaviour)1806{1807bool includeLocal = false;1808bool excludeLocal = false;1809for (const Arg *arg :1810args.filtered(OPT_x, OPT_non_global_symbols_no_strip_list,1811OPT_non_global_symbols_strip_list)) {1812switch (arg->getOption().getID()) {1813case OPT_x:1814config->localSymbolsPresence = SymtabPresence::None;1815break;1816case OPT_non_global_symbols_no_strip_list:1817if (excludeLocal) {1818error("cannot use both -non_global_symbols_no_strip_list and "1819"-non_global_symbols_strip_list");1820} else {1821includeLocal = true;1822config->localSymbolsPresence = SymtabPresence::SelectivelyIncluded;1823parseSymbolPatternsFile(arg, config->localSymbolPatterns);1824}1825break;1826case OPT_non_global_symbols_strip_list:1827if (includeLocal) {1828error("cannot use both -non_global_symbols_no_strip_list and "1829"-non_global_symbols_strip_list");1830} else {1831excludeLocal = true;1832config->localSymbolsPresence = SymtabPresence::SelectivelyExcluded;1833parseSymbolPatternsFile(arg, config->localSymbolPatterns);1834}1835break;1836default:1837llvm_unreachable("unexpected option");1838}1839}1840}1841// Explicitly-exported literal symbols must be defined, but might1842// languish in an archive if unreferenced elsewhere or if they are in the1843// non-global strip list. Light a fire under those lazy symbols!1844for (const CachedHashStringRef &cachedName : config->exportedSymbols.literals)1845symtab->addUndefined(cachedName.val(), /*file=*/nullptr,1846/*isWeakRef=*/false);1847
1848for (const Arg *arg : args.filtered(OPT_why_live))1849config->whyLive.insert(arg->getValue());1850if (!config->whyLive.empty() && !config->deadStrip)1851warn("-why_live has no effect without -dead_strip, ignoring");1852
1853config->saveTemps = args.hasArg(OPT_save_temps);1854
1855config->adhocCodesign = args.hasFlag(1856OPT_adhoc_codesign, OPT_no_adhoc_codesign,1857shouldAdhocSignByDefault(config->arch(), config->platform()));1858
1859if (args.hasArg(OPT_v)) {1860message(getLLDVersion(), lld::errs());1861message(StringRef("Library search paths:") +1862(config->librarySearchPaths.empty()1863? ""1864: "\n\t" + join(config->librarySearchPaths, "\n\t")),1865lld::errs());1866message(StringRef("Framework search paths:") +1867(config->frameworkSearchPaths.empty()1868? ""1869: "\n\t" + join(config->frameworkSearchPaths, "\n\t")),1870lld::errs());1871}1872
1873config->progName = argsArr[0];1874
1875config->timeTraceEnabled = args.hasArg(OPT_time_trace_eq);1876config->timeTraceGranularity =1877args::getInteger(args, OPT_time_trace_granularity_eq, 500);1878
1879// Initialize time trace profiler.1880if (config->timeTraceEnabled)1881timeTraceProfilerInitialize(config->timeTraceGranularity, config->progName);1882
1883{1884TimeTraceScope timeScope("ExecuteLinker");1885
1886initLLVM(); // must be run before any call to addFile()1887createFiles(args);1888
1889// Now that all dylibs have been loaded, search for those that should be1890// re-exported.1891{1892auto reexportHandler = [](const Arg *arg,1893const std::vector<StringRef> &extensions) {1894config->hasReexports = true;1895StringRef searchName = arg->getValue();1896if (!markReexport(searchName, extensions))1897error(arg->getSpelling() + " " + searchName +1898" does not match a supplied dylib");1899};1900std::vector<StringRef> extensions = {".tbd"};1901for (const Arg *arg : args.filtered(OPT_sub_umbrella))1902reexportHandler(arg, extensions);1903
1904extensions.push_back(".dylib");1905for (const Arg *arg : args.filtered(OPT_sub_library))1906reexportHandler(arg, extensions);1907}1908
1909cl::ResetAllOptionOccurrences();1910
1911// Parse LTO options.1912if (const Arg *arg = args.getLastArg(OPT_mcpu))1913parseClangOption(saver().save("-mcpu=" + StringRef(arg->getValue())),1914arg->getSpelling());1915
1916for (const Arg *arg : args.filtered(OPT_mllvm)) {1917parseClangOption(arg->getValue(), arg->getSpelling());1918config->mllvmOpts.emplace_back(arg->getValue());1919}1920
1921createSyntheticSections();1922createSyntheticSymbols();1923addSynthenticMethnames();1924
1925createAliases();1926// If we are in "explicit exports" mode, hide everything that isn't1927// explicitly exported. Do this before running LTO so that LTO can better1928// optimize.1929handleExplicitExports();1930
1931bool didCompileBitcodeFiles = compileBitcodeFiles();1932
1933resolveLCLinkerOptions();1934
1935// If --thinlto-index-only is given, we should create only "index1936// files" and not object files. Index file creation is already done1937// in compileBitcodeFiles, so we are done if that's the case.1938if (config->thinLTOIndexOnly)1939return errorCount() == 0;1940
1941// LTO may emit a non-hidden (extern) object file symbol even if the1942// corresponding bitcode symbol is hidden. In particular, this happens for1943// cross-module references to hidden symbols under ThinLTO. Thus, if we1944// compiled any bitcode files, we must redo the symbol hiding.1945if (didCompileBitcodeFiles)1946handleExplicitExports();1947replaceCommonSymbols();1948
1949StringRef orderFile = args.getLastArgValue(OPT_order_file);1950if (!orderFile.empty())1951priorityBuilder.parseOrderFile(orderFile);1952
1953referenceStubBinder();1954
1955// FIXME: should terminate the link early based on errors encountered so1956// far?1957
1958for (const Arg *arg : args.filtered(OPT_sectcreate)) {1959StringRef segName = arg->getValue(0);1960StringRef sectName = arg->getValue(1);1961StringRef fileName = arg->getValue(2);1962std::optional<MemoryBufferRef> buffer = readFile(fileName);1963if (buffer)1964inputFiles.insert(make<OpaqueFile>(*buffer, segName, sectName));1965}1966
1967for (const Arg *arg : args.filtered(OPT_add_empty_section)) {1968StringRef segName = arg->getValue(0);1969StringRef sectName = arg->getValue(1);1970inputFiles.insert(make<OpaqueFile>(MemoryBufferRef(), segName, sectName));1971}1972
1973gatherInputSections();1974if (config->callGraphProfileSort)1975priorityBuilder.extractCallGraphProfile();1976
1977if (config->deadStrip)1978markLive();1979
1980// Ensure that no symbols point inside __mod_init_func sections if they are1981// removed due to -init_offsets. This must run after dead stripping.1982if (config->emitInitOffsets)1983eraseInitializerSymbols();1984
1985// Categories are not subject to dead-strip. The __objc_catlist section is1986// marked as NO_DEAD_STRIP and that propagates into all category data.1987if (args.hasArg(OPT_check_category_conflicts))1988objc::checkCategories();1989
1990// Category merging uses "->live = false" to erase old category data, so1991// it has to run after dead-stripping (markLive).1992if (args.hasArg(OPT_objc_category_merging, OPT_no_objc_category_merging))1993objc::mergeCategories();1994
1995// ICF assumes that all literals have been folded already, so we must run1996// foldIdenticalLiterals before foldIdenticalSections.1997foldIdenticalLiterals();1998if (config->icfLevel != ICFLevel::none) {1999if (config->icfLevel == ICFLevel::safe)2000markAddrSigSymbols();2001foldIdenticalSections(/*onlyCfStrings=*/false);2002} else if (config->dedupStrings) {2003foldIdenticalSections(/*onlyCfStrings=*/true);2004}2005
2006// Write to an output file.2007if (target->wordSize == 8)2008writeResult<LP64>();2009else2010writeResult<ILP32>();2011
2012depTracker->write(getLLDVersion(), inputFiles, config->outputFile);2013}2014
2015if (config->timeTraceEnabled) {2016checkError(timeTraceProfilerWrite(2017args.getLastArgValue(OPT_time_trace_eq).str(), config->outputFile));2018
2019timeTraceProfilerCleanup();2020}2021
2022if (errorCount() != 0 || config->strictAutoLink)2023for (const auto &warning : missingAutolinkWarnings)2024warn(warning);2025
2026return errorCount() == 0;2027}
2028} // namespace macho2029} // namespace lld2030