1 //===- lib/Driver/DarwinLdDriver.cpp --------------------------------------===//
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
12 /// Concrete instance of the Driver for darwin's ld.
14 //===----------------------------------------------------------------------===//
16 #include "lld/Core/File.h"
17 #include "lld/Core/ArchiveLibraryFile.h"
18 #include "lld/Core/SharedLibraryFile.h"
19 #include "lld/Driver/Driver.h"
20 #include "lld/ReaderWriter/MachOLinkingContext.h"
21 #include "llvm/ADT/ArrayRef.h"
22 #include "llvm/ADT/STLExtras.h"
23 #include "llvm/ADT/Triple.h"
24 #include "llvm/Option/Arg.h"
25 #include "llvm/Option/Option.h"
26 #include "llvm/Support/CommandLine.h"
27 #include "llvm/Support/Debug.h"
28 #include "llvm/Support/FileSystem.h"
29 #include "llvm/Support/Format.h"
30 #include "llvm/Support/Host.h"
31 #include "llvm/Support/MachO.h"
32 #include "llvm/Support/ManagedStatic.h"
33 #include "llvm/Support/Path.h"
34 #include "llvm/Support/PrettyStackTrace.h"
35 #include "llvm/Support/Signals.h"
36 #include "llvm/Support/raw_ostream.h"
43 // Create enum with OPT_xxx values for each option in DarwinLdOptions.td
46 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
49 #include "DarwinLdOptions.inc"
53 // Create prefix string literals used in DarwinLdOptions.td
54 #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
55 #include "DarwinLdOptions.inc"
58 // Create table mapping all options defined in DarwinLdOptions.td
59 static const llvm::opt::OptTable::Info infoTable[] = {
60 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
62 { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \
63 PARAM, FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS },
64 #include "DarwinLdOptions.inc"
68 // Create OptTable class for parsing actual command line arguments
69 class DarwinLdOptTable : public llvm::opt::OptTable {
71 DarwinLdOptTable() : OptTable(infoTable, llvm::array_lengthof(infoTable)){}
74 std::vector<std::unique_ptr<File>>
75 loadFile(MachOLinkingContext &ctx, StringRef path,
76 raw_ostream &diag, bool wholeArchive, bool upwardDylib) {
77 if (ctx.logInputFiles())
80 ErrorOr<std::unique_ptr<MemoryBuffer>> mbOrErr = ctx.getMemoryBuffer(path);
81 if (std::error_code ec = mbOrErr.getError())
82 return makeErrorFile(path, ec);
83 std::vector<std::unique_ptr<File>> files;
84 if (std::error_code ec = ctx.registry().loadFile(std::move(mbOrErr.get()), files))
85 return makeErrorFile(path, ec);
86 for (std::unique_ptr<File> &pf : files) {
87 // If file is a dylib, inform LinkingContext about it.
88 if (SharedLibraryFile *shl = dyn_cast<SharedLibraryFile>(pf.get())) {
89 if (std::error_code ec = shl->parse())
90 return makeErrorFile(path, ec);
91 ctx.registerDylib(reinterpret_cast<mach_o::MachODylibFile*>(shl),
96 return parseMemberFiles(files);
100 } // anonymous namespace
102 // Test may be running on Windows. Canonicalize the path
103 // separator to '/' to get consistent outputs for tests.
104 static std::string canonicalizePath(StringRef path) {
105 char sep = llvm::sys::path::get_separator().front();
107 std::string fixedPath = path;
108 std::replace(fixedPath.begin(), fixedPath.end(), sep, '/');
115 static void addFile(StringRef path, MachOLinkingContext &ctx,
116 bool loadWholeArchive,
117 bool upwardDylib, raw_ostream &diag) {
118 std::vector<std::unique_ptr<File>> files =
119 loadFile(ctx, path, diag, loadWholeArchive, upwardDylib);
120 for (std::unique_ptr<File> &file : files)
121 ctx.getNodes().push_back(llvm::make_unique<FileNode>(std::move(file)));
124 // Export lists are one symbol per line. Blank lines are ignored.
125 // Trailing comments start with #.
126 static std::error_code parseExportsList(StringRef exportFilePath,
127 MachOLinkingContext &ctx,
128 raw_ostream &diagnostics) {
129 // Map in export list file.
130 ErrorOr<std::unique_ptr<MemoryBuffer>> mb =
131 MemoryBuffer::getFileOrSTDIN(exportFilePath);
132 if (std::error_code ec = mb.getError())
134 ctx.addInputFileDependency(exportFilePath);
135 StringRef buffer = mb->get()->getBuffer();
136 while (!buffer.empty()) {
137 // Split off each line in the file.
138 std::pair<StringRef, StringRef> lineAndRest = buffer.split('\n');
139 StringRef line = lineAndRest.first;
140 // Ignore trailing # comments.
141 std::pair<StringRef, StringRef> symAndComment = line.split('#');
142 StringRef sym = symAndComment.first.trim();
144 ctx.addExportSymbol(sym);
145 buffer = lineAndRest.second;
147 return std::error_code();
152 /// Order files are one symbol per line. Blank lines are ignored.
153 /// Trailing comments start with #. Symbol names can be prefixed with an
154 /// architecture name and/or .o leaf name. Examples:
157 /// libfrob.a(bar.o):_bar
159 static std::error_code parseOrderFile(StringRef orderFilePath,
160 MachOLinkingContext &ctx,
161 raw_ostream &diagnostics) {
162 // Map in order file.
163 ErrorOr<std::unique_ptr<MemoryBuffer>> mb =
164 MemoryBuffer::getFileOrSTDIN(orderFilePath);
165 if (std::error_code ec = mb.getError())
167 ctx.addInputFileDependency(orderFilePath);
168 StringRef buffer = mb->get()->getBuffer();
169 while (!buffer.empty()) {
170 // Split off each line in the file.
171 std::pair<StringRef, StringRef> lineAndRest = buffer.split('\n');
172 StringRef line = lineAndRest.first;
173 buffer = lineAndRest.second;
174 // Ignore trailing # comments.
175 std::pair<StringRef, StringRef> symAndComment = line.split('#');
176 if (symAndComment.first.empty())
178 StringRef sym = symAndComment.first.trim();
183 std::pair<StringRef, StringRef> prefixAndSym = sym.split(':');
184 if (!prefixAndSym.second.empty()) {
185 sym = prefixAndSym.second;
186 prefix = prefixAndSym.first;
187 if (!prefix.endswith(".o") && !prefix.endswith(".o)")) {
188 // If arch name prefix does not match arch being linked, ignore symbol.
189 if (!ctx.archName().equals(prefix))
194 sym = prefixAndSym.first;
196 ctx.appendOrderedSymbol(sym, prefix);
197 //llvm::errs() << sym << ", prefix=" << prefix << "\n";
200 return std::error_code();
204 // There are two variants of the -filelist option:
207 // In this variant, the path is to a text file which contains one file path
208 // per line. There are no comments or trimming of whitespace.
210 // -fileList <path>,<dir>
211 // In this variant, the path is to a text file which contains a partial path
212 // per line. The <dir> prefix is prepended to each partial path.
214 static std::error_code loadFileList(StringRef fileListPath,
215 MachOLinkingContext &ctx, bool forceLoad,
216 raw_ostream &diagnostics) {
217 // If there is a comma, split off <dir>.
218 std::pair<StringRef, StringRef> opt = fileListPath.split(',');
219 StringRef filePath = opt.first;
220 StringRef dirName = opt.second;
221 ctx.addInputFileDependency(filePath);
222 // Map in file list file.
223 ErrorOr<std::unique_ptr<MemoryBuffer>> mb =
224 MemoryBuffer::getFileOrSTDIN(filePath);
225 if (std::error_code ec = mb.getError())
227 StringRef buffer = mb->get()->getBuffer();
228 while (!buffer.empty()) {
229 // Split off each line in the file.
230 std::pair<StringRef, StringRef> lineAndRest = buffer.split('\n');
231 StringRef line = lineAndRest.first;
233 if (!dirName.empty()) {
234 // If there is a <dir> then prepend dir to each line.
235 SmallString<256> fullPath;
236 fullPath.assign(dirName);
237 llvm::sys::path::append(fullPath, Twine(line));
238 path = ctx.copy(fullPath.str());
240 // No <dir> use whole line as input file path.
241 path = ctx.copy(line);
243 if (!ctx.pathExists(path)) {
244 return make_dynamic_error_code(Twine("File not found '")
248 if (ctx.testingFileUsage()) {
249 diagnostics << "Found filelist entry " << canonicalizePath(path) << '\n';
251 addFile(path, ctx, forceLoad, false, diagnostics);
252 buffer = lineAndRest.second;
254 return std::error_code();
257 /// Parse number assuming it is base 16, but allow 0x prefix.
258 static bool parseNumberBase16(StringRef numStr, uint64_t &baseAddress) {
259 if (numStr.startswith_lower("0x"))
260 numStr = numStr.drop_front(2);
261 return numStr.getAsInteger(16, baseAddress);
266 bool DarwinLdDriver::linkMachO(int argc, const char *argv[],
267 raw_ostream &diagnostics) {
268 MachOLinkingContext ctx;
269 if (!parse(argc, argv, ctx, diagnostics))
273 return link(ctx, diagnostics);
276 bool DarwinLdDriver::parse(int argc, const char *argv[],
277 MachOLinkingContext &ctx, raw_ostream &diagnostics) {
278 // Parse command line options using DarwinLdOptions.td
279 std::unique_ptr<llvm::opt::InputArgList> parsedArgs;
280 DarwinLdOptTable table;
281 unsigned missingIndex;
282 unsigned missingCount;
283 bool globalWholeArchive = false;
285 table.ParseArgs(&argv[1], &argv[argc], missingIndex, missingCount));
287 diagnostics << "error: missing arg value for '"
288 << parsedArgs->getArgString(missingIndex) << "' expected "
289 << missingCount << " argument(s).\n";
293 for (auto unknownArg : parsedArgs->filtered(OPT_UNKNOWN)) {
294 diagnostics << "warning: ignoring unknown argument: "
295 << unknownArg->getAsString(*parsedArgs) << "\n";
298 // Figure out output kind ( -dylib, -r, -bundle, -preload, or -static )
299 llvm::MachO::HeaderFileType fileType = llvm::MachO::MH_EXECUTE;
300 if ( llvm::opt::Arg *kind = parsedArgs->getLastArg(OPT_dylib, OPT_relocatable,
301 OPT_bundle, OPT_static, OPT_preload)) {
302 switch (kind->getOption().getID()) {
304 fileType = llvm::MachO::MH_DYLIB;
306 case OPT_relocatable:
307 fileType = llvm::MachO::MH_OBJECT;
310 fileType = llvm::MachO::MH_BUNDLE;
313 fileType = llvm::MachO::MH_EXECUTE;
316 fileType = llvm::MachO::MH_PRELOAD;
322 MachOLinkingContext::Arch arch = MachOLinkingContext::arch_unknown;
323 if (llvm::opt::Arg *archStr = parsedArgs->getLastArg(OPT_arch)) {
324 arch = MachOLinkingContext::archFromName(archStr->getValue());
325 if (arch == MachOLinkingContext::arch_unknown) {
326 diagnostics << "error: unknown arch named '" << archStr->getValue()
331 // If no -arch specified, scan input files to find first non-fat .o file.
332 if (arch == MachOLinkingContext::arch_unknown) {
333 for (auto &inFile: parsedArgs->filtered(OPT_INPUT)) {
334 // This is expensive because it opens and maps the file. But that is
335 // ok because no -arch is rare.
336 if (MachOLinkingContext::isThinObjectFile(inFile->getValue(), arch))
339 if (arch == MachOLinkingContext::arch_unknown
340 && !parsedArgs->getLastArg(OPT_test_file_usage)) {
341 // If no -arch and no options at all, print usage message.
342 if (parsedArgs->size() == 0)
343 table.PrintHelp(llvm::outs(), argv[0], "LLVM Linker", false);
345 diagnostics << "error: -arch not specified and could not be inferred\n";
350 // Handle -macosx_version_min or -ios_version_min
351 MachOLinkingContext::OS os = MachOLinkingContext::OS::macOSX;
352 uint32_t minOSVersion = 0;
353 if (llvm::opt::Arg *minOS =
354 parsedArgs->getLastArg(OPT_macosx_version_min, OPT_ios_version_min,
355 OPT_ios_simulator_version_min)) {
356 switch (minOS->getOption().getID()) {
357 case OPT_macosx_version_min:
358 os = MachOLinkingContext::OS::macOSX;
359 if (MachOLinkingContext::parsePackedVersion(minOS->getValue(),
361 diagnostics << "error: malformed macosx_version_min value\n";
365 case OPT_ios_version_min:
366 os = MachOLinkingContext::OS::iOS;
367 if (MachOLinkingContext::parsePackedVersion(minOS->getValue(),
369 diagnostics << "error: malformed ios_version_min value\n";
373 case OPT_ios_simulator_version_min:
374 os = MachOLinkingContext::OS::iOS_simulator;
375 if (MachOLinkingContext::parsePackedVersion(minOS->getValue(),
377 diagnostics << "error: malformed ios_simulator_version_min value\n";
383 // No min-os version on command line, check environment variables
386 // Now that there's enough information parsed in, let the linking context
387 // set up default values.
388 ctx.configure(fileType, arch, os, minOSVersion);
391 if (llvm::opt::Arg *entry = parsedArgs->getLastArg(OPT_entry))
392 ctx.setEntrySymbolName(entry->getValue());
395 if (llvm::opt::Arg *outpath = parsedArgs->getLastArg(OPT_output))
396 ctx.setOutputPath(outpath->getValue());
398 ctx.setOutputPath("a.out");
400 // Handle -image_base XXX and -seg1addr XXXX
401 if (llvm::opt::Arg *imageBase = parsedArgs->getLastArg(OPT_image_base)) {
402 uint64_t baseAddress;
403 if (parseNumberBase16(imageBase->getValue(), baseAddress)) {
404 diagnostics << "error: image_base expects a hex number\n";
406 } else if (baseAddress < ctx.pageZeroSize()) {
407 diagnostics << "error: image_base overlaps with __PAGEZERO\n";
409 } else if (baseAddress % ctx.pageSize()) {
410 diagnostics << "error: image_base must be a multiple of page size ("
411 << llvm::format("0x%" PRIx64, ctx.pageSize()) << ")\n";
415 ctx.setBaseAddress(baseAddress);
418 // Handle -dead_strip
419 if (parsedArgs->getLastArg(OPT_dead_strip))
420 ctx.setDeadStripping(true);
423 if (parsedArgs->getLastArg(OPT_all_load))
424 globalWholeArchive = true;
426 // Handle -install_name
427 if (llvm::opt::Arg *installName = parsedArgs->getLastArg(OPT_install_name))
428 ctx.setInstallName(installName->getValue());
430 ctx.setInstallName(ctx.outputPath());
432 // Handle -mark_dead_strippable_dylib
433 if (parsedArgs->getLastArg(OPT_mark_dead_strippable_dylib))
434 ctx.setDeadStrippableDylib(true);
436 // Handle -compatibility_version and -current_version
437 if (llvm::opt::Arg *vers =
438 parsedArgs->getLastArg(OPT_compatibility_version)) {
439 if (ctx.outputMachOType() != llvm::MachO::MH_DYLIB) {
441 << "error: -compatibility_version can only be used with -dylib\n";
445 if (MachOLinkingContext::parsePackedVersion(vers->getValue(), parsedVers)) {
446 diagnostics << "error: -compatibility_version value is malformed\n";
449 ctx.setCompatibilityVersion(parsedVers);
452 if (llvm::opt::Arg *vers = parsedArgs->getLastArg(OPT_current_version)) {
453 if (ctx.outputMachOType() != llvm::MachO::MH_DYLIB) {
454 diagnostics << "-current_version can only be used with -dylib\n";
458 if (MachOLinkingContext::parsePackedVersion(vers->getValue(), parsedVers)) {
459 diagnostics << "error: -current_version value is malformed\n";
462 ctx.setCurrentVersion(parsedVers);
465 // Handle -bundle_loader
466 if (llvm::opt::Arg *loader = parsedArgs->getLastArg(OPT_bundle_loader))
467 ctx.setBundleLoader(loader->getValue());
469 // Handle -sectalign segname sectname align
470 for (auto &alignArg : parsedArgs->filtered(OPT_sectalign)) {
471 const char* segName = alignArg->getValue(0);
472 const char* sectName = alignArg->getValue(1);
473 const char* alignStr = alignArg->getValue(2);
474 if ((alignStr[0] == '0') && (alignStr[1] == 'x'))
476 unsigned long long alignValue;
477 if (llvm::getAsUnsignedInteger(alignStr, 16, alignValue)) {
478 diagnostics << "error: -sectalign alignment value '"
479 << alignStr << "' not a valid number\n";
482 uint8_t align2 = llvm::countTrailingZeros(alignValue);
483 if ( (unsigned long)(1 << align2) != alignValue ) {
484 diagnostics << "warning: alignment for '-sectalign "
485 << segName << " " << sectName
486 << llvm::format(" 0x%llX", alignValue)
487 << "' is not a power of two, using "
488 << llvm::format("0x%08X", (1 << align2)) << "\n";
490 ctx.addSectionAlignment(segName, sectName, align2);
494 for (auto &llvmArg : parsedArgs->filtered(OPT_mllvm)) {
495 ctx.appendLLVMOption(llvmArg->getValue());
498 // Handle -print_atoms
499 if (parsedArgs->getLastArg(OPT_print_atoms))
502 // Handle -t (trace) option.
503 if (parsedArgs->getLastArg(OPT_t))
504 ctx.setLogInputFiles(true);
506 // Handle -demangle option.
507 if (parsedArgs->getLastArg(OPT_demangle))
508 ctx.setDemangleSymbols(true);
510 // Handle -keep_private_externs
511 if (parsedArgs->getLastArg(OPT_keep_private_externs)) {
512 ctx.setKeepPrivateExterns(true);
513 if (ctx.outputMachOType() != llvm::MachO::MH_OBJECT)
514 diagnostics << "warning: -keep_private_externs only used in -r mode\n";
517 // Handle -dependency_info <path> used by Xcode.
518 if (llvm::opt::Arg *depInfo = parsedArgs->getLastArg(OPT_dependency_info)) {
519 if (std::error_code ec = ctx.createDependencyFile(depInfo->getValue())) {
520 diagnostics << "warning: " << ec.message()
521 << ", processing '-dependency_info "
522 << depInfo->getValue()
527 // In -test_file_usage mode, we'll be given an explicit list of paths that
528 // exist. We'll also be expected to print out information about how we located
529 // libraries and so on that the user specified, but not to actually do any
531 if (parsedArgs->getLastArg(OPT_test_file_usage)) {
532 ctx.setTestingFileUsage();
534 // With paths existing by fiat, linking is not going to end well.
535 ctx.setDoNothing(true);
537 // Only bother looking for an existence override if we're going to use it.
538 for (auto existingPath : parsedArgs->filtered(OPT_path_exists)) {
539 ctx.addExistingPathForDebug(existingPath->getValue());
543 // Register possible input file parsers.
544 if (!ctx.doNothing()) {
545 ctx.registry().addSupportMachOObjects(ctx);
546 ctx.registry().addSupportArchives(ctx.logInputFiles());
547 ctx.registry().addSupportNativeObjects();
548 ctx.registry().addSupportYamlFiles();
551 // Now construct the set of library search directories, following ld64's
552 // baroque set of accumulated hacks. Mostly, the algorithm constructs
553 // { syslibroots } x { libpaths }
555 // Unfortunately, there are numerous exceptions:
556 // 1. Only absolute paths get modified by syslibroot options.
557 // 2. If there is just 1 -syslibroot, system paths not found in it are
559 // 3. If the last -syslibroot is "/", all of them are ignored entirely.
560 // 4. If { syslibroots } x path == {}, the original path is kept.
561 std::vector<StringRef> sysLibRoots;
562 for (auto syslibRoot : parsedArgs->filtered(OPT_syslibroot)) {
563 sysLibRoots.push_back(syslibRoot->getValue());
565 if (!sysLibRoots.empty()) {
566 // Ignore all if last -syslibroot is "/".
567 if (sysLibRoots.back() != "/")
568 ctx.setSysLibRoots(sysLibRoots);
571 // Paths specified with -L come first, and are not considered system paths for
572 // the case where there is precisely 1 -syslibroot.
573 for (auto libPath : parsedArgs->filtered(OPT_L)) {
574 ctx.addModifiedSearchDir(libPath->getValue());
577 // Process -F directories (where to look for frameworks).
578 for (auto fwPath : parsedArgs->filtered(OPT_F)) {
579 ctx.addFrameworkSearchDir(fwPath->getValue());
582 // -Z suppresses the standard search paths.
583 if (!parsedArgs->hasArg(OPT_Z)) {
584 ctx.addModifiedSearchDir("/usr/lib", true);
585 ctx.addModifiedSearchDir("/usr/local/lib", true);
586 ctx.addFrameworkSearchDir("/Library/Frameworks", true);
587 ctx.addFrameworkSearchDir("/System/Library/Frameworks", true);
590 // Now that we've constructed the final set of search paths, print out those
591 // search paths in verbose mode.
592 if (parsedArgs->getLastArg(OPT_v)) {
593 diagnostics << "Library search paths:\n";
594 for (auto path : ctx.searchDirs()) {
595 diagnostics << " " << path << '\n';
597 diagnostics << "Framework search paths:\n";
598 for (auto path : ctx.frameworkDirs()) {
599 diagnostics << " " << path << '\n';
603 // Handle -exported_symbols_list <file>
604 for (auto expFile : parsedArgs->filtered(OPT_exported_symbols_list)) {
605 if (ctx.exportMode() == MachOLinkingContext::ExportMode::blackList) {
606 diagnostics << "error: -exported_symbols_list cannot be combined "
607 << "with -unexported_symbol[s_list]\n";
610 ctx.setExportMode(MachOLinkingContext::ExportMode::whiteList);
611 if (std::error_code ec = parseExportsList(expFile->getValue(), ctx,
613 diagnostics << "error: " << ec.message()
614 << ", processing '-exported_symbols_list "
615 << expFile->getValue()
621 // Handle -exported_symbol <symbol>
622 for (auto symbol : parsedArgs->filtered(OPT_exported_symbol)) {
623 if (ctx.exportMode() == MachOLinkingContext::ExportMode::blackList) {
624 diagnostics << "error: -exported_symbol cannot be combined "
625 << "with -unexported_symbol[s_list]\n";
628 ctx.setExportMode(MachOLinkingContext::ExportMode::whiteList);
629 ctx.addExportSymbol(symbol->getValue());
632 // Handle -unexported_symbols_list <file>
633 for (auto expFile : parsedArgs->filtered(OPT_unexported_symbols_list)) {
634 if (ctx.exportMode() == MachOLinkingContext::ExportMode::whiteList) {
635 diagnostics << "error: -unexported_symbols_list cannot be combined "
636 << "with -exported_symbol[s_list]\n";
639 ctx.setExportMode(MachOLinkingContext::ExportMode::blackList);
640 if (std::error_code ec = parseExportsList(expFile->getValue(), ctx,
642 diagnostics << "error: " << ec.message()
643 << ", processing '-unexported_symbols_list "
644 << expFile->getValue()
650 // Handle -unexported_symbol <symbol>
651 for (auto symbol : parsedArgs->filtered(OPT_unexported_symbol)) {
652 if (ctx.exportMode() == MachOLinkingContext::ExportMode::whiteList) {
653 diagnostics << "error: -unexported_symbol cannot be combined "
654 << "with -exported_symbol[s_list]\n";
657 ctx.setExportMode(MachOLinkingContext::ExportMode::blackList);
658 ctx.addExportSymbol(symbol->getValue());
661 // Handle obosolete -multi_module and -single_module
662 if (llvm::opt::Arg *mod = parsedArgs->getLastArg(OPT_multi_module,
663 OPT_single_module)) {
664 if (mod->getOption().getID() == OPT_multi_module) {
665 diagnostics << "warning: -multi_module is obsolete and being ignored\n";
668 if (ctx.outputMachOType() != llvm::MachO::MH_DYLIB) {
669 diagnostics << "warning: -single_module being ignored. "
670 "It is only for use when producing a dylib\n";
675 // Handle -pie or -no_pie
676 if (llvm::opt::Arg *pie = parsedArgs->getLastArg(OPT_pie, OPT_no_pie)) {
677 switch (ctx.outputMachOType()) {
678 case llvm::MachO::MH_EXECUTE:
680 case MachOLinkingContext::OS::macOSX:
681 if ((minOSVersion < 0x000A0500) &&
682 (pie->getOption().getID() == OPT_pie)) {
683 diagnostics << "-pie can only be used when targeting "
684 "Mac OS X 10.5 or later\n";
688 case MachOLinkingContext::OS::iOS:
689 if ((minOSVersion < 0x00040200) &&
690 (pie->getOption().getID() == OPT_pie)) {
691 diagnostics << "-pie can only be used when targeting "
692 "iOS 4.2 or later\n";
696 case MachOLinkingContext::OS::iOS_simulator:
697 if (pie->getOption().getID() == OPT_no_pie)
698 diagnostics << "iOS simulator programs must be built PIE\n";
701 case MachOLinkingContext::OS::unknown:
704 ctx.setPIE(pie->getOption().getID() == OPT_pie);
706 case llvm::MachO::MH_PRELOAD:
708 case llvm::MachO::MH_DYLIB:
709 case llvm::MachO::MH_BUNDLE:
710 diagnostics << "warning: " << pie->getSpelling() << " being ignored. "
711 << "It is only used when linking main executables\n";
714 diagnostics << pie->getSpelling()
715 << " can only used when linking main executables\n";
721 // Handle debug info handling options: -S
722 if (parsedArgs->hasArg(OPT_S))
723 ctx.setDebugInfoMode(MachOLinkingContext::DebugInfoMode::noDebugMap);
725 // Handle -order_file <file>
726 for (auto orderFile : parsedArgs->filtered(OPT_order_file)) {
727 if (std::error_code ec = parseOrderFile(orderFile->getValue(), ctx,
729 diagnostics << "error: " << ec.message()
730 << ", processing '-order_file "
731 << orderFile->getValue()
737 // Handle -rpath <path>
738 if (parsedArgs->hasArg(OPT_rpath)) {
739 switch (ctx.outputMachOType()) {
740 case llvm::MachO::MH_EXECUTE:
741 case llvm::MachO::MH_DYLIB:
742 case llvm::MachO::MH_BUNDLE:
743 if (!ctx.minOS("10.5", "2.0")) {
744 if (ctx.os() == MachOLinkingContext::OS::macOSX) {
745 diagnostics << "error: -rpath can only be used when targeting "
746 "OS X 10.5 or later\n";
748 diagnostics << "error: -rpath can only be used when targeting "
749 "iOS 2.0 or later\n";
755 diagnostics << "error: -rpath can only be used when creating "
756 "a dynamic final linked image\n";
760 for (auto rPath : parsedArgs->filtered(OPT_rpath)) {
761 ctx.addRpath(rPath->getValue());
765 // Handle input files
766 for (auto &arg : *parsedArgs) {
768 ErrorOr<StringRef> resolvedPath = StringRef();
769 switch (arg->getOption().getID()) {
773 addFile(arg->getValue(), ctx, globalWholeArchive, false, diagnostics);
775 case OPT_upward_library:
776 addFile(arg->getValue(), ctx, false, true, diagnostics);
779 addFile(arg->getValue(), ctx, true, false, diagnostics);
783 upward = (arg->getOption().getID() == OPT_upward_l);
784 resolvedPath = ctx.searchLibrary(arg->getValue());
786 diagnostics << "Unable to find library for " << arg->getSpelling()
787 << arg->getValue() << "\n";
789 } else if (ctx.testingFileUsage()) {
790 diagnostics << "Found " << (upward ? "upward " : " ") << "library "
791 << canonicalizePath(resolvedPath.get()) << '\n';
793 addFile(resolvedPath.get(), ctx, globalWholeArchive, upward, diagnostics);
796 case OPT_upward_framework:
797 upward = (arg->getOption().getID() == OPT_upward_framework);
798 resolvedPath = ctx.findPathForFramework(arg->getValue());
800 diagnostics << "Unable to find framework for "
801 << arg->getSpelling() << " " << arg->getValue() << "\n";
803 } else if (ctx.testingFileUsage()) {
804 diagnostics << "Found " << (upward ? "upward " : " ") << "framework "
805 << canonicalizePath(resolvedPath.get()) << '\n';
807 addFile(resolvedPath.get(), ctx, globalWholeArchive, upward, diagnostics);
810 if (std::error_code ec = loadFileList(arg->getValue(),
811 ctx, globalWholeArchive,
813 diagnostics << "error: " << ec.message()
814 << ", processing '-filelist " << arg->getValue()
822 if (ctx.getNodes().empty()) {
823 diagnostics << "No input files\n";
827 // Validate the combination of options used.
828 return ctx.validate(diagnostics);