xref: /llvm-project-15.0.7/lld/MachO/Driver.cpp (revision 7518006d)
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 "InputFiles.h"
12 #include "OutputSection.h"
13 #include "OutputSegment.h"
14 #include "SymbolTable.h"
15 #include "Symbols.h"
16 #include "SyntheticSections.h"
17 #include "Target.h"
18 #include "Writer.h"
19 
20 #include "lld/Common/Args.h"
21 #include "lld/Common/Driver.h"
22 #include "lld/Common/ErrorHandler.h"
23 #include "lld/Common/LLVM.h"
24 #include "lld/Common/Memory.h"
25 #include "lld/Common/Version.h"
26 #include "llvm/ADT/DenseSet.h"
27 #include "llvm/ADT/StringExtras.h"
28 #include "llvm/ADT/StringRef.h"
29 #include "llvm/BinaryFormat/MachO.h"
30 #include "llvm/BinaryFormat/Magic.h"
31 #include "llvm/Object/Archive.h"
32 #include "llvm/Option/ArgList.h"
33 #include "llvm/Option/Option.h"
34 #include "llvm/Support/FileSystem.h"
35 #include "llvm/Support/Host.h"
36 #include "llvm/Support/MemoryBuffer.h"
37 #include "llvm/Support/Path.h"
38 
39 #include <algorithm>
40 
41 using namespace llvm;
42 using namespace llvm::MachO;
43 using namespace llvm::object;
44 using namespace llvm::opt;
45 using namespace llvm::sys;
46 using namespace lld;
47 using namespace lld::macho;
48 
49 Configuration *lld::macho::config;
50 
51 // Create prefix string literals used in Options.td
52 #define PREFIX(NAME, VALUE) const char *NAME[] = VALUE;
53 #include "Options.inc"
54 #undef PREFIX
55 
56 // Create table mapping all options defined in Options.td
57 static const opt::OptTable::Info optInfo[] = {
58 #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12)      \
59   {X1, X2, X10,         X11,         OPT_##ID, opt::Option::KIND##Class,       \
60    X9, X8, OPT_##GROUP, OPT_##ALIAS, X7,       X12},
61 #include "Options.inc"
62 #undef OPTION
63 };
64 
65 MachOOptTable::MachOOptTable() : OptTable(optInfo) {}
66 
67 opt::InputArgList MachOOptTable::parse(ArrayRef<const char *> argv) {
68   // Make InputArgList from string vectors.
69   unsigned missingIndex;
70   unsigned missingCount;
71   SmallVector<const char *, 256> vec(argv.data(), argv.data() + argv.size());
72 
73   opt::InputArgList args = ParseArgs(vec, missingIndex, missingCount);
74 
75   if (missingCount)
76     error(Twine(args.getArgString(missingIndex)) + ": missing argument");
77 
78   for (opt::Arg *arg : args.filtered(OPT_UNKNOWN))
79     error("unknown argument: " + arg->getSpelling());
80   return args;
81 }
82 
83 void MachOOptTable::printHelp(const char *argv0, bool showHidden) const {
84   PrintHelp(lld::outs(), (std::string(argv0) + " [options] file...").c_str(),
85             "LLVM Linker", showHidden);
86   lld::outs() << "\n";
87 }
88 
89 static Optional<std::string> findWithExtension(StringRef base,
90                                                ArrayRef<StringRef> extensions) {
91   for (StringRef ext : extensions) {
92     Twine location = base + ext;
93     if (fs::exists(location))
94       return location.str();
95   }
96   return {};
97 }
98 
99 static Optional<std::string> findLibrary(StringRef name) {
100   llvm::SmallString<261> location;
101   for (StringRef dir : config->librarySearchPaths) {
102       location = dir;
103       path::append(location, Twine("lib") + name);
104       if (Optional<std::string> path =
105               findWithExtension(location, {".tbd", ".dylib", ".a"}))
106         return path;
107   }
108   return {};
109 }
110 
111 static Optional<std::string> findFramework(StringRef name) {
112   llvm::SmallString<260> symlink;
113   StringRef suffix;
114   std::tie(name, suffix) = name.split(",");
115   for (StringRef dir : config->frameworkSearchPaths) {
116     symlink = dir;
117     path::append(symlink, name + ".framework", name);
118 
119     if (!suffix.empty()) {
120       // NOTE: we must resolve the symlink before trying the suffixes, because
121       // there are no symlinks for the suffixed paths.
122       llvm::SmallString<260> location;
123       if (!fs::real_path(symlink, location)) {
124         // only append suffix if realpath() succeeds
125         Twine suffixed = location + suffix;
126         if (fs::exists(suffixed))
127           return suffixed.str();
128       }
129       // Suffix lookup failed, fall through to the no-suffix case.
130     }
131 
132     if (Optional<std::string> path = findWithExtension(symlink, {".tbd", ""}))
133       return path;
134   }
135   return {};
136 }
137 
138 static TargetInfo *createTargetInfo(opt::InputArgList &args) {
139   StringRef arch = args.getLastArgValue(OPT_arch, "x86_64");
140   config->arch = llvm::MachO::getArchitectureFromName(
141       args.getLastArgValue(OPT_arch, arch));
142   switch (config->arch) {
143   case llvm::MachO::AK_x86_64:
144   case llvm::MachO::AK_x86_64h:
145     return createX86_64TargetInfo();
146   default:
147     fatal("missing or unsupported -arch " + arch);
148   }
149 }
150 
151 static bool isDirectory(StringRef option, StringRef path) {
152   if (!fs::exists(path)) {
153     warn("directory not found for option -" + option + path);
154     return false;
155   } else if (!fs::is_directory(path)) {
156     warn("option -" + option + path + " references a non-directory path");
157     return false;
158   }
159   return true;
160 }
161 
162 static void getSearchPaths(std::vector<StringRef> &paths, unsigned optionCode,
163                            opt::InputArgList &args,
164                            const std::vector<StringRef> &roots,
165                            const SmallVector<StringRef, 2> &systemPaths) {
166   StringRef optionLetter{(optionCode == OPT_F ? "F" : "L")};
167   for (auto const &path : args::getStrings(args, optionCode)) {
168     // NOTE: only absolute paths are re-rooted to syslibroot(s)
169     if (llvm::sys::path::is_absolute(path, llvm::sys::path::Style::posix)) {
170       for (StringRef root : roots) {
171         SmallString<261> buffer(root);
172         llvm::sys::path::append(buffer, path);
173         // Do not warn about paths that are computed via the syslib roots
174         if (llvm::sys::fs::is_directory(buffer))
175           paths.push_back(saver.save(buffer.str()));
176       }
177     } else {
178       if (isDirectory(optionLetter, path))
179         paths.push_back(path);
180     }
181   }
182 
183   // `-Z` suppresses the standard "system" search paths.
184   if (args.hasArg(OPT_Z))
185     return;
186 
187   for (auto const &path : systemPaths) {
188     for (auto root : roots) {
189       SmallString<261> buffer(root);
190       llvm::sys::path::append(buffer, path);
191       if (isDirectory(optionLetter, buffer))
192         paths.push_back(saver.save(buffer.str()));
193     }
194   }
195 }
196 
197 static void getLibrarySearchPaths(opt::InputArgList &args,
198                                   const std::vector<StringRef> &roots,
199                                   std::vector<StringRef> &paths) {
200   getSearchPaths(paths, OPT_L, args, roots, {"/usr/lib", "/usr/local/lib"});
201 }
202 
203 static void getFrameworkSearchPaths(opt::InputArgList &args,
204                                     const std::vector<StringRef> &roots,
205                                     std::vector<StringRef> &paths) {
206   getSearchPaths(paths, OPT_F, args, roots,
207                  {"/Library/Frameworks", "/System/Library/Frameworks"});
208 }
209 
210 static void addFile(StringRef path) {
211   Optional<MemoryBufferRef> buffer = readFile(path);
212   if (!buffer)
213     return;
214   MemoryBufferRef mbref = *buffer;
215 
216   switch (identify_magic(mbref.getBuffer())) {
217   case file_magic::archive: {
218     std::unique_ptr<object::Archive> file = CHECK(
219         object::Archive::create(mbref), path + ": failed to parse archive");
220 
221     if (!file->isEmpty() && !file->hasSymbolTable())
222       error(path + ": archive has no index; run ranlib to add one");
223 
224     inputFiles.push_back(make<ArchiveFile>(std::move(file)));
225     break;
226   }
227   case file_magic::macho_object:
228     inputFiles.push_back(make<ObjFile>(mbref));
229     break;
230   case file_magic::macho_dynamically_linked_shared_lib:
231     inputFiles.push_back(make<DylibFile>(mbref));
232     break;
233   case file_magic::tapi_file: {
234     Expected<std::unique_ptr<InterfaceFile>> result = TextAPIReader::get(mbref);
235     if (!result) {
236       error("could not load TAPI file at " + mbref.getBufferIdentifier() +
237             ": " + toString(result.takeError()));
238       return;
239     }
240     inputFiles.push_back(make<DylibFile>(**result));
241     break;
242   }
243   default:
244     error(path + ": unhandled file type");
245   }
246 }
247 
248 static void addFileList(StringRef path) {
249   Optional<MemoryBufferRef> buffer = readFile(path);
250   if (!buffer)
251     return;
252   MemoryBufferRef mbref = *buffer;
253   for (StringRef path : args::getLines(mbref))
254     addFile(path);
255 }
256 
257 // Returns slices of MB by parsing MB as an archive file.
258 // Each slice consists of a member file in the archive.
259 static std::vector<MemoryBufferRef> getArchiveMembers(MemoryBufferRef mb) {
260   std::unique_ptr<Archive> file =
261       CHECK(Archive::create(mb),
262             mb.getBufferIdentifier() + ": failed to parse archive");
263 
264   std::vector<MemoryBufferRef> v;
265   Error err = Error::success();
266   for (const Archive::Child &c : file->children(err)) {
267     MemoryBufferRef mbref =
268         CHECK(c.getMemoryBufferRef(),
269               mb.getBufferIdentifier() +
270                   ": could not get the buffer for a child of the archive");
271     v.push_back(mbref);
272   }
273   if (err)
274     fatal(mb.getBufferIdentifier() +
275           ": Archive::children failed: " + toString(std::move(err)));
276 
277   return v;
278 }
279 
280 static void forceLoadArchive(StringRef path) {
281   if (Optional<MemoryBufferRef> buffer = readFile(path))
282     for (MemoryBufferRef member : getArchiveMembers(*buffer))
283       inputFiles.push_back(make<ObjFile>(member));
284 }
285 
286 static std::array<StringRef, 6> archNames{"arm",    "arm64", "i386",
287                                           "x86_64", "ppc",   "ppc64"};
288 static bool isArchString(StringRef s) {
289   static DenseSet<StringRef> archNamesSet(archNames.begin(), archNames.end());
290   return archNamesSet.find(s) != archNamesSet.end();
291 }
292 
293 // An order file has one entry per line, in the following format:
294 //
295 //   <arch>:<object file>:<symbol name>
296 //
297 // <arch> and <object file> are optional. If not specified, then that entry
298 // matches any symbol of that name.
299 //
300 // If a symbol is matched by multiple entries, then it takes the lowest-ordered
301 // entry (the one nearest to the front of the list.)
302 //
303 // The file can also have line comments that start with '#'.
304 static void parseOrderFile(StringRef path) {
305   Optional<MemoryBufferRef> buffer = readFile(path);
306   if (!buffer) {
307     error("Could not read order file at " + path);
308     return;
309   }
310 
311   MemoryBufferRef mbref = *buffer;
312   size_t priority = std::numeric_limits<size_t>::max();
313   for (StringRef rest : args::getLines(mbref)) {
314     StringRef arch, objectFile, symbol;
315 
316     std::array<StringRef, 3> fields;
317     uint8_t fieldCount = 0;
318     while (rest != "" && fieldCount < 3) {
319       std::pair<StringRef, StringRef> p = getToken(rest, ": \t\n\v\f\r");
320       StringRef tok = p.first;
321       rest = p.second;
322 
323       // Check if we have a comment
324       if (tok == "" || tok[0] == '#')
325         break;
326 
327       fields[fieldCount++] = tok;
328     }
329 
330     switch (fieldCount) {
331     case 3:
332       arch = fields[0];
333       objectFile = fields[1];
334       symbol = fields[2];
335       break;
336     case 2:
337       (isArchString(fields[0]) ? arch : objectFile) = fields[0];
338       symbol = fields[1];
339       break;
340     case 1:
341       symbol = fields[0];
342       break;
343     case 0:
344       break;
345     default:
346       llvm_unreachable("too many fields in order file");
347     }
348 
349     if (!arch.empty()) {
350       if (!isArchString(arch)) {
351         error("invalid arch \"" + arch + "\" in order file: expected one of " +
352               llvm::join(archNames, ", "));
353         continue;
354       }
355 
356       // TODO: Update when we extend support for other archs
357       if (arch != "x86_64")
358         continue;
359     }
360 
361     if (!objectFile.empty() && !objectFile.endswith(".o")) {
362       error("invalid object file name \"" + objectFile +
363             "\" in order file: should end with .o");
364       continue;
365     }
366 
367     if (!symbol.empty()) {
368       SymbolPriorityEntry &entry = config->priorities[symbol];
369       if (!objectFile.empty())
370         entry.objectFiles.insert(std::make_pair(objectFile, priority));
371       else
372         entry.anyObjectFile = std::max(entry.anyObjectFile, priority);
373     }
374 
375     --priority;
376   }
377 }
378 
379 // We expect sub-library names of the form "libfoo", which will match a dylib
380 // with a path of .*/libfoo.dylib.
381 static bool markSubLibrary(StringRef searchName) {
382   for (InputFile *file : inputFiles) {
383     if (auto *dylibFile = dyn_cast<DylibFile>(file)) {
384       StringRef filename = path::filename(dylibFile->getName());
385       if (filename.consume_front(searchName) && filename == ".dylib") {
386         dylibFile->reexport = true;
387         return true;
388       }
389     }
390   }
391   return false;
392 }
393 
394 static inline char toLowerDash(char x) {
395   if (x >= 'A' && x <= 'Z')
396     return x - 'A' + 'a';
397   else if (x == ' ')
398     return '-';
399   return x;
400 }
401 
402 static std::string lowerDash(StringRef s) {
403   return std::string(map_iterator(s.begin(), toLowerDash),
404                      map_iterator(s.end(), toLowerDash));
405 }
406 
407 static void handlePlatformVersion(const opt::Arg *arg) {
408   StringRef platformStr = arg->getValue(0);
409   StringRef minVersionStr = arg->getValue(1);
410   StringRef sdkVersionStr = arg->getValue(2);
411 
412   // TODO(compnerd) see if we can generate this case list via XMACROS
413   config->platform.kind =
414       llvm::StringSwitch<llvm::MachO::PlatformKind>(lowerDash(platformStr))
415           .Cases("macos", "1", llvm::MachO::PlatformKind::macOS)
416           .Cases("ios", "2", llvm::MachO::PlatformKind::iOS)
417           .Cases("tvos", "3", llvm::MachO::PlatformKind::tvOS)
418           .Cases("watchos", "4", llvm::MachO::PlatformKind::watchOS)
419           .Cases("bridgeos", "5", llvm::MachO::PlatformKind::bridgeOS)
420           .Cases("mac-catalyst", "6", llvm::MachO::PlatformKind::macCatalyst)
421           .Cases("ios-simulator", "7", llvm::MachO::PlatformKind::iOSSimulator)
422           .Cases("tvos-simulator", "8",
423                  llvm::MachO::PlatformKind::tvOSSimulator)
424           .Cases("watchos-simulator", "9",
425                  llvm::MachO::PlatformKind::watchOSSimulator)
426           .Default(llvm::MachO::PlatformKind::unknown);
427   if (config->platform.kind == llvm::MachO::PlatformKind::unknown)
428     error(Twine("malformed platform: ") + platformStr);
429   // TODO: check validity of version strings, which varies by platform
430   // NOTE: ld64 accepts version strings with 5 components
431   // llvm::VersionTuple accepts no more than 4 components
432   // Has Apple ever published version strings with 5 components?
433   if (config->platform.minimum.tryParse(minVersionStr))
434     error(Twine("malformed minimum version: ") + minVersionStr);
435   if (config->platform.sdk.tryParse(sdkVersionStr))
436     error(Twine("malformed sdk version: ") + sdkVersionStr);
437 }
438 
439 static void warnIfDeprecatedOption(const opt::Option &opt) {
440   if (!opt.getGroup().isValid())
441     return;
442   if (opt.getGroup().getID() == OPT_grp_deprecated) {
443     warn("Option `" + opt.getPrefixedName() + "' is deprecated in ld64:");
444     warn(opt.getHelpText());
445   }
446 }
447 
448 static void warnIfUnimplementedOption(const opt::Option &opt) {
449   if (!opt.getGroup().isValid())
450     return;
451   switch (opt.getGroup().getID()) {
452   case OPT_grp_deprecated:
453     // warn about deprecated options elsewhere
454     break;
455   case OPT_grp_undocumented:
456     warn("Option `" + opt.getPrefixedName() +
457          "' is undocumented. Should lld implement it?");
458     break;
459   case OPT_grp_obsolete:
460     warn("Option `" + opt.getPrefixedName() +
461          "' is obsolete. Please modernize your usage.");
462     break;
463   case OPT_grp_ignored:
464     warn("Option `" + opt.getPrefixedName() + "' is ignored.");
465     break;
466   default:
467     warn("Option `" + opt.getPrefixedName() +
468          "' is not yet implemented. Stay tuned...");
469     break;
470   }
471 }
472 
473 bool macho::link(llvm::ArrayRef<const char *> argsArr, bool canExitEarly,
474                  raw_ostream &stdoutOS, raw_ostream &stderrOS) {
475   lld::stdoutOS = &stdoutOS;
476   lld::stderrOS = &stderrOS;
477 
478   stderrOS.enable_colors(stderrOS.has_colors());
479   // TODO: Set up error handler properly, e.g. the errorLimitExceededMsg
480 
481   MachOOptTable parser;
482   opt::InputArgList args = parser.parse(argsArr.slice(1));
483 
484   if (args.hasArg(OPT_help_hidden)) {
485     parser.printHelp(argsArr[0], /*showHidden=*/true);
486     return true;
487   } else if (args.hasArg(OPT_help)) {
488     parser.printHelp(argsArr[0], /*showHidden=*/false);
489     return true;
490   }
491 
492   config = make<Configuration>();
493   symtab = make<SymbolTable>();
494   target = createTargetInfo(args);
495 
496   config->entry = symtab->addUndefined(args.getLastArgValue(OPT_e, "_main"));
497   config->outputFile = args.getLastArgValue(OPT_o, "a.out");
498   config->installName =
499       args.getLastArgValue(OPT_install_name, config->outputFile);
500   config->headerPad = args::getHex(args, OPT_headerpad, /*Default=*/32);
501   config->outputType = args.hasArg(OPT_dylib) ? MH_DYLIB : MH_EXECUTE;
502   config->runtimePaths = args::getStrings(args, OPT_rpath);
503 
504   std::vector<StringRef> roots;
505   for (const Arg *arg : args.filtered(OPT_syslibroot))
506     roots.push_back(arg->getValue());
507   // NOTE: the final `-syslibroot` being `/` will ignore all roots
508   if (roots.size() && roots.back() == "/")
509     roots.clear();
510   // NOTE: roots can never be empty - add an empty root to simplify the library
511   // and framework search path computation.
512   if (roots.empty())
513     roots.emplace_back("");
514 
515   getLibrarySearchPaths(args, roots, config->librarySearchPaths);
516   getFrameworkSearchPaths(args, roots, config->frameworkSearchPaths);
517 
518   if (args.hasArg(OPT_v)) {
519     message(getLLDVersion());
520     message(StringRef("Library search paths:") +
521             (config->librarySearchPaths.size()
522                  ? "\n\t" + llvm::join(config->librarySearchPaths, "\n\t")
523                  : ""));
524     message(StringRef("Framework search paths:") +
525             (config->frameworkSearchPaths.size()
526                  ? "\n\t" + llvm::join(config->frameworkSearchPaths, "\n\t")
527                  : ""));
528     freeArena();
529     return !errorCount();
530   }
531 
532   for (const auto &arg : args) {
533     const auto &opt = arg->getOption();
534     warnIfDeprecatedOption(opt);
535     switch (arg->getOption().getID()) {
536     case OPT_INPUT:
537       addFile(arg->getValue());
538       break;
539     case OPT_filelist:
540       addFileList(arg->getValue());
541       break;
542     case OPT_force_load:
543       forceLoadArchive(arg->getValue());
544       break;
545     case OPT_l: {
546       StringRef name = arg->getValue();
547       if (Optional<std::string> path = findLibrary(name)) {
548         addFile(*path);
549         break;
550       }
551       error("library not found for -l" + name);
552       break;
553     }
554     case OPT_framework: {
555       StringRef name = arg->getValue();
556       if (Optional<std::string> path = findFramework(name)) {
557         addFile(*path);
558         break;
559       }
560       error("framework not found for -framework " + name);
561       break;
562     }
563     case OPT_platform_version:
564       handlePlatformVersion(arg);
565       break;
566     case OPT_o:
567     case OPT_dylib:
568     case OPT_e:
569     case OPT_F:
570     case OPT_L:
571     case OPT_headerpad:
572     case OPT_install_name:
573     case OPT_rpath:
574     case OPT_sub_library:
575     case OPT_Z:
576     case OPT_arch:
577     case OPT_syslibroot:
578     case OPT_sectcreate:
579       // handled elsewhere
580       break;
581     default:
582       warnIfUnimplementedOption(opt);
583       break;
584     }
585   }
586 
587   // Now that all dylibs have been loaded, search for those that should be
588   // re-exported.
589   for (opt::Arg *arg : args.filtered(OPT_sub_library)) {
590     config->hasReexports = true;
591     StringRef searchName = arg->getValue();
592     if (!markSubLibrary(searchName))
593       error("-sub_library " + searchName + " does not match a supplied dylib");
594   }
595 
596   StringRef orderFile = args.getLastArgValue(OPT_order_file);
597   if (!orderFile.empty())
598     parseOrderFile(orderFile);
599 
600   if (config->outputType == MH_EXECUTE && !isa<Defined>(config->entry)) {
601     error("undefined symbol: " + config->entry->getName());
602     return false;
603   }
604 
605   createSyntheticSections();
606   symtab->addDSOHandle(in.header);
607 
608   for (opt::Arg *arg : args.filtered(OPT_sectcreate)) {
609     StringRef segName = arg->getValue(0);
610     StringRef sectName = arg->getValue(1);
611     StringRef fileName = arg->getValue(2);
612     Optional<MemoryBufferRef> buffer = readFile(fileName);
613     if (buffer)
614       inputFiles.push_back(make<OpaqueFile>(*buffer, segName, sectName));
615   }
616 
617   // Initialize InputSections.
618   for (InputFile *file : inputFiles) {
619     for (SubsectionMap &map : file->subsections) {
620       for (auto &p : map) {
621         InputSection *isec = p.second;
622         inputSections.push_back(isec);
623       }
624     }
625   }
626 
627   // Write to an output file.
628   writeResult();
629 
630   if (canExitEarly)
631     exitLld(errorCount() ? 1 : 0);
632 
633   freeArena();
634   return !errorCount();
635 }
636