xref: /llvm-project-15.0.7/lld/ELF/Driver.cpp (revision 45faf47e)
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 "Driver.h"
11 #include "Config.h"
12 #include "Error.h"
13 #include "InputFiles.h"
14 #include "SymbolTable.h"
15 #include "Target.h"
16 #include "Writer.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/StringExtras.h"
19 #include "llvm/Support/raw_ostream.h"
20 #include <utility>
21 
22 using namespace llvm;
23 using namespace llvm::ELF;
24 using namespace llvm::object;
25 
26 using namespace lld;
27 using namespace lld::elf2;
28 
29 Configuration *lld::elf2::Config;
30 LinkerDriver *lld::elf2::Driver;
31 
32 void lld::elf2::link(ArrayRef<const char *> Args) {
33   Configuration C;
34   LinkerDriver D;
35   Config = &C;
36   Driver = &D;
37   Driver->main(Args.slice(1));
38 }
39 
40 static std::pair<ELFKind, uint16_t> parseEmulation(StringRef S) {
41   if (S == "elf32btsmip")
42     return {ELF32BEKind, EM_MIPS};
43   if (S == "elf32ltsmip")
44     return {ELF32LEKind, EM_MIPS};
45   if (S == "elf32ppc")
46     return {ELF32BEKind, EM_PPC};
47   if (S == "elf64ppc")
48     return {ELF64BEKind, EM_PPC64};
49   if (S == "elf_i386")
50     return {ELF32LEKind, EM_386};
51   if (S == "elf_x86_64")
52     return {ELF64LEKind, EM_X86_64};
53   error("Unknown emulation: " + S);
54 }
55 
56 // Opens and parses a file. Path has to be resolved already.
57 // Newly created memory buffers are owned by this driver.
58 void LinkerDriver::addFile(StringRef Path) {
59   using namespace llvm::sys::fs;
60   if (Config->Verbose)
61     llvm::outs() << Path << "\n";
62   auto MBOrErr = MemoryBuffer::getFile(Path);
63   error(MBOrErr, "cannot open " + Path);
64   std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
65   MemoryBufferRef MBRef = MB->getMemBufferRef();
66   OwningMBs.push_back(std::move(MB)); // take MB ownership
67 
68   switch (identify_magic(MBRef.getBuffer())) {
69   case file_magic::unknown:
70     readLinkerScript(&Alloc, MBRef);
71     return;
72   case file_magic::archive:
73     if (WholeArchive) {
74       auto File = make_unique<ArchiveFile>(MBRef);
75       for (MemoryBufferRef &MB : File->getMembers())
76         Files.push_back(createELFFile<ObjectFile>(MB));
77       OwningArchives.emplace_back(std::move(File));
78       return;
79     }
80     Files.push_back(make_unique<ArchiveFile>(MBRef));
81     return;
82   case file_magic::elf_shared_object:
83     Files.push_back(createELFFile<SharedFile>(MBRef));
84     return;
85   default:
86     Files.push_back(createELFFile<ObjectFile>(MBRef));
87   }
88 }
89 
90 static StringRef
91 getString(opt::InputArgList &Args, unsigned Key, StringRef Default = "") {
92   if (auto *Arg = Args.getLastArg(Key))
93     return Arg->getValue();
94   return Default;
95 }
96 
97 void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {
98   initSymbols();
99 
100   opt::InputArgList Args = parseArgs(&Alloc, ArgsArr);
101   createFiles(Args);
102 
103   switch (Config->EKind) {
104   case ELF32LEKind:
105     link<ELF32LE>(Args);
106     return;
107   case ELF32BEKind:
108     link<ELF32BE>(Args);
109     return;
110   case ELF64LEKind:
111     link<ELF64LE>(Args);
112     return;
113   case ELF64BEKind:
114     link<ELF64BE>(Args);
115     return;
116   default:
117     error("-m or at least a .o file required");
118   }
119 }
120 
121 void LinkerDriver::createFiles(opt::InputArgList &Args) {
122   for (auto *Arg : Args.filtered(OPT_L))
123     Config->SearchPaths.push_back(Arg->getValue());
124 
125   std::vector<StringRef> RPaths;
126   for (auto *Arg : Args.filtered(OPT_rpath))
127     RPaths.push_back(Arg->getValue());
128   if (!RPaths.empty())
129     Config->RPath = llvm::join(RPaths.begin(), RPaths.end(), ":");
130 
131   if (auto *Arg = Args.getLastArg(OPT_m)) {
132     StringRef S = Arg->getValue();
133     std::pair<ELFKind, uint16_t> P = parseEmulation(S);
134     Config->EKind = P.first;
135     Config->EMachine = P.second;
136     Config->Emulation = S;
137   }
138 
139   Config->AllowMultipleDefinition = Args.hasArg(OPT_allow_multiple_definition);
140   Config->Bsymbolic = Args.hasArg(OPT_Bsymbolic);
141   Config->DiscardAll = Args.hasArg(OPT_discard_all);
142   Config->DiscardLocals = Args.hasArg(OPT_discard_locals);
143   Config->DiscardNone = Args.hasArg(OPT_discard_none);
144   Config->EnableNewDtags = !Args.hasArg(OPT_disable_new_dtags);
145   Config->ExportDynamic = Args.hasArg(OPT_export_dynamic);
146   Config->GcSections = Args.hasArg(OPT_gc_sections);
147   Config->NoInhibitExec = Args.hasArg(OPT_noinhibit_exec);
148   Config->NoUndefined = Args.hasArg(OPT_no_undefined);
149   Config->Shared = Args.hasArg(OPT_shared);
150   Config->StripAll = Args.hasArg(OPT_strip_all);
151   Config->Verbose = Args.hasArg(OPT_verbose);
152 
153   Config->DynamicLinker = getString(Args, OPT_dynamic_linker);
154   Config->Entry = getString(Args, OPT_entry);
155   Config->Fini = getString(Args, OPT_fini, "_fini");
156   Config->Init = getString(Args, OPT_init, "_init");
157   Config->OutputFile = getString(Args, OPT_o);
158   Config->SoName = getString(Args, OPT_soname);
159   Config->Sysroot = getString(Args, OPT_sysroot);
160 
161   if (auto *Arg = Args.getLastArg(OPT_O)) {
162     StringRef Val = Arg->getValue();
163     if (Val.getAsInteger(10, Config->Optimize))
164       error("Invalid optimization level");
165   }
166 
167   if (auto *Arg = Args.getLastArg(OPT_hash_style)) {
168     StringRef S = Arg->getValue();
169     if (S == "gnu") {
170       Config->GnuHash = true;
171       Config->SysvHash = false;
172     } else if (S == "both") {
173       Config->GnuHash = true;
174     } else if (S != "sysv")
175       error("Unknown hash style: " + S);
176   }
177 
178   for (auto *Arg : Args.filtered(OPT_undefined))
179     Config->Undefined.push_back(Arg->getValue());
180 
181   for (auto *Arg : Args.filtered(OPT_z)) {
182     StringRef S = Arg->getValue();
183     if (S == "nodelete")
184       Config->ZNodelete = true;
185     else if (S == "now")
186       Config->ZNow = true;
187     else if (S == "origin")
188       Config->ZOrigin = true;
189   }
190 
191   for (auto *Arg : Args) {
192     switch (Arg->getOption().getID()) {
193     case OPT_l:
194       addFile(searchLibrary(Arg->getValue()));
195       break;
196     case OPT_INPUT:
197     case OPT_script:
198       addFile(Arg->getValue());
199       break;
200     case OPT_as_needed:
201       Config->AsNeeded = true;
202       break;
203     case OPT_no_as_needed:
204       Config->AsNeeded = false;
205       break;
206     case OPT_Bstatic:
207       Config->Static = true;
208       break;
209     case OPT_Bdynamic:
210       Config->Static = false;
211       break;
212     case OPT_whole_archive:
213       WholeArchive = true;
214       break;
215     case OPT_no_whole_archive:
216       WholeArchive = false;
217       break;
218     }
219   }
220 
221   if (Files.empty())
222     error("no input files.");
223 }
224 
225 template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
226   SymbolTable<ELFT> Symtab;
227   Target.reset(createTarget());
228 
229   if (!Config->Shared) {
230     // Add entry symbol.
231     if (Config->Entry.empty())
232       Config->Entry = (Config->EMachine == EM_MIPS) ? "__start" : "_start";
233 
234     // Set either EntryAddr (if S is a number) or EntrySym (otherwise).
235     StringRef S = Config->Entry;
236     if (S.getAsInteger(0, Config->EntryAddr))
237       Config->EntrySym = Symtab.addUndefined(S);
238 
239     // In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol
240     // is magical and is used to produce a R_386_GOTPC relocation.
241     // The R_386_GOTPC relocation value doesn't actually depend on the
242     // symbol value, so it could use an index of STN_UNDEF which, according
243     // to the spec, means the symbol value is 0.
244     // Unfortunately both gas and MC keep the _GLOBAL_OFFSET_TABLE_ symbol in
245     // the object file.
246     // The situation is even stranger on x86_64 where the assembly doesn't
247     // need the magical symbol, but gas still puts _GLOBAL_OFFSET_TABLE_ as
248     // an undefined symbol in the .o files.
249     // Given that the symbol is effectively unused, we just create a dummy
250     // hidden one to avoid the undefined symbol error.
251     Symtab.addIgnoredSym("_GLOBAL_OFFSET_TABLE_");
252   }
253 
254   for (std::unique_ptr<InputFile> &F : Files)
255     Symtab.addFile(std::move(F));
256 
257   for (StringRef S : Config->Undefined)
258     Symtab.addUndefinedOpt(S);
259 
260   if (Config->OutputFile.empty())
261     Config->OutputFile = "a.out";
262 
263   // Write the result to the file.
264   Symtab.scanShlibUndefined();
265   if (Config->GcSections)
266     markLive<ELFT>(&Symtab);
267   writeResult<ELFT>(&Symtab);
268 }
269