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 140 if (auto *A = Args.getLastArg(OPT_o)) 141 Add("-out:" + StringRef(A->getValue())); 142 else if (Args.hasArg(OPT_shared)) 143 Add("-out:a.dll"); 144 else 145 Add("-out:a.exe"); 146 147 if (Args.hasArg(OPT_shared)) 148 Add("-dll"); 149 if (Args.hasArg(OPT_verbose)) 150 Add("-verbose"); 151 if (Args.hasArg(OPT_export_all_symbols)) 152 Add("-export-all-symbols"); 153 if (!Args.hasArg(OPT_strip_all)) 154 Add("-debug:dwarf"); 155 if (Args.hasArg(OPT_large_address_aware)) 156 Add("-largeaddressaware"); 157 158 if (Args.getLastArgValue(OPT_m) != "thumb2pe" && 159 Args.getLastArgValue(OPT_m) != "arm64pe" && !Args.hasArg(OPT_dynamicbase)) 160 Add("-dynamicbase:no"); 161 162 if (Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, false)) 163 Add("-opt:ref"); 164 else 165 Add("-opt:noref"); 166 167 if (auto *A = Args.getLastArg(OPT_icf)) { 168 StringRef S = A->getValue(); 169 if (S == "all") 170 Add("-opt:icf"); 171 else if (S == "safe" || S == "none") 172 Add("-opt:noicf"); 173 else 174 fatal("unknown parameter: --icf=" + S); 175 } else { 176 Add("-opt:noicf"); 177 } 178 179 if (auto *A = Args.getLastArg(OPT_m)) { 180 StringRef S = A->getValue(); 181 if (S == "i386pe") 182 Add("-machine:x86"); 183 else if (S == "i386pep") 184 Add("-machine:x64"); 185 else if (S == "thumb2pe") 186 Add("-machine:arm"); 187 else if (S == "arm64pe") 188 Add("-machine:arm64"); 189 else 190 fatal("unknown parameter: -m" + S); 191 } 192 193 for (auto *A : Args.filtered(OPT_mllvm)) 194 Add("-mllvm:" + StringRef(A->getValue())); 195 196 for (auto *A : Args.filtered(OPT_Xlink)) 197 Add(A->getValue()); 198 199 if (Args.getLastArgValue(OPT_m) == "i386pe") 200 Add("-alternatename:__image_base__=___ImageBase"); 201 else 202 Add("-alternatename:__image_base__=__ImageBase"); 203 204 std::vector<StringRef> SearchPaths; 205 for (auto *A : Args.filtered(OPT_L)) 206 SearchPaths.push_back(A->getValue()); 207 208 StringRef Prefix = ""; 209 bool Static = false; 210 for (auto *A : Args) { 211 switch (A->getOption().getUnaliasedOption().getID()) { 212 case OPT_INPUT: 213 if (StringRef(A->getValue()).endswith_lower(".def")) 214 Add("-def:" + StringRef(A->getValue())); 215 else 216 Add(Prefix + StringRef(A->getValue())); 217 break; 218 case OPT_l: 219 Add(Prefix + searchLibrary(A->getValue(), SearchPaths, Static)); 220 break; 221 case OPT_whole_archive: 222 Prefix = "-wholearchive:"; 223 break; 224 case OPT_no_whole_archive: 225 Prefix = ""; 226 break; 227 case OPT_Bstatic: 228 Static = true; 229 break; 230 case OPT_Bdynamic: 231 Static = false; 232 break; 233 } 234 } 235 236 if (Args.hasArg(OPT_verbose) || Args.hasArg(OPT__HASH_HASH_HASH)) 237 outs() << llvm::join(LinkArgs, " ") << "\n"; 238 239 if (Args.hasArg(OPT__HASH_HASH_HASH)) 240 return true; 241 242 // Repack vector of strings to vector of const char pointers for coff::link. 243 std::vector<const char *> Vec; 244 for (const std::string &S : LinkArgs) 245 Vec.push_back(S.c_str()); 246 return coff::link(Vec, true); 247 } 248