xref: /llvm-project-15.0.7/lld/COFF/Driver.cpp (revision 95213c31)
1 //===- 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 #include "Config.h"
11 #include "Driver.h"
12 #include "InputFiles.h"
13 #include "Memory.h"
14 #include "SymbolTable.h"
15 #include "Writer.h"
16 #include "llvm/ADT/Optional.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/LibDriver/LibDriver.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/Debug.h"
25 #include "llvm/Support/Path.h"
26 #include "llvm/Support/Process.h"
27 #include "llvm/Support/TargetSelect.h"
28 #include "llvm/Support/raw_ostream.h"
29 #include <memory>
30 
31 using namespace llvm;
32 using llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN;
33 using llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI;
34 using llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_GUI;
35 using llvm::sys::Process;
36 using llvm::sys::fs::file_magic;
37 using llvm::sys::fs::identify_magic;
38 
39 namespace lld {
40 namespace coff {
41 
42 Configuration *Config;
43 LinkerDriver *Driver;
44 
45 bool link(int Argc, const char *Argv[]) {
46   auto C = make_unique<Configuration>();
47   Config = C.get();
48   auto D = make_unique<LinkerDriver>();
49   Driver = D.get();
50   return Driver->link(Argc, Argv);
51 }
52 
53 // Drop directory components and replace extension with ".exe".
54 static std::string getOutputPath(StringRef Path) {
55   auto P = Path.find_last_of("\\/");
56   StringRef S = (P == StringRef::npos) ? Path : Path.substr(P + 1);
57   return (S.substr(0, S.rfind('.')) + ".exe").str();
58 }
59 
60 // Opens a file. Path has to be resolved already.
61 // Newly created memory buffers are owned by this driver.
62 ErrorOr<std::unique_ptr<InputFile>> LinkerDriver::openFile(StringRef Path) {
63   auto MBOrErr = MemoryBuffer::getFile(Path);
64   if (auto EC = MBOrErr.getError())
65     return EC;
66   std::unique_ptr<MemoryBuffer> MB = std::move(MBOrErr.get());
67   MemoryBufferRef MBRef = MB->getMemBufferRef();
68   OwningMBs.push_back(std::move(MB)); // take ownership
69 
70   // File type is detected by contents, not by file extension.
71   file_magic Magic = identify_magic(MBRef.getBuffer());
72   if (Magic == file_magic::archive)
73     return std::unique_ptr<InputFile>(new ArchiveFile(MBRef));
74   if (Magic == file_magic::bitcode)
75     return std::unique_ptr<InputFile>(new BitcodeFile(MBRef));
76   if (Config->OutputFile == "")
77     Config->OutputFile = getOutputPath(Path);
78   return std::unique_ptr<InputFile>(new ObjectFile(MBRef));
79 }
80 
81 // Parses .drectve section contents and returns a list of files
82 // specified by /defaultlib.
83 std::error_code
84 LinkerDriver::parseDirectives(StringRef S,
85                               std::vector<std::unique_ptr<InputFile>> *Res) {
86   auto ArgsOrErr = Parser.parse(S);
87   if (auto EC = ArgsOrErr.getError())
88     return EC;
89   std::unique_ptr<llvm::opt::InputArgList> Args = std::move(ArgsOrErr.get());
90 
91   // Handle /failifmismatch
92   if (auto EC = checkFailIfMismatch(Args.get()))
93     return EC;
94 
95   // Handle /defaultlib
96   for (auto *Arg : Args->filtered(OPT_defaultlib)) {
97     if (Optional<StringRef> Path = findLib(Arg->getValue())) {
98       auto FileOrErr = openFile(*Path);
99       if (auto EC = FileOrErr.getError())
100         return EC;
101       std::unique_ptr<InputFile> File = std::move(FileOrErr.get());
102       Res->push_back(std::move(File));
103     }
104   }
105   return std::error_code();
106 }
107 
108 // Find file from search paths. You can omit ".obj", this function takes
109 // care of that. Note that the returned path is not guaranteed to exist.
110 StringRef LinkerDriver::doFindFile(StringRef Filename) {
111   bool hasPathSep = (Filename.find_first_of("/\\") != StringRef::npos);
112   if (hasPathSep)
113     return Filename;
114   bool hasExt = (Filename.find('.') != StringRef::npos);
115   for (StringRef Dir : SearchPaths) {
116     SmallString<128> Path = Dir;
117     llvm::sys::path::append(Path, Filename);
118     if (llvm::sys::fs::exists(Path.str()))
119       return Alloc.save(Path.str());
120     if (!hasExt) {
121       Path.append(".obj");
122       if (llvm::sys::fs::exists(Path.str()))
123         return Alloc.save(Path.str());
124     }
125   }
126   return Filename;
127 }
128 
129 // Resolves a file path. This never returns the same path
130 // (in that case, it returns None).
131 Optional<StringRef> LinkerDriver::findFile(StringRef Filename) {
132   StringRef Path = doFindFile(Filename);
133   bool Seen = !VisitedFiles.insert(Path.lower()).second;
134   if (Seen)
135     return None;
136   return Path;
137 }
138 
139 // Find library file from search path.
140 StringRef LinkerDriver::doFindLib(StringRef Filename) {
141   // Add ".lib" to Filename if that has no file extension.
142   bool hasExt = (Filename.find('.') != StringRef::npos);
143   if (!hasExt)
144     Filename = Alloc.save(Filename + ".lib");
145   return doFindFile(Filename);
146 }
147 
148 // Resolves a library path. /nodefaultlib options are taken into
149 // consideration. This never returns the same path (in that case,
150 // it returns None).
151 Optional<StringRef> LinkerDriver::findLib(StringRef Filename) {
152   if (Config->NoDefaultLibAll)
153     return None;
154   StringRef Path = doFindLib(Filename);
155   if (Config->NoDefaultLibs.count(Path))
156     return None;
157   bool Seen = !VisitedFiles.insert(Path.lower()).second;
158   if (Seen)
159     return None;
160   return Path;
161 }
162 
163 // Parses LIB environment which contains a list of search paths.
164 std::vector<StringRef> LinkerDriver::getSearchPaths() {
165   std::vector<StringRef> Ret;
166   // Add current directory as first item of the search paths.
167   Ret.push_back("");
168   Optional<std::string> EnvOpt = Process::GetEnv("LIB");
169   if (!EnvOpt.hasValue())
170     return Ret;
171   StringRef Env = Alloc.save(*EnvOpt);
172   while (!Env.empty()) {
173     StringRef Path;
174     std::tie(Path, Env) = Env.split(';');
175     Ret.push_back(Path);
176   }
177   return Ret;
178 }
179 
180 bool LinkerDriver::link(int Argc, const char *Argv[]) {
181   // Needed for LTO.
182   llvm::InitializeAllTargetInfos();
183   llvm::InitializeAllTargets();
184   llvm::InitializeAllTargetMCs();
185   llvm::InitializeAllAsmParsers();
186   llvm::InitializeAllAsmPrinters();
187   llvm::InitializeAllDisassemblers();
188 
189   // If the first command line argument is "/lib", link.exe acts like lib.exe.
190   // We call our own implementation of lib.exe that understands bitcode files.
191   if (Argc > 1 && StringRef(Argv[1]).equals_lower("/lib"))
192     return llvm::libDriverMain(Argc - 1, Argv + 1) == 0;
193 
194   // Parse command line options.
195   auto ArgsOrErr = Parser.parse(Argc, Argv);
196   if (auto EC = ArgsOrErr.getError()) {
197     llvm::errs() << EC.message() << "\n";
198     return false;
199   }
200   std::unique_ptr<llvm::opt::InputArgList> Args = std::move(ArgsOrErr.get());
201 
202   // Handle /help
203   if (Args->hasArg(OPT_help)) {
204     printHelp(Argv[0]);
205     return true;
206   }
207 
208   if (Args->filtered_begin(OPT_INPUT) == Args->filtered_end()) {
209     llvm::errs() << "no input files.\n";
210     return false;
211   }
212 
213   // Handle /out
214   if (auto *Arg = Args->getLastArg(OPT_out))
215     Config->OutputFile = Arg->getValue();
216 
217   // Handle /verbose
218   if (Args->hasArg(OPT_verbose))
219     Config->Verbose = true;
220 
221   // Handle /entry
222   if (auto *Arg = Args->getLastArg(OPT_entry))
223     Config->EntryName = Arg->getValue();
224 
225   // Handle /machine
226   auto MTOrErr = getMachineType(Args.get());
227   if (auto EC = MTOrErr.getError()) {
228     llvm::errs() << EC.message() << "\n";
229     return false;
230   }
231   Config->MachineType = MTOrErr.get();
232 
233   // Handle /libpath
234   for (auto *Arg : Args->filtered(OPT_libpath)) {
235     // Inserting at front of a vector is okay because it's short.
236     // +1 because the first entry is always "." (current directory).
237     SearchPaths.insert(SearchPaths.begin() + 1, Arg->getValue());
238   }
239 
240   // Handle /nodefaultlib:<filename>
241   for (auto *Arg : Args->filtered(OPT_nodefaultlib))
242     Config->NoDefaultLibs.insert(doFindLib(Arg->getValue()));
243 
244   // Handle /nodefaultlib
245   if (Args->hasArg(OPT_nodefaultlib_all))
246     Config->NoDefaultLibAll = true;
247 
248   // Handle /base
249   if (auto *Arg = Args->getLastArg(OPT_base)) {
250     if (auto EC = parseNumbers(Arg->getValue(), &Config->ImageBase)) {
251       llvm::errs() << "/base: " << EC.message() << "\n";
252       return false;
253     }
254   }
255 
256   // Handle /stack
257   if (auto *Arg = Args->getLastArg(OPT_stack)) {
258     if (auto EC = parseNumbers(Arg->getValue(), &Config->StackReserve,
259                                &Config->StackCommit)) {
260       llvm::errs() << "/stack: " << EC.message() << "\n";
261       return false;
262     }
263   }
264 
265   // Handle /heap
266   if (auto *Arg = Args->getLastArg(OPT_heap)) {
267     if (auto EC = parseNumbers(Arg->getValue(), &Config->HeapReserve,
268                                &Config->HeapCommit)) {
269       llvm::errs() << "/heap: " << EC.message() << "\n";
270       return false;
271     }
272   }
273 
274   // Handle /version
275   if (auto *Arg = Args->getLastArg(OPT_version)) {
276     if (auto EC = parseVersion(Arg->getValue(), &Config->MajorImageVersion,
277                                &Config->MinorImageVersion)) {
278       llvm::errs() << "/version: " << EC.message() << "\n";
279       return false;
280     }
281   }
282 
283   // Handle /subsystem
284   if (auto *Arg = Args->getLastArg(OPT_subsystem)) {
285     if (auto EC = parseSubsystem(Arg->getValue(), &Config->Subsystem,
286                                  &Config->MajorOSVersion,
287                                  &Config->MinorOSVersion)) {
288       llvm::errs() << "/subsystem: " << EC.message() << "\n";
289       return false;
290     }
291   }
292 
293   // Handle /opt
294   for (auto *Arg : Args->filtered(OPT_opt)) {
295     std::string S = StringRef(Arg->getValue()).lower();
296     if (S == "noref") {
297       Config->DoGC = false;
298       continue;
299     }
300     if (S != "ref" && S != "icf" && S != "noicf" &&
301         S != "lbr" && S != "nolbr" &&
302         !StringRef(S).startswith("icf=")) {
303       llvm::errs() << "/opt: unknown option: " << S << "\n";
304       return false;
305     }
306   }
307 
308   // Handle /failifmismatch
309   if (auto EC = checkFailIfMismatch(Args.get())) {
310     llvm::errs() << "/failifmismatch: " << EC.message() << "\n";
311     return false;
312   }
313 
314   // Create a list of input files. Files can be given as arguments
315   // for /defaultlib option.
316   std::vector<StringRef> Inputs;
317   for (auto *Arg : Args->filtered(OPT_INPUT))
318     if (Optional<StringRef> Path = findFile(Arg->getValue()))
319       Inputs.push_back(*Path);
320   for (auto *Arg : Args->filtered(OPT_defaultlib))
321     if (Optional<StringRef> Path = findLib(Arg->getValue()))
322       Inputs.push_back(*Path);
323 
324   // Create a symbol table.
325   SymbolTable Symtab;
326 
327   // Add undefined symbols given via the command line.
328   // (/include is equivalent to Unix linker's -u option.)
329   for (auto *Arg : Args->filtered(OPT_incl)) {
330     StringRef Sym = Arg->getValue();
331     Symtab.addUndefined(Sym);
332     Config->GCRoots.insert(Sym);
333   }
334 
335   // Parse all input files and put all symbols to the symbol table.
336   // The symbol table will take care of name resolution.
337   for (StringRef Path : Inputs) {
338     auto FileOrErr = openFile(Path);
339     if (auto EC = FileOrErr.getError()) {
340       llvm::errs() << Path << ": " << EC.message() << "\n";
341       return false;
342     }
343     std::unique_ptr<InputFile> File = std::move(FileOrErr.get());
344     if (Config->Verbose)
345       llvm::outs() << "Reading " << File->getName() << "\n";
346     if (auto EC = Symtab.addFile(std::move(File))) {
347       llvm::errs() << Path << ": " << EC.message() << "\n";
348       return false;
349     }
350   }
351 
352   // Add weak aliases. Weak aliases is a mechanism to give remaining
353   // undefined symbols final chance to be resolved successfully.
354   // This is symbol renaming.
355   for (auto *Arg : Args->filtered(OPT_alternatename)) {
356     // Parse a string of the form of "/alternatename:From=To".
357     StringRef From, To;
358     std::tie(From, To) = StringRef(Arg->getValue()).split('=');
359     if (From.empty() || To.empty()) {
360       llvm::errs() << "/alternatename: invalid argument: "
361                    << Arg->getValue() << "\n";
362       return false;
363     }
364     // If From is already resolved to a Defined type, do nothing.
365     // Otherwise, rename it to see if To can be resolved instead.
366     if (Symtab.find(From))
367       continue;
368     if (auto EC = Symtab.rename(From, To)) {
369       llvm::errs() << EC.message() << "\n";
370       return false;
371     }
372   }
373 
374   // Windows specific -- If entry point name is not given, we need to
375   // infer that from user-defined entry name. The symbol table takes
376   // care of details.
377   if (Config->EntryName.empty()) {
378     auto EntryOrErr = Symtab.findDefaultEntry();
379     if (auto EC = EntryOrErr.getError()) {
380       llvm::errs() << EC.message() << "\n";
381       return false;
382     }
383     Config->EntryName = EntryOrErr.get();
384   }
385   Config->GCRoots.insert(Config->EntryName);
386 
387   // Make sure we have resolved all symbols.
388   if (Symtab.reportRemainingUndefines())
389     return false;
390 
391   // Do LTO by compiling bitcode input files to a native COFF file
392   // then link that file.
393   if (auto EC = Symtab.addCombinedLTOObject()) {
394     llvm::errs() << EC.message() << "\n";
395     return false;
396   }
397 
398   // Windows specific -- if no /subsystem is given, we need to infer
399   // that from entry point name.
400   if (Config->Subsystem == IMAGE_SUBSYSTEM_UNKNOWN) {
401     Config->Subsystem =
402       StringSwitch<WindowsSubsystem>(Config->EntryName)
403           .Case("mainCRTStartup", IMAGE_SUBSYSTEM_WINDOWS_CUI)
404           .Case("wmainCRTStartup", IMAGE_SUBSYSTEM_WINDOWS_CUI)
405           .Case("WinMainCRTStartup", IMAGE_SUBSYSTEM_WINDOWS_GUI)
406           .Case("wWinMainCRTStartup", IMAGE_SUBSYSTEM_WINDOWS_GUI)
407           .Default(IMAGE_SUBSYSTEM_UNKNOWN);
408     if (Config->Subsystem == IMAGE_SUBSYSTEM_UNKNOWN) {
409       llvm::errs() << "subsystem must be defined\n";
410       return false;
411     }
412   }
413 
414   // Write the result.
415   Writer Out(&Symtab);
416   if (auto EC = Out.write(Config->OutputFile)) {
417     llvm::errs() << EC.message() << "\n";
418     return false;
419   }
420   return true;
421 }
422 
423 } // namespace coff
424 } // namespace lld
425