]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lld/COFF/DLL.cpp
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r304149, and update
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lld / COFF / DLL.cpp
1 //===- DLL.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 defines various types of chunks for the DLL import or export
11 // descriptor tables. They are inherently Windows-specific.
12 // You need to read Microsoft PE/COFF spec to understand details
13 // about the data structures.
14 //
15 // If you are not particularly interested in linking against Windows
16 // DLL, you can skip this file, and you should still be able to
17 // understand the rest of the linker.
18 //
19 //===----------------------------------------------------------------------===//
20
21 #include "Chunks.h"
22 #include "DLL.h"
23 #include "llvm/Object/COFF.h"
24 #include "llvm/Support/Endian.h"
25 #include "llvm/Support/Path.h"
26
27 using namespace llvm;
28 using namespace llvm::object;
29 using namespace llvm::support::endian;
30 using namespace llvm::COFF;
31
32 namespace lld {
33 namespace coff {
34 namespace {
35
36 // Import table
37
38 static int ptrSize() { return Config->is64() ? 8 : 4; }
39
40 // A chunk for the import descriptor table.
41 class HintNameChunk : public Chunk {
42 public:
43   HintNameChunk(StringRef N, uint16_t H) : Name(N), Hint(H) {}
44
45   size_t getSize() const override {
46     // Starts with 2 byte Hint field, followed by a null-terminated string,
47     // ends with 0 or 1 byte padding.
48     return alignTo(Name.size() + 3, 2);
49   }
50
51   void writeTo(uint8_t *Buf) const override {
52     write16le(Buf + OutputSectionOff, Hint);
53     memcpy(Buf + OutputSectionOff + 2, Name.data(), Name.size());
54   }
55
56 private:
57   StringRef Name;
58   uint16_t Hint;
59 };
60
61 // A chunk for the import descriptor table.
62 class LookupChunk : public Chunk {
63 public:
64   explicit LookupChunk(Chunk *C) : HintName(C) {}
65   size_t getSize() const override { return ptrSize(); }
66
67   void writeTo(uint8_t *Buf) const override {
68     write32le(Buf + OutputSectionOff, HintName->getRVA());
69   }
70
71   Chunk *HintName;
72 };
73
74 // A chunk for the import descriptor table.
75 // This chunk represent import-by-ordinal symbols.
76 // See Microsoft PE/COFF spec 7.1. Import Header for details.
77 class OrdinalOnlyChunk : public Chunk {
78 public:
79   explicit OrdinalOnlyChunk(uint16_t V) : Ordinal(V) {}
80   size_t getSize() const override { return ptrSize(); }
81
82   void writeTo(uint8_t *Buf) const override {
83     // An import-by-ordinal slot has MSB 1 to indicate that
84     // this is import-by-ordinal (and not import-by-name).
85     if (Config->is64()) {
86       write64le(Buf + OutputSectionOff, (1ULL << 63) | Ordinal);
87     } else {
88       write32le(Buf + OutputSectionOff, (1ULL << 31) | Ordinal);
89     }
90   }
91
92   uint16_t Ordinal;
93 };
94
95 // A chunk for the import descriptor table.
96 class ImportDirectoryChunk : public Chunk {
97 public:
98   explicit ImportDirectoryChunk(Chunk *N) : DLLName(N) {}
99   size_t getSize() const override { return sizeof(ImportDirectoryTableEntry); }
100
101   void writeTo(uint8_t *Buf) const override {
102     auto *E = (coff_import_directory_table_entry *)(Buf + OutputSectionOff);
103     E->NameRVA = DLLName->getRVA();
104
105     // The import descriptor table contains two pointers to
106     // the tables describing dllimported symbols. But the
107     // Windows loader actually uses only one. So we create
108     // only one table and set both fields to its address.
109     E->ImportLookupTableRVA = AddressTab->getRVA();
110     E->ImportAddressTableRVA = AddressTab->getRVA();
111   }
112
113   Chunk *DLLName;
114   Chunk *AddressTab;
115 };
116
117 // A chunk representing null terminator in the import table.
118 // Contents of this chunk is always null bytes.
119 class NullChunk : public Chunk {
120 public:
121   explicit NullChunk(size_t N) : Size(N) {}
122   bool hasData() const override { return false; }
123   size_t getSize() const override { return Size; }
124   void setAlign(size_t N) { Align = N; }
125
126 private:
127   size_t Size;
128 };
129
130 static std::vector<std::vector<DefinedImportData *>>
131 binImports(const std::vector<DefinedImportData *> &Imports) {
132   // Group DLL-imported symbols by DLL name because that's how
133   // symbols are layed out in the import descriptor table.
134   auto Less = [](const std::string &A, const std::string &B) {
135     return Config->DLLOrder[A] < Config->DLLOrder[B];
136   };
137   std::map<std::string, std::vector<DefinedImportData *>,
138            bool(*)(const std::string &, const std::string &)> M(Less);
139   for (DefinedImportData *Sym : Imports)
140     M[Sym->getDLLName().lower()].push_back(Sym);
141
142   std::vector<std::vector<DefinedImportData *>> V;
143   for (auto &KV : M) {
144     // Sort symbols by name for each group.
145     std::vector<DefinedImportData *> &Syms = KV.second;
146     std::sort(Syms.begin(), Syms.end(),
147               [](DefinedImportData *A, DefinedImportData *B) {
148                 return A->getName() < B->getName();
149               });
150     V.push_back(std::move(Syms));
151   }
152   return V;
153 }
154
155 // Export table
156 // See Microsoft PE/COFF spec 4.3 for details.
157
158 // A chunk for the delay import descriptor table etnry.
159 class DelayDirectoryChunk : public Chunk {
160 public:
161   explicit DelayDirectoryChunk(Chunk *N) : DLLName(N) {}
162
163   size_t getSize() const override {
164     return sizeof(delay_import_directory_table_entry);
165   }
166
167   void writeTo(uint8_t *Buf) const override {
168     auto *E = (delay_import_directory_table_entry *)(Buf + OutputSectionOff);
169     E->Attributes = 1;
170     E->Name = DLLName->getRVA();
171     E->ModuleHandle = ModuleHandle->getRVA();
172     E->DelayImportAddressTable = AddressTab->getRVA();
173     E->DelayImportNameTable = NameTab->getRVA();
174   }
175
176   Chunk *DLLName;
177   Chunk *ModuleHandle;
178   Chunk *AddressTab;
179   Chunk *NameTab;
180 };
181
182 // Initial contents for delay-loaded functions.
183 // This code calls __delayLoadHelper2 function to resolve a symbol
184 // and then overwrites its jump table slot with the result
185 // for subsequent function calls.
186 static const uint8_t ThunkX64[] = {
187     0x51,                               // push    rcx
188     0x52,                               // push    rdx
189     0x41, 0x50,                         // push    r8
190     0x41, 0x51,                         // push    r9
191     0x48, 0x83, 0xEC, 0x48,             // sub     rsp, 48h
192     0x66, 0x0F, 0x7F, 0x04, 0x24,       // movdqa  xmmword ptr [rsp], xmm0
193     0x66, 0x0F, 0x7F, 0x4C, 0x24, 0x10, // movdqa  xmmword ptr [rsp+10h], xmm1
194     0x66, 0x0F, 0x7F, 0x54, 0x24, 0x20, // movdqa  xmmword ptr [rsp+20h], xmm2
195     0x66, 0x0F, 0x7F, 0x5C, 0x24, 0x30, // movdqa  xmmword ptr [rsp+30h], xmm3
196     0x48, 0x8D, 0x15, 0, 0, 0, 0,       // lea     rdx, [__imp_<FUNCNAME>]
197     0x48, 0x8D, 0x0D, 0, 0, 0, 0,       // lea     rcx, [___DELAY_IMPORT_...]
198     0xE8, 0, 0, 0, 0,                   // call    __delayLoadHelper2
199     0x66, 0x0F, 0x6F, 0x04, 0x24,       // movdqa  xmm0, xmmword ptr [rsp]
200     0x66, 0x0F, 0x6F, 0x4C, 0x24, 0x10, // movdqa  xmm1, xmmword ptr [rsp+10h]
201     0x66, 0x0F, 0x6F, 0x54, 0x24, 0x20, // movdqa  xmm2, xmmword ptr [rsp+20h]
202     0x66, 0x0F, 0x6F, 0x5C, 0x24, 0x30, // movdqa  xmm3, xmmword ptr [rsp+30h]
203     0x48, 0x83, 0xC4, 0x48,             // add     rsp, 48h
204     0x41, 0x59,                         // pop     r9
205     0x41, 0x58,                         // pop     r8
206     0x5A,                               // pop     rdx
207     0x59,                               // pop     rcx
208     0xFF, 0xE0,                         // jmp     rax
209 };
210
211 static const uint8_t ThunkX86[] = {
212     0x51,              // push  ecx
213     0x52,              // push  edx
214     0x68, 0, 0, 0, 0,  // push  offset ___imp__<FUNCNAME>
215     0x68, 0, 0, 0, 0,  // push  offset ___DELAY_IMPORT_DESCRIPTOR_<DLLNAME>_dll
216     0xE8, 0, 0, 0, 0,  // call  ___delayLoadHelper2@8
217     0x5A,              // pop   edx
218     0x59,              // pop   ecx
219     0xFF, 0xE0,        // jmp   eax
220 };
221
222 // A chunk for the delay import thunk.
223 class ThunkChunkX64 : public Chunk {
224 public:
225   ThunkChunkX64(Defined *I, Chunk *D, Defined *H)
226       : Imp(I), Desc(D), Helper(H) {}
227
228   size_t getSize() const override { return sizeof(ThunkX64); }
229
230   void writeTo(uint8_t *Buf) const override {
231     memcpy(Buf + OutputSectionOff, ThunkX64, sizeof(ThunkX64));
232     write32le(Buf + OutputSectionOff + 36, Imp->getRVA() - RVA - 40);
233     write32le(Buf + OutputSectionOff + 43, Desc->getRVA() - RVA - 47);
234     write32le(Buf + OutputSectionOff + 48, Helper->getRVA() - RVA - 52);
235   }
236
237   Defined *Imp = nullptr;
238   Chunk *Desc = nullptr;
239   Defined *Helper = nullptr;
240 };
241
242 class ThunkChunkX86 : public Chunk {
243 public:
244   ThunkChunkX86(Defined *I, Chunk *D, Defined *H)
245       : Imp(I), Desc(D), Helper(H) {}
246
247   size_t getSize() const override { return sizeof(ThunkX86); }
248
249   void writeTo(uint8_t *Buf) const override {
250     memcpy(Buf + OutputSectionOff, ThunkX86, sizeof(ThunkX86));
251     write32le(Buf + OutputSectionOff + 3, Imp->getRVA() + Config->ImageBase);
252     write32le(Buf + OutputSectionOff + 8, Desc->getRVA() + Config->ImageBase);
253     write32le(Buf + OutputSectionOff + 13, Helper->getRVA() - RVA - 17);
254   }
255
256   void getBaserels(std::vector<Baserel> *Res) override {
257     Res->emplace_back(RVA + 3);
258     Res->emplace_back(RVA + 8);
259   }
260
261   Defined *Imp = nullptr;
262   Chunk *Desc = nullptr;
263   Defined *Helper = nullptr;
264 };
265
266 // A chunk for the import descriptor table.
267 class DelayAddressChunk : public Chunk {
268 public:
269   explicit DelayAddressChunk(Chunk *C) : Thunk(C) {}
270   size_t getSize() const override { return ptrSize(); }
271
272   void writeTo(uint8_t *Buf) const override {
273     if (Config->is64()) {
274       write64le(Buf + OutputSectionOff, Thunk->getRVA() + Config->ImageBase);
275     } else {
276       write32le(Buf + OutputSectionOff, Thunk->getRVA() + Config->ImageBase);
277     }
278   }
279
280   void getBaserels(std::vector<Baserel> *Res) override {
281     Res->emplace_back(RVA);
282   }
283
284   Chunk *Thunk;
285 };
286
287 // Export table
288 // Read Microsoft PE/COFF spec 5.3 for details.
289
290 // A chunk for the export descriptor table.
291 class ExportDirectoryChunk : public Chunk {
292 public:
293   ExportDirectoryChunk(int I, int J, Chunk *D, Chunk *A, Chunk *N, Chunk *O)
294       : MaxOrdinal(I), NameTabSize(J), DLLName(D), AddressTab(A), NameTab(N),
295         OrdinalTab(O) {}
296
297   size_t getSize() const override {
298     return sizeof(export_directory_table_entry);
299   }
300
301   void writeTo(uint8_t *Buf) const override {
302     auto *E = (export_directory_table_entry *)(Buf + OutputSectionOff);
303     E->NameRVA = DLLName->getRVA();
304     E->OrdinalBase = 0;
305     E->AddressTableEntries = MaxOrdinal + 1;
306     E->NumberOfNamePointers = NameTabSize;
307     E->ExportAddressTableRVA = AddressTab->getRVA();
308     E->NamePointerRVA = NameTab->getRVA();
309     E->OrdinalTableRVA = OrdinalTab->getRVA();
310   }
311
312   uint16_t MaxOrdinal;
313   uint16_t NameTabSize;
314   Chunk *DLLName;
315   Chunk *AddressTab;
316   Chunk *NameTab;
317   Chunk *OrdinalTab;
318 };
319
320 class AddressTableChunk : public Chunk {
321 public:
322   explicit AddressTableChunk(size_t MaxOrdinal) : Size(MaxOrdinal + 1) {}
323   size_t getSize() const override { return Size * 4; }
324
325   void writeTo(uint8_t *Buf) const override {
326     for (Export &E : Config->Exports) {
327       uint8_t *P = Buf + OutputSectionOff + E.Ordinal * 4;
328       if (E.ForwardChunk) {
329         write32le(P, E.ForwardChunk->getRVA());
330       } else {
331         write32le(P, cast<Defined>(E.Sym)->getRVA());
332       }
333     }
334   }
335
336 private:
337   size_t Size;
338 };
339
340 class NamePointersChunk : public Chunk {
341 public:
342   explicit NamePointersChunk(std::vector<Chunk *> &V) : Chunks(V) {}
343   size_t getSize() const override { return Chunks.size() * 4; }
344
345   void writeTo(uint8_t *Buf) const override {
346     uint8_t *P = Buf + OutputSectionOff;
347     for (Chunk *C : Chunks) {
348       write32le(P, C->getRVA());
349       P += 4;
350     }
351   }
352
353 private:
354   std::vector<Chunk *> Chunks;
355 };
356
357 class ExportOrdinalChunk : public Chunk {
358 public:
359   explicit ExportOrdinalChunk(size_t I) : Size(I) {}
360   size_t getSize() const override { return Size * 2; }
361
362   void writeTo(uint8_t *Buf) const override {
363     uint8_t *P = Buf + OutputSectionOff;
364     for (Export &E : Config->Exports) {
365       if (E.Noname)
366         continue;
367       write16le(P, E.Ordinal);
368       P += 2;
369     }
370   }
371
372 private:
373   size_t Size;
374 };
375
376 } // anonymous namespace
377
378 uint64_t IdataContents::getDirSize() {
379   return Dirs.size() * sizeof(ImportDirectoryTableEntry);
380 }
381
382 uint64_t IdataContents::getIATSize() {
383   return Addresses.size() * ptrSize();
384 }
385
386 // Returns a list of .idata contents.
387 // See Microsoft PE/COFF spec 5.4 for details.
388 std::vector<Chunk *> IdataContents::getChunks() {
389   create();
390
391   // The loader assumes a specific order of data.
392   // Add each type in the correct order.
393   std::vector<Chunk *> V;
394   V.insert(V.end(), Dirs.begin(), Dirs.end());
395   V.insert(V.end(), Addresses.begin(), Addresses.end());
396   V.insert(V.end(), Hints.begin(), Hints.end());
397   V.insert(V.end(), DLLNames.begin(), DLLNames.end());
398   return V;
399 }
400
401 void IdataContents::create() {
402   std::vector<std::vector<DefinedImportData *>> V = binImports(Imports);
403
404   // Create .idata contents for each DLL.
405   for (std::vector<DefinedImportData *> &Syms : V) {
406     // Create lookup and address tables. If they have external names,
407     // we need to create HintName chunks to store the names.
408     // If they don't (if they are import-by-ordinals), we store only
409     // ordinal values to the table.
410     size_t Base = Addresses.size();
411     for (DefinedImportData *S : Syms) {
412       uint16_t Ord = S->getOrdinal();
413       if (S->getExternalName().empty()) {
414         Addresses.push_back(make<OrdinalOnlyChunk>(Ord));
415         continue;
416       }
417       auto *C = make<HintNameChunk>(S->getExternalName(), Ord);
418       Addresses.push_back(make<LookupChunk>(C));
419       Hints.push_back(C);
420     }
421     // Terminate with null values.
422     Addresses.push_back(make<NullChunk>(ptrSize()));
423
424     for (int I = 0, E = Syms.size(); I < E; ++I)
425       Syms[I]->setLocation(Addresses[Base + I]);
426
427     // Create the import table header.
428     DLLNames.push_back(make<StringChunk>(Syms[0]->getDLLName()));
429     auto *Dir = make<ImportDirectoryChunk>(DLLNames.back());
430     Dir->AddressTab = Addresses[Base];
431     Dirs.push_back(Dir);
432   }
433   // Add null terminator.
434   Dirs.push_back(make<NullChunk>(sizeof(ImportDirectoryTableEntry)));
435 }
436
437 std::vector<Chunk *> DelayLoadContents::getChunks() {
438   std::vector<Chunk *> V;
439   V.insert(V.end(), Dirs.begin(), Dirs.end());
440   V.insert(V.end(), Names.begin(), Names.end());
441   V.insert(V.end(), HintNames.begin(), HintNames.end());
442   V.insert(V.end(), DLLNames.begin(), DLLNames.end());
443   return V;
444 }
445
446 std::vector<Chunk *> DelayLoadContents::getDataChunks() {
447   std::vector<Chunk *> V;
448   V.insert(V.end(), ModuleHandles.begin(), ModuleHandles.end());
449   V.insert(V.end(), Addresses.begin(), Addresses.end());
450   return V;
451 }
452
453 uint64_t DelayLoadContents::getDirSize() {
454   return Dirs.size() * sizeof(delay_import_directory_table_entry);
455 }
456
457 void DelayLoadContents::create(Defined *H) {
458   Helper = H;
459   std::vector<std::vector<DefinedImportData *>> V = binImports(Imports);
460
461   // Create .didat contents for each DLL.
462   for (std::vector<DefinedImportData *> &Syms : V) {
463     // Create the delay import table header.
464     DLLNames.push_back(make<StringChunk>(Syms[0]->getDLLName()));
465     auto *Dir = make<DelayDirectoryChunk>(DLLNames.back());
466
467     size_t Base = Addresses.size();
468     for (DefinedImportData *S : Syms) {
469       Chunk *T = newThunkChunk(S, Dir);
470       auto *A = make<DelayAddressChunk>(T);
471       Addresses.push_back(A);
472       Thunks.push_back(T);
473       StringRef ExtName = S->getExternalName();
474       if (ExtName.empty()) {
475         Names.push_back(make<OrdinalOnlyChunk>(S->getOrdinal()));
476       } else {
477         auto *C = make<HintNameChunk>(ExtName, 0);
478         Names.push_back(make<LookupChunk>(C));
479         HintNames.push_back(C);
480       }
481     }
482     // Terminate with null values.
483     Addresses.push_back(make<NullChunk>(8));
484     Names.push_back(make<NullChunk>(8));
485
486     for (int I = 0, E = Syms.size(); I < E; ++I)
487       Syms[I]->setLocation(Addresses[Base + I]);
488     auto *MH = make<NullChunk>(8);
489     MH->setAlign(8);
490     ModuleHandles.push_back(MH);
491
492     // Fill the delay import table header fields.
493     Dir->ModuleHandle = MH;
494     Dir->AddressTab = Addresses[Base];
495     Dir->NameTab = Names[Base];
496     Dirs.push_back(Dir);
497   }
498   // Add null terminator.
499   Dirs.push_back(make<NullChunk>(sizeof(delay_import_directory_table_entry)));
500 }
501
502 Chunk *DelayLoadContents::newThunkChunk(DefinedImportData *S, Chunk *Dir) {
503   switch (Config->Machine) {
504   case AMD64:
505     return make<ThunkChunkX64>(S, Dir, Helper);
506   case I386:
507     return make<ThunkChunkX86>(S, Dir, Helper);
508   default:
509     llvm_unreachable("unsupported machine type");
510   }
511 }
512
513 EdataContents::EdataContents() {
514   uint16_t MaxOrdinal = 0;
515   for (Export &E : Config->Exports)
516     MaxOrdinal = std::max(MaxOrdinal, E.Ordinal);
517
518   auto *DLLName = make<StringChunk>(sys::path::filename(Config->OutputFile));
519   auto *AddressTab = make<AddressTableChunk>(MaxOrdinal);
520   std::vector<Chunk *> Names;
521   for (Export &E : Config->Exports)
522     if (!E.Noname)
523       Names.push_back(make<StringChunk>(E.ExportName));
524
525   std::vector<Chunk *> Forwards;
526   for (Export &E : Config->Exports) {
527     if (E.ForwardTo.empty())
528       continue;
529     E.ForwardChunk = make<StringChunk>(E.ForwardTo);
530     Forwards.push_back(E.ForwardChunk);
531   }
532
533   auto *NameTab = make<NamePointersChunk>(Names);
534   auto *OrdinalTab = make<ExportOrdinalChunk>(Names.size());
535   auto *Dir = make<ExportDirectoryChunk>(MaxOrdinal, Names.size(), DLLName,
536                                          AddressTab, NameTab, OrdinalTab);
537   Chunks.push_back(Dir);
538   Chunks.push_back(DLLName);
539   Chunks.push_back(AddressTab);
540   Chunks.push_back(NameTab);
541   Chunks.push_back(OrdinalTab);
542   Chunks.insert(Chunks.end(), Names.begin(), Names.end());
543   Chunks.insert(Chunks.end(), Forwards.begin(), Forwards.end());
544 }
545
546 } // namespace coff
547 } // namespace lld