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