1 //===- MinGW/Driver.cpp ---------------------------------------------------===// 2 // 3 // The LLVM Linker 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// 10 /// GNU ld style linker driver for COFF currently supporting mingw-w64. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "lld/Common/Driver.h" 15 #include "lld/Common/ErrorHandler.h" 16 #include "llvm/ADT/ArrayRef.h" 17 #include "llvm/ADT/Optional.h" 18 #include "llvm/ADT/StringExtras.h" 19 #include "llvm/ADT/StringRef.h" 20 #include "llvm/Option/Arg.h" 21 #include "llvm/Option/ArgList.h" 22 #include "llvm/Option/Option.h" 23 #include "llvm/Support/CommandLine.h" 24 #include "llvm/Support/FileSystem.h" 25 #include "llvm/Support/Path.h" 26 27 #if !defined(_MSC_VER) && !defined(__MINGW32__) 28 #include <unistd.h> 29 #endif 30 31 using namespace lld; 32 using namespace llvm; 33 34 // Create OptTable 35 enum { 36 OPT_INVALID = 0, 37 #define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11, _12) OPT_##ID, 38 #include "Options.inc" 39 #undef OPTION 40 }; 41 42 // Create prefix string literals used in Options.td 43 #define PREFIX(NAME, VALUE) static const char *const NAME[] = VALUE; 44 #include "Options.inc" 45 #undef PREFIX 46 47 // Create table mapping all options defined in Options.td 48 static const opt::OptTable::Info InfoTable[] = { 49 #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \ 50 {X1, X2, X10, X11, OPT_##ID, opt::Option::KIND##Class, \ 51 X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12}, 52 #include "Options.inc" 53 #undef OPTION 54 }; 55 56 namespace { 57 class MinGWOptTable : public opt::OptTable { 58 public: 59 MinGWOptTable() : OptTable(InfoTable, false) {} 60 opt::InputArgList parse(ArrayRef<const char *> Argv); 61 }; 62 } // namespace 63 64 opt::InputArgList MinGWOptTable::parse(ArrayRef<const char *> Argv) { 65 unsigned MissingIndex; 66 unsigned MissingCount; 67 68 SmallVector<const char *, 256> Vec(Argv.data(), Argv.data() + Argv.size()); 69 opt::InputArgList Args = this->ParseArgs(Vec, MissingIndex, MissingCount); 70 71 if (MissingCount) 72 fatal(StringRef(Args.getArgString(MissingIndex)) + ": missing argument"); 73 for (auto *Arg : Args.filtered(OPT_UNKNOWN)) 74 fatal("unknown argument: " + Arg->getSpelling()); 75 if (!Args.hasArg(OPT_INPUT) && !Args.hasArg(OPT_l)) 76 fatal("no input files"); 77 return Args; 78 } 79 80 // Find a file by concatenating given paths. 81 static Optional<std::string> findFile(StringRef Path1, const Twine &Path2) { 82 SmallString<128> S; 83 sys::path::append(S, Path1, Path2); 84 if (sys::fs::exists(S)) 85 return S.str().str(); 86 return None; 87 } 88 89 // This is for -lfoo. We'll look for libfoo.dll.a or libfoo.a from search paths. 90 static std::string 91 searchLibrary(StringRef Name, ArrayRef<StringRef> SearchPaths, bool BStatic) { 92 if (Name.startswith(":")) { 93 for (StringRef Dir : SearchPaths) 94 if (Optional<std::string> S = findFile(Dir, Name.substr(1))) 95 return *S; 96 fatal("unable to find library -l" + Name); 97 } 98 99 for (StringRef Dir : SearchPaths) { 100 if (!BStatic) 101 if (Optional<std::string> S = findFile(Dir, "lib" + Name + ".dll.a")) 102 return *S; 103 if (Optional<std::string> S = findFile(Dir, "lib" + Name + ".a")) 104 return *S; 105 } 106 fatal("unable to find library -l" + Name); 107 } 108 109 // Convert Unix-ish command line arguments to Windows-ish ones and 110 // then call coff::link. 111 bool mingw::link(ArrayRef<const char *> ArgsArr, raw_ostream &Diag) { 112 MinGWOptTable Parser; 113 opt::InputArgList Args = Parser.parse(ArgsArr.slice(1)); 114 115 std::vector<std::string> LinkArgs; 116 auto Add = [&](const Twine &S) { LinkArgs.push_back(S.str()); }; 117 118 Add("lld-link"); 119 Add("-lldmingw"); 120 121 if (auto *A = Args.getLastArg(OPT_entry)) { 122 StringRef S = A->getValue(); 123 if (Args.getLastArgValue(OPT_m) == "i386pe" && S.startswith("_")) 124 Add("-entry:" + S.substr(1)); 125 else 126 Add("-entry:" + S); 127 } 128 129 if (auto *A = Args.getLastArg(OPT_subs)) 130 Add("-subsystem:" + StringRef(A->getValue())); 131 if (auto *A = Args.getLastArg(OPT_out_implib)) 132 Add("-implib:" + StringRef(A->getValue())); 133 if (auto *A = Args.getLastArg(OPT_stack)) 134 Add("-stack:" + StringRef(A->getValue())); 135 if (auto *A = Args.getLastArg(OPT_output_def)) 136 Add("-output-def:" + StringRef(A->getValue())); 137 if (auto *A = Args.getLastArg(OPT_image_base)) 138 Add("-base:" + StringRef(A->getValue())); 139 if (auto *A = Args.getLastArg(OPT_map)) 140 Add("-lldmap:" + StringRef(A->getValue())); 141 142 if (auto *A = Args.getLastArg(OPT_o)) 143 Add("-out:" + StringRef(A->getValue())); 144 else if (Args.hasArg(OPT_shared)) 145 Add("-out:a.dll"); 146 else 147 Add("-out:a.exe"); 148 149 if (auto *A = Args.getLastArg(OPT_pdb)) { 150 Add("-debug"); 151 Add("-pdb:" + StringRef(A->getValue())); 152 } else if (Args.hasArg(OPT_strip_debug)) { 153 Add("-debug:symtab"); 154 } else if (!Args.hasArg(OPT_strip_all)) { 155 Add("-debug:dwarf"); 156 } 157 158 if (Args.hasArg(OPT_shared)) 159 Add("-dll"); 160 if (Args.hasArg(OPT_verbose)) 161 Add("-verbose"); 162 if (Args.hasArg(OPT_export_all_symbols)) 163 Add("-export-all-symbols"); 164 if (Args.hasArg(OPT_large_address_aware)) 165 Add("-largeaddressaware"); 166 if (Args.hasArg(OPT_kill_at)) 167 Add("-kill-at"); 168 169 if (Args.getLastArgValue(OPT_m) != "thumb2pe" && 170 Args.getLastArgValue(OPT_m) != "arm64pe" && !Args.hasArg(OPT_dynamicbase)) 171 Add("-dynamicbase:no"); 172 173 if (Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, false)) 174 Add("-opt:ref"); 175 else 176 Add("-opt:noref"); 177 178 if (auto *A = Args.getLastArg(OPT_icf)) { 179 StringRef S = A->getValue(); 180 if (S == "all") 181 Add("-opt:icf"); 182 else if (S == "safe" || S == "none") 183 Add("-opt:noicf"); 184 else 185 fatal("unknown parameter: --icf=" + S); 186 } else { 187 Add("-opt:noicf"); 188 } 189 190 if (auto *A = Args.getLastArg(OPT_m)) { 191 StringRef S = A->getValue(); 192 if (S == "i386pe") 193 Add("-machine:x86"); 194 else if (S == "i386pep") 195 Add("-machine:x64"); 196 else if (S == "thumb2pe") 197 Add("-machine:arm"); 198 else if (S == "arm64pe") 199 Add("-machine:arm64"); 200 else 201 fatal("unknown parameter: -m" + S); 202 } 203 204 for (auto *A : Args.filtered(OPT_mllvm)) 205 Add("-mllvm:" + StringRef(A->getValue())); 206 207 for (auto *A : Args.filtered(OPT_Xlink)) 208 Add(A->getValue()); 209 210 if (Args.getLastArgValue(OPT_m) == "i386pe") 211 Add("-alternatename:__image_base__=___ImageBase"); 212 else 213 Add("-alternatename:__image_base__=__ImageBase"); 214 215 for (auto *A : Args.filtered(OPT_require_defined)) 216 Add("-include:" + StringRef(A->getValue())); 217 218 std::vector<StringRef> SearchPaths; 219 for (auto *A : Args.filtered(OPT_L)) { 220 SearchPaths.push_back(A->getValue()); 221 Add("-libpath:" + StringRef(A->getValue())); 222 } 223 224 StringRef Prefix = ""; 225 bool Static = false; 226 for (auto *A : Args) { 227 switch (A->getOption().getUnaliasedOption().getID()) { 228 case OPT_INPUT: 229 if (StringRef(A->getValue()).endswith_lower(".def")) 230 Add("-def:" + StringRef(A->getValue())); 231 else 232 Add(Prefix + StringRef(A->getValue())); 233 break; 234 case OPT_l: 235 Add(Prefix + searchLibrary(A->getValue(), SearchPaths, Static)); 236 break; 237 case OPT_whole_archive: 238 Prefix = "-wholearchive:"; 239 break; 240 case OPT_no_whole_archive: 241 Prefix = ""; 242 break; 243 case OPT_Bstatic: 244 Static = true; 245 break; 246 case OPT_Bdynamic: 247 Static = false; 248 break; 249 } 250 } 251 252 if (Args.hasArg(OPT_verbose) || Args.hasArg(OPT__HASH_HASH_HASH)) 253 outs() << llvm::join(LinkArgs, " ") << "\n"; 254 255 if (Args.hasArg(OPT__HASH_HASH_HASH)) 256 return true; 257 258 // Repack vector of strings to vector of const char pointers for coff::link. 259 std::vector<const char *> Vec; 260 for (const std::string &S : LinkArgs) 261 Vec.push_back(S.c_str()); 262 return coff::link(Vec, true); 263 } 264