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/StringExtras.h" 26 #include "llvm/ADT/StringRef.h" 27 #include "llvm/BinaryFormat/MachO.h" 28 #include "llvm/BinaryFormat/Magic.h" 29 #include "llvm/Option/ArgList.h" 30 #include "llvm/Option/Option.h" 31 #include "llvm/Support/MemoryBuffer.h" 32 33 using namespace llvm; 34 using namespace llvm::MachO; 35 using namespace llvm::sys; 36 using namespace lld; 37 using namespace lld::macho; 38 39 Configuration *lld::macho::config; 40 41 // Create prefix string literals used in Options.td 42 #define PREFIX(NAME, VALUE) const char *NAME[] = VALUE; 43 #include "Options.inc" 44 #undef PREFIX 45 46 // Create table mapping all options defined in Options.td 47 static const opt::OptTable::Info optInfo[] = { 48 #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \ 49 {X1, X2, X10, X11, OPT_##ID, opt::Option::KIND##Class, \ 50 X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12}, 51 #include "Options.inc" 52 #undef OPTION 53 }; 54 55 MachOOptTable::MachOOptTable() : OptTable(optInfo) {} 56 57 opt::InputArgList MachOOptTable::parse(ArrayRef<const char *> argv) { 58 // Make InputArgList from string vectors. 59 unsigned missingIndex; 60 unsigned missingCount; 61 SmallVector<const char *, 256> vec(argv.data(), argv.data() + argv.size()); 62 63 opt::InputArgList args = ParseArgs(vec, missingIndex, missingCount); 64 65 if (missingCount) 66 error(Twine(args.getArgString(missingIndex)) + ": missing argument"); 67 68 for (opt::Arg *arg : args.filtered(OPT_UNKNOWN)) 69 error("unknown argument: " + arg->getSpelling()); 70 return args; 71 } 72 73 // This is for -lfoo. We'll look for libfoo.dylib from search paths. 74 static Optional<std::string> findDylib(StringRef name) { 75 for (StringRef dir : config->searchPaths) { 76 std::string path = (dir + "/lib" + name + ".dylib").str(); 77 if (fs::exists(path)) 78 return path; 79 } 80 error("library not found for -l" + name); 81 return None; 82 } 83 84 static TargetInfo *createTargetInfo(opt::InputArgList &args) { 85 StringRef s = args.getLastArgValue(OPT_arch, "x86_64"); 86 if (s != "x86_64") 87 error("missing or unsupported -arch " + s); 88 return createX86_64TargetInfo(); 89 } 90 91 static std::vector<StringRef> getSearchPaths(opt::InputArgList &args) { 92 std::vector<StringRef> ret{args::getStrings(args, OPT_L)}; 93 if (!args.hasArg(OPT_Z)) { 94 ret.push_back("/usr/lib"); 95 ret.push_back("/usr/local/lib"); 96 } 97 return ret; 98 } 99 100 static void addFile(StringRef path) { 101 Optional<MemoryBufferRef> buffer = readFile(path); 102 if (!buffer) 103 return; 104 MemoryBufferRef mbref = *buffer; 105 106 switch (identify_magic(mbref.getBuffer())) { 107 case file_magic::macho_object: 108 inputFiles.push_back(make<ObjFile>(mbref)); 109 break; 110 case file_magic::macho_dynamically_linked_shared_lib: 111 inputFiles.push_back(make<DylibFile>(mbref)); 112 break; 113 default: 114 error(path + ": unhandled file type"); 115 } 116 } 117 118 bool macho::link(llvm::ArrayRef<const char *> argsArr, bool canExitEarly, 119 raw_ostream &stdoutOS, raw_ostream &stderrOS) { 120 lld::stdoutOS = &stdoutOS; 121 lld::stderrOS = &stderrOS; 122 123 stderrOS.enable_colors(stderrOS.has_colors()); 124 // TODO: Set up error handler properly, e.g. the errorLimitExceededMsg 125 126 MachOOptTable parser; 127 opt::InputArgList args = parser.parse(argsArr.slice(1)); 128 129 config = make<Configuration>(); 130 symtab = make<SymbolTable>(); 131 target = createTargetInfo(args); 132 133 config->entry = symtab->addUndefined(args.getLastArgValue(OPT_e, "_main")); 134 config->outputFile = args.getLastArgValue(OPT_o, "a.out"); 135 config->installName = 136 args.getLastArgValue(OPT_install_name, config->outputFile); 137 config->searchPaths = getSearchPaths(args); 138 config->outputType = args.hasArg(OPT_dylib) ? MH_DYLIB : MH_EXECUTE; 139 140 if (args.hasArg(OPT_v)) { 141 message(getLLDVersion()); 142 std::vector<StringRef> &searchPaths = config->searchPaths; 143 message("Library search paths:\n" + 144 llvm::join(searchPaths.begin(), searchPaths.end(), "\n")); 145 freeArena(); 146 return !errorCount(); 147 } 148 149 for (opt::Arg *arg : args) { 150 switch (arg->getOption().getID()) { 151 case OPT_INPUT: 152 addFile(arg->getValue()); 153 break; 154 case OPT_l: 155 if (Optional<std::string> path = findDylib(arg->getValue())) 156 addFile(*path); 157 break; 158 } 159 } 160 161 if (config->outputType == MH_EXECUTE && !isa<Defined>(config->entry)) { 162 error("undefined symbol: " + config->entry->getName()); 163 return false; 164 } 165 166 createSyntheticSections(); 167 168 // Initialize InputSections. 169 for (InputFile *file : inputFiles) 170 for (InputSection *sec : file->sections) 171 inputSections.push_back(sec); 172 173 // Write to an output file. 174 writeResult(); 175 176 if (canExitEarly) 177 exitLld(errorCount() ? 1 : 0); 178 179 freeArena(); 180 return !errorCount(); 181 } 182