]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lld/COFF/Librarian.cpp
Update llvm, clang, lld and lldb to release_39 branch r288513.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lld / COFF / Librarian.cpp
1 //===- Librarian.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 // This file contains functions for the Librarian.  The librarian creates and
11 // manages libraries of the Common Object File Format (COFF) object files.  It
12 // primarily is used for creating static libraries and import libraries.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #include "Config.h"
17 #include "Driver.h"
18 #include "Error.h"
19 #include "Symbols.h"
20 #include "llvm/Object/Archive.h"
21 #include "llvm/Object/ArchiveWriter.h"
22 #include "llvm/Object/COFF.h"
23 #include "llvm/Support/Path.h"
24
25 #include <vector>
26
27 using namespace lld::coff;
28 using namespace llvm::COFF;
29 using namespace llvm::object;
30 using namespace llvm;
31
32 static bool is32bit() {
33   switch (Config->Machine) {
34   default:
35     llvm_unreachable("unsupported machine");
36   case IMAGE_FILE_MACHINE_AMD64:
37     return false;
38   case IMAGE_FILE_MACHINE_ARMNT:
39   case IMAGE_FILE_MACHINE_I386:
40     return true;
41   }
42 }
43
44 static uint16_t getImgRelRelocation() {
45   switch (Config->Machine) {
46   default:
47     llvm_unreachable("unsupported machine");
48   case IMAGE_FILE_MACHINE_AMD64:
49     return IMAGE_REL_AMD64_ADDR32NB;
50   case IMAGE_FILE_MACHINE_ARMNT:
51     return IMAGE_REL_ARM_ADDR32NB;
52   case IMAGE_FILE_MACHINE_I386:
53     return IMAGE_REL_I386_DIR32NB;
54   }
55 }
56
57 template <class T> void append(std::vector<uint8_t> &B, const T &Data) {
58   size_t S = B.size();
59   B.resize(S + sizeof(T));
60   memcpy(&B[S], &Data, sizeof(T));
61 }
62
63 static void writeStringTable(std::vector<uint8_t> &B,
64                              ArrayRef<const std::string> Strings) {
65   // The COFF string table consists of a 4-byte value which is the size of the
66   // table, including the length field itself.  This value is followed by the
67   // string content itself, which is an array of null-terminated C-style
68   // strings.  The termination is important as they are referenced to by offset
69   // by the symbol entity in the file format.
70
71   std::vector<uint8_t>::size_type Pos = B.size();
72   std::vector<uint8_t>::size_type Offset = B.size();
73
74   // Skip over the length field, we will fill it in later as we will have
75   // computed the length while emitting the string content itself.
76   Pos += sizeof(uint32_t);
77
78   for (const auto &S : Strings) {
79     B.resize(Pos + S.length() + 1);
80     strcpy(reinterpret_cast<char *>(&B[Pos]), S.c_str());
81     Pos += S.length() + 1;
82   }
83
84   // Backfill the length of the table now that it has been computed.
85   support::ulittle32_t Length(B.size() - Offset);
86   memcpy(&B[Offset], &Length, sizeof(Length));
87 }
88
89 static std::string getImplibPath() {
90   if (!Config->Implib.empty())
91     return Config->Implib;
92   SmallString<128> Out = StringRef(Config->OutputFile);
93   sys::path::replace_extension(Out, ".lib");
94   return Out.str();
95 }
96
97 static ImportNameType getNameType(StringRef Sym, StringRef ExtName) {
98   if (Sym != ExtName)
99     return IMPORT_NAME_UNDECORATE;
100   if (Config->Machine == I386 && Sym.startswith("_"))
101     return IMPORT_NAME_NOPREFIX;
102   return IMPORT_NAME;
103 }
104
105 static std::string replace(StringRef S, StringRef From, StringRef To) {
106   size_t Pos = S.find(From);
107   assert(Pos != StringRef::npos);
108   return (Twine(S.substr(0, Pos)) + To + S.substr(Pos + From.size())).str();
109 }
110
111 static const std::string NullImportDescriptorSymbolName =
112     "__NULL_IMPORT_DESCRIPTOR";
113
114 namespace {
115 // This class constructs various small object files necessary to support linking
116 // symbols imported from a DLL.  The contents are pretty strictly defined and
117 // nearly entirely static.  The details of the structures files are defined in
118 // WINNT.h and the PE/COFF specification.
119 class ObjectFactory {
120   using u16 = support::ulittle16_t;
121   using u32 = support::ulittle32_t;
122
123   BumpPtrAllocator Alloc;
124   StringRef DLLName;
125   StringRef Library;
126   std::string ImportDescriptorSymbolName;
127   std::string NullThunkSymbolName;
128
129 public:
130   ObjectFactory(StringRef S)
131       : DLLName(S), Library(S.drop_back(4)),
132         ImportDescriptorSymbolName(("__IMPORT_DESCRIPTOR_" + Library).str()),
133         NullThunkSymbolName(("\x7f" + Library + "_NULL_THUNK_DATA").str()) {}
134
135   // Creates an Import Descriptor.  This is a small object file which contains a
136   // reference to the terminators and contains the library name (entry) for the
137   // import name table.  It will force the linker to construct the necessary
138   // structure to import symbols from the DLL.
139   NewArchiveMember createImportDescriptor(std::vector<uint8_t> &Buffer);
140
141   // Creates a NULL import descriptor.  This is a small object file whcih
142   // contains a NULL import descriptor.  It is used to terminate the imports
143   // from a specific DLL.
144   NewArchiveMember createNullImportDescriptor(std::vector<uint8_t> &Buffer);
145
146   // Create a NULL Thunk Entry.  This is a small object file which contains a
147   // NULL Import Address Table entry and a NULL Import Lookup Table Entry.  It
148   // is used to terminate the IAT and ILT.
149   NewArchiveMember createNullThunk(std::vector<uint8_t> &Buffer);
150
151   // Create a short import file which is described in PE/COFF spec 7. Import
152   // Library Format.
153   NewArchiveMember createShortImport(StringRef Sym, uint16_t Ordinal,
154                                      ImportNameType NameType, bool isData);
155 };
156 }
157
158 NewArchiveMember
159 ObjectFactory::createImportDescriptor(std::vector<uint8_t> &Buffer) {
160   static const uint32_t NumberOfSections = 2;
161   static const uint32_t NumberOfSymbols = 7;
162   static const uint32_t NumberOfRelocations = 3;
163
164   // COFF Header
165   coff_file_header Header{
166       u16(Config->Machine), u16(NumberOfSections), u32(0),
167       u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section)) +
168           // .idata$2
169           sizeof(coff_import_directory_table_entry) +
170           NumberOfRelocations * sizeof(coff_relocation) +
171           // .idata$4
172           (DLLName.size() + 1)),
173       u32(NumberOfSymbols), u16(0),
174       u16(is32bit() ? IMAGE_FILE_32BIT_MACHINE : 0),
175   };
176   append(Buffer, Header);
177
178   // Section Header Table
179   static const coff_section SectionTable[NumberOfSections] = {
180       {{'.', 'i', 'd', 'a', 't', 'a', '$', '2'},
181        u32(0),
182        u32(0),
183        u32(sizeof(coff_import_directory_table_entry)),
184        u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section)),
185        u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section) +
186            sizeof(coff_import_directory_table_entry)),
187        u32(0),
188        u16(NumberOfRelocations),
189        u16(0),
190        u32(IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_CNT_INITIALIZED_DATA |
191            IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE)},
192       {{'.', 'i', 'd', 'a', 't', 'a', '$', '6'},
193        u32(0),
194        u32(0),
195        u32(DLLName.size() + 1),
196        u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section) +
197            sizeof(coff_import_directory_table_entry) +
198            NumberOfRelocations * sizeof(coff_relocation)),
199        u32(0),
200        u32(0),
201        u16(0),
202        u16(0),
203        u32(IMAGE_SCN_ALIGN_2BYTES | IMAGE_SCN_CNT_INITIALIZED_DATA |
204            IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE)},
205   };
206   append(Buffer, SectionTable);
207
208   // .idata$2
209   static const coff_import_directory_table_entry ImportDescriptor{
210       u32(0), u32(0), u32(0), u32(0), u32(0),
211   };
212   append(Buffer, ImportDescriptor);
213
214   static const coff_relocation RelocationTable[NumberOfRelocations] = {
215       {u32(offsetof(coff_import_directory_table_entry, NameRVA)), u32(2),
216        u16(getImgRelRelocation())},
217       {u32(offsetof(coff_import_directory_table_entry, ImportLookupTableRVA)),
218        u32(3), u16(getImgRelRelocation())},
219       {u32(offsetof(coff_import_directory_table_entry, ImportAddressTableRVA)),
220        u32(4), u16(getImgRelRelocation())},
221   };
222   append(Buffer, RelocationTable);
223
224   // .idata$6
225   auto S = Buffer.size();
226   Buffer.resize(S + DLLName.size() + 1);
227   memcpy(&Buffer[S], DLLName.data(), DLLName.size());
228   Buffer[S + DLLName.size()] = '\0';
229
230   // Symbol Table
231   coff_symbol16 SymbolTable[NumberOfSymbols] = {
232       {{{0, 0, 0, 0, 0, 0, 0, 0}},
233        u32(0),
234        u16(1),
235        u16(0),
236        IMAGE_SYM_CLASS_EXTERNAL,
237        0},
238       {{{'.', 'i', 'd', 'a', 't', 'a', '$', '2'}},
239        u32(0),
240        u16(1),
241        u16(0),
242        IMAGE_SYM_CLASS_SECTION,
243        0},
244       {{{'.', 'i', 'd', 'a', 't', 'a', '$', '6'}},
245        u32(0),
246        u16(2),
247        u16(0),
248        IMAGE_SYM_CLASS_STATIC,
249        0},
250       {{{'.', 'i', 'd', 'a', 't', 'a', '$', '4'}},
251        u32(0),
252        u16(0),
253        u16(0),
254        IMAGE_SYM_CLASS_SECTION,
255        0},
256       {{{'.', 'i', 'd', 'a', 't', 'a', '$', '5'}},
257        u32(0),
258        u16(0),
259        u16(0),
260        IMAGE_SYM_CLASS_SECTION,
261        0},
262       {{{0, 0, 0, 0, 0, 0, 0, 0}},
263        u32(0),
264        u16(0),
265        u16(0),
266        IMAGE_SYM_CLASS_EXTERNAL,
267        0},
268       {{{0, 0, 0, 0, 0, 0, 0, 0}},
269        u32(0),
270        u16(0),
271        u16(0),
272        IMAGE_SYM_CLASS_EXTERNAL,
273        0},
274   };
275   reinterpret_cast<StringTableOffset &>(SymbolTable[0].Name).Offset =
276       sizeof(uint32_t);
277   reinterpret_cast<StringTableOffset &>(SymbolTable[5].Name).Offset =
278       sizeof(uint32_t) + ImportDescriptorSymbolName.length() + 1;
279   reinterpret_cast<StringTableOffset &>(SymbolTable[6].Name).Offset =
280       sizeof(uint32_t) + ImportDescriptorSymbolName.length() + 1 +
281       NullImportDescriptorSymbolName.length() + 1;
282   append(Buffer, SymbolTable);
283
284   // String Table
285   writeStringTable(Buffer,
286                    {ImportDescriptorSymbolName, NullImportDescriptorSymbolName,
287                     NullThunkSymbolName});
288
289   StringRef F{reinterpret_cast<const char *>(Buffer.data()), Buffer.size()};
290   return {MemoryBufferRef(F, DLLName)};
291 }
292
293 NewArchiveMember
294 ObjectFactory::createNullImportDescriptor(std::vector<uint8_t> &Buffer) {
295   static const uint32_t NumberOfSections = 1;
296   static const uint32_t NumberOfSymbols = 1;
297
298   // COFF Header
299   coff_file_header Header{
300       u16(Config->Machine), u16(NumberOfSections), u32(0),
301       u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section)) +
302           // .idata$3
303           sizeof(coff_import_directory_table_entry)),
304       u32(NumberOfSymbols), u16(0),
305       u16(is32bit() ? IMAGE_FILE_32BIT_MACHINE : 0),
306   };
307   append(Buffer, Header);
308
309   // Section Header Table
310   static const coff_section SectionTable[NumberOfSections] = {
311       {{'.', 'i', 'd', 'a', 't', 'a', '$', '3'},
312        u32(0),
313        u32(0),
314        u32(sizeof(coff_import_directory_table_entry)),
315        u32(sizeof(coff_file_header) +
316            (NumberOfSections * sizeof(coff_section))),
317        u32(0),
318        u32(0),
319        u16(0),
320        u16(0),
321        u32(IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_CNT_INITIALIZED_DATA |
322            IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE)},
323   };
324   append(Buffer, SectionTable);
325
326   // .idata$3
327   static const coff_import_directory_table_entry ImportDescriptor{
328       u32(0), u32(0), u32(0), u32(0), u32(0),
329   };
330   append(Buffer, ImportDescriptor);
331
332   // Symbol Table
333   coff_symbol16 SymbolTable[NumberOfSymbols] = {
334       {{{0, 0, 0, 0, 0, 0, 0, 0}},
335        u32(0),
336        u16(1),
337        u16(0),
338        IMAGE_SYM_CLASS_EXTERNAL,
339        0},
340   };
341   reinterpret_cast<StringTableOffset &>(SymbolTable[0].Name).Offset =
342       sizeof(uint32_t);
343   append(Buffer, SymbolTable);
344
345   // String Table
346   writeStringTable(Buffer, {NullImportDescriptorSymbolName});
347
348   StringRef F{reinterpret_cast<const char *>(Buffer.data()), Buffer.size()};
349   return {MemoryBufferRef(F, DLLName)};
350 }
351
352 NewArchiveMember ObjectFactory::createNullThunk(std::vector<uint8_t> &Buffer) {
353   static const uint32_t NumberOfSections = 2;
354   static const uint32_t NumberOfSymbols = 1;
355
356   // COFF Header
357   coff_file_header Header{
358       u16(Config->Machine), u16(NumberOfSections), u32(0),
359       u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section)) +
360           // .idata$5
361           sizeof(export_address_table_entry) +
362           // .idata$4
363           sizeof(export_address_table_entry)),
364       u32(NumberOfSymbols), u16(0),
365       u16(is32bit() ? IMAGE_FILE_32BIT_MACHINE : 0),
366   };
367   append(Buffer, Header);
368
369   // Section Header Table
370   static const coff_section SectionTable[NumberOfSections] = {
371       {{'.', 'i', 'd', 'a', 't', 'a', '$', '5'},
372        u32(0),
373        u32(0),
374        u32(sizeof(export_address_table_entry)),
375        u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section)),
376        u32(0),
377        u32(0),
378        u16(0),
379        u16(0),
380        u32(IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_CNT_INITIALIZED_DATA |
381            IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE)},
382       {{'.', 'i', 'd', 'a', 't', 'a', '$', '4'},
383        u32(0),
384        u32(0),
385        u32(sizeof(export_address_table_entry)),
386        u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section) +
387            sizeof(export_address_table_entry)),
388        u32(0),
389        u32(0),
390        u16(0),
391        u16(0),
392        u32(IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_CNT_INITIALIZED_DATA |
393            IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE)},
394   };
395   append(Buffer, SectionTable);
396
397   // .idata$5
398   static const export_address_table_entry ILT{u32(0)};
399   append(Buffer, ILT);
400
401   // .idata$4
402   static const export_address_table_entry IAT{u32(0)};
403   append(Buffer, IAT);
404
405   // Symbol Table
406   coff_symbol16 SymbolTable[NumberOfSymbols] = {
407       {{{0, 0, 0, 0, 0, 0, 0, 0}},
408        u32(0),
409        u16(1),
410        u16(0),
411        IMAGE_SYM_CLASS_EXTERNAL,
412        0},
413   };
414   reinterpret_cast<StringTableOffset &>(SymbolTable[0].Name).Offset =
415       sizeof(uint32_t);
416   append(Buffer, SymbolTable);
417
418   // String Table
419   writeStringTable(Buffer, {NullThunkSymbolName});
420
421   StringRef F{reinterpret_cast<const char *>(Buffer.data()), Buffer.size()};
422   return {MemoryBufferRef{F, DLLName}};
423 }
424
425 NewArchiveMember ObjectFactory::createShortImport(StringRef Sym,
426                                                   uint16_t Ordinal,
427                                                   ImportNameType NameType,
428                                                   bool isData) {
429   size_t ImpSize = DLLName.size() + Sym.size() + 2; // +2 for NULs
430   size_t Size = sizeof(coff_import_header) + ImpSize;
431   char *Buf = Alloc.Allocate<char>(Size);
432   memset(Buf, 0, Size);
433   char *P = Buf;
434
435   // Write short import library.
436   auto *Imp = reinterpret_cast<coff_import_header *>(P);
437   P += sizeof(*Imp);
438   Imp->Sig2 = 0xFFFF;
439   Imp->Machine = Config->Machine;
440   Imp->SizeOfData = ImpSize;
441   if (Ordinal > 0)
442     Imp->OrdinalHint = Ordinal;
443   Imp->TypeInfo = (isData ? IMPORT_DATA : IMPORT_CODE);
444   Imp->TypeInfo |= NameType << 2;
445
446   // Write symbol name and DLL name.
447   memcpy(P, Sym.data(), Sym.size());
448   P += Sym.size() + 1;
449   memcpy(P, DLLName.data(), DLLName.size());
450
451   return {MemoryBufferRef(StringRef(Buf, Size), DLLName)};
452 }
453
454 // Creates an import library for a DLL. In this function, we first
455 // create an empty import library using lib.exe and then adds short
456 // import files to that file.
457 void lld::coff::writeImportLibrary() {
458   std::vector<NewArchiveMember> Members;
459
460   std::string Path = getImplibPath();
461   std::string DLLName = llvm::sys::path::filename(Config->OutputFile);
462   ObjectFactory OF(DLLName);
463
464   std::vector<uint8_t> ImportDescriptor;
465   Members.push_back(OF.createImportDescriptor(ImportDescriptor));
466
467   std::vector<uint8_t> NullImportDescriptor;
468   Members.push_back(OF.createNullImportDescriptor(NullImportDescriptor));
469
470   std::vector<uint8_t> NullThunk;
471   Members.push_back(OF.createNullThunk(NullThunk));
472
473   for (Export &E : Config->Exports) {
474     if (E.Private)
475       continue;
476
477     ImportNameType Type = getNameType(E.SymbolName, E.Name);
478     std::string Name = E.ExtName.empty()
479                            ? std::string(E.SymbolName)
480                            : replace(E.SymbolName, E.Name, E.ExtName);
481     Members.push_back(OF.createShortImport(Name, E.Ordinal, Type, E.Data));
482   }
483
484   std::pair<StringRef, std::error_code> Result =
485       writeArchive(Path, Members, /*WriteSymtab*/ true, object::Archive::K_GNU,
486                    /*Deterministic*/ true, /*Thin*/ false);
487   if (auto EC = Result.second)
488     fatal(EC, "failed to write " + Path);
489 }