Driver.cpp revision 1.1.1.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 "InputFiles.h"
12#include "OutputSection.h"
13#include "OutputSegment.h"
14#include "SymbolTable.h"
15#include "Symbols.h"
16#include "Target.h"
17#include "Writer.h"
18
19#include "lld/Common/Args.h"
20#include "lld/Common/Driver.h"
21#include "lld/Common/ErrorHandler.h"
22#include "lld/Common/LLVM.h"
23#include "lld/Common/Memory.h"
24#include "lld/Common/Version.h"
25#include "llvm/ADT/DenseSet.h"
26#include "llvm/ADT/StringExtras.h"
27#include "llvm/ADT/StringRef.h"
28#include "llvm/BinaryFormat/MachO.h"
29#include "llvm/BinaryFormat/Magic.h"
30#include "llvm/Object/Archive.h"
31#include "llvm/Option/ArgList.h"
32#include "llvm/Option/Option.h"
33#include "llvm/Support/Host.h"
34#include "llvm/Support/MemoryBuffer.h"
35#include "llvm/Support/Path.h"
36
37using namespace llvm;
38using namespace llvm::MachO;
39using namespace llvm::sys;
40using namespace llvm::opt;
41using namespace lld;
42using namespace lld::macho;
43
44Configuration *lld::macho::config;
45
46// Create prefix string literals used in Options.td
47#define PREFIX(NAME, VALUE) const char *NAME[] = VALUE;
48#include "Options.inc"
49#undef PREFIX
50
51// Create table mapping all options defined in Options.td
52static const opt::OptTable::Info optInfo[] = {
53#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12)      \
54  {X1, X2, X10,         X11,         OPT_##ID, opt::Option::KIND##Class,       \
55   X9, X8, OPT_##GROUP, OPT_##ALIAS, X7,       X12},
56#include "Options.inc"
57#undef OPTION
58};
59
60MachOOptTable::MachOOptTable() : OptTable(optInfo) {}
61
62opt::InputArgList MachOOptTable::parse(ArrayRef<const char *> argv) {
63  // Make InputArgList from string vectors.
64  unsigned missingIndex;
65  unsigned missingCount;
66  SmallVector<const char *, 256> vec(argv.data(), argv.data() + argv.size());
67
68  opt::InputArgList args = ParseArgs(vec, missingIndex, missingCount);
69
70  if (missingCount)
71    error(Twine(args.getArgString(missingIndex)) + ": missing argument");
72
73  for (opt::Arg *arg : args.filtered(OPT_UNKNOWN))
74    error("unknown argument: " + arg->getSpelling());
75  return args;
76}
77
78void MachOOptTable::printHelp(const char *argv0, bool showHidden) const {
79  PrintHelp(lld::outs(), (std::string(argv0) + " [options] file...").c_str(),
80            "LLVM Linker", showHidden);
81  lld::outs() << "\n";
82}
83
84static Optional<std::string> findLibrary(StringRef name) {
85  std::string stub = (llvm::Twine("lib") + name + ".tbd").str();
86  std::string shared = (llvm::Twine("lib") + name + ".dylib").str();
87  std::string archive = (llvm::Twine("lib") + name + ".a").str();
88  llvm::SmallString<260> location;
89
90  for (StringRef dir : config->librarySearchPaths) {
91    for (StringRef library : {stub, shared, archive}) {
92      location = dir;
93      llvm::sys::path::append(location, library);
94      if (fs::exists(location))
95        return location.str().str();
96    }
97  }
98  return {};
99}
100
101static TargetInfo *createTargetInfo(opt::InputArgList &args) {
102  StringRef arch = args.getLastArgValue(OPT_arch, "x86_64");
103  config->arch = llvm::MachO::getArchitectureFromName(
104      args.getLastArgValue(OPT_arch, arch));
105  switch (config->arch) {
106  case llvm::MachO::AK_x86_64:
107  case llvm::MachO::AK_x86_64h:
108    return createX86_64TargetInfo();
109  default:
110    fatal("missing or unsupported -arch " + arch);
111  }
112}
113
114static bool isDirectory(StringRef option, StringRef path) {
115  if (!fs::exists(path)) {
116    warn("directory not found for option -" + option + path);
117    return false;
118  } else if (!fs::is_directory(path)) {
119    warn("option -" + option + path + " references a non-directory path");
120    return false;
121  }
122  return true;
123}
124
125static void getSearchPaths(std::vector<StringRef> &paths, unsigned optionCode,
126                           opt::InputArgList &args,
127                           const SmallVector<StringRef, 2> &systemPaths) {
128  StringRef optionLetter{(optionCode == OPT_F ? "F" : "L")};
129  for (auto const &path : args::getStrings(args, optionCode)) {
130    if (isDirectory(optionLetter, path))
131      paths.push_back(path);
132  }
133  if (!args.hasArg(OPT_Z) && Triple(sys::getProcessTriple()).isOSDarwin()) {
134    for (auto const &path : systemPaths) {
135      if (isDirectory(optionLetter, path))
136        paths.push_back(path);
137    }
138  }
139}
140
141static void getLibrarySearchPaths(std::vector<StringRef> &paths,
142                                  opt::InputArgList &args) {
143  getSearchPaths(paths, OPT_L, args, {"/usr/lib", "/usr/local/lib"});
144}
145
146static void getFrameworkSearchPaths(std::vector<StringRef> &paths,
147                                    opt::InputArgList &args) {
148  getSearchPaths(paths, OPT_F, args,
149                 {"/Library/Frameworks", "/System/Library/Frameworks"});
150}
151
152static void addFile(StringRef path) {
153  Optional<MemoryBufferRef> buffer = readFile(path);
154  if (!buffer)
155    return;
156  MemoryBufferRef mbref = *buffer;
157
158  switch (identify_magic(mbref.getBuffer())) {
159  case file_magic::archive: {
160    std::unique_ptr<object::Archive> file = CHECK(
161        object::Archive::create(mbref), path + ": failed to parse archive");
162
163    if (!file->isEmpty() && !file->hasSymbolTable())
164      error(path + ": archive has no index; run ranlib to add one");
165
166    inputFiles.push_back(make<ArchiveFile>(std::move(file)));
167    break;
168  }
169  case file_magic::macho_object:
170    inputFiles.push_back(make<ObjFile>(mbref));
171    break;
172  case file_magic::macho_dynamically_linked_shared_lib:
173    inputFiles.push_back(make<DylibFile>(mbref));
174    break;
175  case file_magic::tapi_file: {
176    llvm::Expected<std::unique_ptr<llvm::MachO::InterfaceFile>> result =
177        TextAPIReader::get(mbref);
178    if (!result)
179      return;
180
181    inputFiles.push_back(make<DylibFile>(std::move(*result)));
182    break;
183  }
184  default:
185    error(path + ": unhandled file type");
186  }
187}
188
189static std::array<StringRef, 6> archNames{"arm",    "arm64", "i386",
190                                          "x86_64", "ppc",   "ppc64"};
191static bool isArchString(StringRef s) {
192  static DenseSet<StringRef> archNamesSet(archNames.begin(), archNames.end());
193  return archNamesSet.find(s) != archNamesSet.end();
194}
195
196// An order file has one entry per line, in the following format:
197//
198//   <arch>:<object file>:<symbol name>
199//
200// <arch> and <object file> are optional. If not specified, then that entry
201// matches any symbol of that name.
202//
203// If a symbol is matched by multiple entries, then it takes the lowest-ordered
204// entry (the one nearest to the front of the list.)
205//
206// The file can also have line comments that start with '#'.
207void parseOrderFile(StringRef path) {
208  Optional<MemoryBufferRef> buffer = readFile(path);
209  if (!buffer) {
210    error("Could not read order file at " + path);
211    return;
212  }
213
214  MemoryBufferRef mbref = *buffer;
215  size_t priority = std::numeric_limits<size_t>::max();
216  for (StringRef rest : args::getLines(mbref)) {
217    StringRef arch, objectFile, symbol;
218
219    std::array<StringRef, 3> fields;
220    uint8_t fieldCount = 0;
221    while (rest != "" && fieldCount < 3) {
222      std::pair<StringRef, StringRef> p = getToken(rest, ": \t\n\v\f\r");
223      StringRef tok = p.first;
224      rest = p.second;
225
226      // Check if we have a comment
227      if (tok == "" || tok[0] == '#')
228        break;
229
230      fields[fieldCount++] = tok;
231    }
232
233    switch (fieldCount) {
234    case 3:
235      arch = fields[0];
236      objectFile = fields[1];
237      symbol = fields[2];
238      break;
239    case 2:
240      (isArchString(fields[0]) ? arch : objectFile) = fields[0];
241      symbol = fields[1];
242      break;
243    case 1:
244      symbol = fields[0];
245      break;
246    case 0:
247      break;
248    default:
249      llvm_unreachable("too many fields in order file");
250    }
251
252    if (!arch.empty()) {
253      if (!isArchString(arch)) {
254        error("invalid arch \"" + arch + "\" in order file: expected one of " +
255              llvm::join(archNames, ", "));
256        continue;
257      }
258
259      // TODO: Update when we extend support for other archs
260      if (arch != "x86_64")
261        continue;
262    }
263
264    if (!objectFile.empty() && !objectFile.endswith(".o")) {
265      error("invalid object file name \"" + objectFile +
266            "\" in order file: should end with .o");
267      continue;
268    }
269
270    if (!symbol.empty()) {
271      SymbolPriorityEntry &entry = config->priorities[symbol];
272      if (!objectFile.empty())
273        entry.objectFiles.insert(std::make_pair(objectFile, priority));
274      else
275        entry.anyObjectFile = std::max(entry.anyObjectFile, priority);
276    }
277
278    --priority;
279  }
280}
281
282// We expect sub-library names of the form "libfoo", which will match a dylib
283// with a path of .*/libfoo.dylib.
284static bool markSubLibrary(StringRef searchName) {
285  for (InputFile *file : inputFiles) {
286    if (auto *dylibFile = dyn_cast<DylibFile>(file)) {
287      StringRef filename = path::filename(dylibFile->getName());
288      if (filename.consume_front(searchName) && filename == ".dylib") {
289        dylibFile->reexport = true;
290        return true;
291      }
292    }
293  }
294  return false;
295}
296
297static void handlePlatformVersion(const opt::Arg *arg) {
298  // TODO: implementation coming very soon ...
299}
300
301static void warnIfDeprecatedOption(const opt::Option &opt) {
302  if (!opt.getGroup().isValid())
303    return;
304  if (opt.getGroup().getID() == OPT_grp_deprecated) {
305    warn("Option `" + opt.getPrefixedName() + "' is deprecated in ld64:");
306    warn(opt.getHelpText());
307  }
308}
309
310static void warnIfUnimplementedOption(const opt::Option &opt) {
311  if (!opt.getGroup().isValid())
312    return;
313  switch (opt.getGroup().getID()) {
314  case OPT_grp_deprecated:
315    // warn about deprecated options elsewhere
316    break;
317  case OPT_grp_undocumented:
318    warn("Option `" + opt.getPrefixedName() +
319         "' is undocumented. Should lld implement it?");
320    break;
321  case OPT_grp_obsolete:
322    warn("Option `" + opt.getPrefixedName() +
323         "' is obsolete. Please modernize your usage.");
324    break;
325  case OPT_grp_ignored:
326    warn("Option `" + opt.getPrefixedName() + "' is ignored.");
327    break;
328  default:
329    warn("Option `" + opt.getPrefixedName() +
330         "' is not yet implemented. Stay tuned...");
331    break;
332  }
333}
334
335bool macho::link(llvm::ArrayRef<const char *> argsArr, bool canExitEarly,
336                 raw_ostream &stdoutOS, raw_ostream &stderrOS) {
337  lld::stdoutOS = &stdoutOS;
338  lld::stderrOS = &stderrOS;
339
340  stderrOS.enable_colors(stderrOS.has_colors());
341  // TODO: Set up error handler properly, e.g. the errorLimitExceededMsg
342
343  MachOOptTable parser;
344  opt::InputArgList args = parser.parse(argsArr.slice(1));
345
346  if (args.hasArg(OPT_help_hidden)) {
347    parser.printHelp(argsArr[0], /*showHidden=*/true);
348    return true;
349  } else if (args.hasArg(OPT_help)) {
350    parser.printHelp(argsArr[0], /*showHidden=*/false);
351    return true;
352  }
353
354  config = make<Configuration>();
355  symtab = make<SymbolTable>();
356  target = createTargetInfo(args);
357
358  config->entry = symtab->addUndefined(args.getLastArgValue(OPT_e, "_main"));
359  config->outputFile = args.getLastArgValue(OPT_o, "a.out");
360  config->installName =
361      args.getLastArgValue(OPT_install_name, config->outputFile);
362  getLibrarySearchPaths(config->librarySearchPaths, args);
363  getFrameworkSearchPaths(config->frameworkSearchPaths, args);
364  config->outputType = args.hasArg(OPT_dylib) ? MH_DYLIB : MH_EXECUTE;
365
366  if (args.hasArg(OPT_v)) {
367    message(getLLDVersion());
368    message(StringRef("Library search paths:") +
369            (config->librarySearchPaths.size()
370                 ? "\n\t" + llvm::join(config->librarySearchPaths, "\n\t")
371                 : ""));
372    message(StringRef("Framework search paths:") +
373            (config->frameworkSearchPaths.size()
374                 ? "\n\t" + llvm::join(config->frameworkSearchPaths, "\n\t")
375                 : ""));
376    freeArena();
377    return !errorCount();
378  }
379
380  for (const auto &arg : args) {
381    const auto &opt = arg->getOption();
382    warnIfDeprecatedOption(opt);
383    switch (arg->getOption().getID()) {
384    case OPT_INPUT:
385      addFile(arg->getValue());
386      break;
387    case OPT_l: {
388      StringRef name = arg->getValue();
389      if (Optional<std::string> path = findLibrary(name)) {
390        addFile(*path);
391        break;
392      }
393      error("library not found for -l" + name);
394      break;
395    }
396    case OPT_platform_version:
397      handlePlatformVersion(arg);
398      break;
399    case OPT_o:
400    case OPT_dylib:
401    case OPT_e:
402    case OPT_L:
403    case OPT_Z:
404    case OPT_arch:
405      // handled elsewhere
406      break;
407    default:
408      warnIfUnimplementedOption(opt);
409      break;
410    }
411  }
412
413  // Now that all dylibs have been loaded, search for those that should be
414  // re-exported.
415  for (opt::Arg *arg : args.filtered(OPT_sub_library)) {
416    config->hasReexports = true;
417    StringRef searchName = arg->getValue();
418    if (!markSubLibrary(searchName))
419      error("-sub_library " + searchName + " does not match a supplied dylib");
420  }
421
422  StringRef orderFile = args.getLastArgValue(OPT_order_file);
423  if (!orderFile.empty())
424    parseOrderFile(orderFile);
425
426  if (config->outputType == MH_EXECUTE && !isa<Defined>(config->entry)) {
427    error("undefined symbol: " + config->entry->getName());
428    return false;
429  }
430
431  createSyntheticSections();
432
433  // Initialize InputSections.
434  for (InputFile *file : inputFiles) {
435    for (SubsectionMap &map : file->subsections) {
436      for (auto &p : map) {
437        InputSection *isec = p.second;
438        inputSections.push_back(isec);
439      }
440    }
441  }
442
443  // Write to an output file.
444  writeResult();
445
446  if (canExitEarly)
447    exitLld(errorCount() ? 1 : 0);
448
449  freeArena();
450  return !errorCount();
451}
452