LLVM 17.0.0git
COFFImportFile.cpp
Go to the documentation of this file.
1//===- COFFImportFile.cpp - COFF short import file implementation ---------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the writeImportLibrary function.
10//
11//===----------------------------------------------------------------------===//
12
14#include "llvm/ADT/ArrayRef.h"
15#include "llvm/ADT/Twine.h"
16#include "llvm/Object/Archive.h"
18#include "llvm/Object/COFF.h"
20#include "llvm/Support/Endian.h"
21#include "llvm/Support/Error.h"
23#include "llvm/Support/Path.h"
24
25#include <cstdint>
26#include <string>
27#include <vector>
28
29using namespace llvm::COFF;
30using namespace llvm::object;
31using namespace llvm;
32
33namespace llvm {
34namespace object {
35
36static bool is32bit(MachineTypes Machine) {
37 switch (Machine) {
38 default:
39 llvm_unreachable("unsupported machine");
43 return false;
46 return true;
47 }
48}
49
51 switch (Machine) {
52 default:
53 llvm_unreachable("unsupported machine");
63 }
64}
65
66template <class T> static void append(std::vector<uint8_t> &B, const T &Data) {
67 size_t S = B.size();
68 B.resize(S + sizeof(T));
69 memcpy(&B[S], &Data, sizeof(T));
70}
71
72static void writeStringTable(std::vector<uint8_t> &B,
74 // The COFF string table consists of a 4-byte value which is the size of the
75 // table, including the length field itself. This value is followed by the
76 // string content itself, which is an array of null-terminated C-style
77 // strings. The termination is important as they are referenced to by offset
78 // by the symbol entity in the file format.
79
80 size_t Pos = B.size();
81 size_t Offset = B.size();
82
83 // Skip over the length field, we will fill it in later as we will have
84 // computed the length while emitting the string content itself.
85 Pos += sizeof(uint32_t);
86
87 for (const auto &S : Strings) {
88 B.resize(Pos + S.length() + 1);
89 std::copy(S.begin(), S.end(), std::next(B.begin(), Pos));
90 B[Pos + S.length()] = 0;
91 Pos += S.length() + 1;
92 }
93
94 // Backfill the length of the table now that it has been computed.
97}
98
100 MachineTypes Machine, bool MinGW) {
101 // A decorated stdcall function in MSVC is exported with the
102 // type IMPORT_NAME, and the exported function name includes the
103 // the leading underscore. In MinGW on the other hand, a decorated
104 // stdcall function still omits the underscore (IMPORT_NAME_NOPREFIX).
105 // See the comment in isDecorated in COFFModuleDefinition.cpp for more
106 // details.
107 if (ExtName.startswith("_") && ExtName.contains('@') && !MinGW)
108 return IMPORT_NAME;
109 if (Sym != ExtName)
111 if (Machine == IMAGE_FILE_MACHINE_I386 && Sym.startswith("_"))
113 return IMPORT_NAME;
114}
115
117 StringRef To) {
118 size_t Pos = S.find(From);
119
120 // From and To may be mangled, but substrings in S may not.
121 if (Pos == StringRef::npos && From.startswith("_") && To.startswith("_")) {
122 From = From.substr(1);
123 To = To.substr(1);
124 Pos = S.find(From);
125 }
126
127 if (Pos == StringRef::npos) {
128 return make_error<StringError>(
129 StringRef(Twine(S + ": replacing '" + From +
130 "' with '" + To + "' failed").str()), object_error::parse_failed);
131 }
132
133 return (Twine(S.substr(0, Pos)) + To + S.substr(Pos + From.size())).str();
134}
135
136static const std::string NullImportDescriptorSymbolName =
137 "__NULL_IMPORT_DESCRIPTOR";
138
139namespace {
140// This class constructs various small object files necessary to support linking
141// symbols imported from a DLL. The contents are pretty strictly defined and
142// nearly entirely static. The details of the structures files are defined in
143// WINNT.h and the PE/COFF specification.
144class ObjectFactory {
145 using u16 = support::ulittle16_t;
146 using u32 = support::ulittle32_t;
147 MachineTypes Machine;
148 BumpPtrAllocator Alloc;
149 StringRef ImportName;
150 StringRef Library;
151 std::string ImportDescriptorSymbolName;
152 std::string NullThunkSymbolName;
153
154public:
155 ObjectFactory(StringRef S, MachineTypes M)
156 : Machine(M), ImportName(S), Library(S.drop_back(4)),
157 ImportDescriptorSymbolName(("__IMPORT_DESCRIPTOR_" + Library).str()),
158 NullThunkSymbolName(("\x7f" + Library + "_NULL_THUNK_DATA").str()) {}
159
160 // Creates an Import Descriptor. This is a small object file which contains a
161 // reference to the terminators and contains the library name (entry) for the
162 // import name table. It will force the linker to construct the necessary
163 // structure to import symbols from the DLL.
164 NewArchiveMember createImportDescriptor(std::vector<uint8_t> &Buffer);
165
166 // Creates a NULL import descriptor. This is a small object file whcih
167 // contains a NULL import descriptor. It is used to terminate the imports
168 // from a specific DLL.
169 NewArchiveMember createNullImportDescriptor(std::vector<uint8_t> &Buffer);
170
171 // Create a NULL Thunk Entry. This is a small object file which contains a
172 // NULL Import Address Table entry and a NULL Import Lookup Table Entry. It
173 // is used to terminate the IAT and ILT.
174 NewArchiveMember createNullThunk(std::vector<uint8_t> &Buffer);
175
176 // Create a short import file which is described in PE/COFF spec 7. Import
177 // Library Format.
178 NewArchiveMember createShortImport(StringRef Sym, uint16_t Ordinal,
180
181 // Create a weak external file which is described in PE/COFF Aux Format 3.
182 NewArchiveMember createWeakExternal(StringRef Sym, StringRef Weak, bool Imp);
183};
184} // namespace
185
187ObjectFactory::createImportDescriptor(std::vector<uint8_t> &Buffer) {
188 const uint32_t NumberOfSections = 2;
189 const uint32_t NumberOfSymbols = 7;
190 const uint32_t NumberOfRelocations = 3;
191
192 // COFF Header
193 coff_file_header Header{
194 u16(Machine),
195 u16(NumberOfSections),
196 u32(0),
197 u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section)) +
198 // .idata$2
200 NumberOfRelocations * sizeof(coff_relocation) +
201 // .idata$4
202 (ImportName.size() + 1)),
203 u32(NumberOfSymbols),
204 u16(0),
206 };
207 append(Buffer, Header);
208
209 // Section Header Table
210 const coff_section SectionTable[NumberOfSections] = {
211 {{'.', 'i', 'd', 'a', 't', 'a', '$', '2'},
212 u32(0),
213 u32(0),
215 u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section)),
216 u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section) +
218 u32(0),
219 u16(NumberOfRelocations),
220 u16(0),
223 {{'.', 'i', 'd', 'a', 't', 'a', '$', '6'},
224 u32(0),
225 u32(0),
226 u32(ImportName.size() + 1),
227 u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section) +
229 NumberOfRelocations * sizeof(coff_relocation)),
230 u32(0),
231 u32(0),
232 u16(0),
233 u16(0),
236 };
237 append(Buffer, SectionTable);
238
239 // .idata$2
240 const coff_import_directory_table_entry ImportDescriptor{
241 u32(0), u32(0), u32(0), u32(0), u32(0),
242 };
243 append(Buffer, ImportDescriptor);
244
245 const coff_relocation RelocationTable[NumberOfRelocations] = {
246 {u32(offsetof(coff_import_directory_table_entry, NameRVA)), u32(2),
247 u16(getImgRelRelocation(Machine))},
248 {u32(offsetof(coff_import_directory_table_entry, ImportLookupTableRVA)),
249 u32(3), u16(getImgRelRelocation(Machine))},
250 {u32(offsetof(coff_import_directory_table_entry, ImportAddressTableRVA)),
251 u32(4), u16(getImgRelRelocation(Machine))},
252 };
253 append(Buffer, RelocationTable);
254
255 // .idata$6
256 auto S = Buffer.size();
257 Buffer.resize(S + ImportName.size() + 1);
258 memcpy(&Buffer[S], ImportName.data(), ImportName.size());
259 Buffer[S + ImportName.size()] = '\0';
260
261 // Symbol Table
262 coff_symbol16 SymbolTable[NumberOfSymbols] = {
263 {{{0, 0, 0, 0, 0, 0, 0, 0}},
264 u32(0),
265 u16(1),
266 u16(0),
268 0},
269 {{{'.', 'i', 'd', 'a', 't', 'a', '$', '2'}},
270 u32(0),
271 u16(1),
272 u16(0),
274 0},
275 {{{'.', 'i', 'd', 'a', 't', 'a', '$', '6'}},
276 u32(0),
277 u16(2),
278 u16(0),
280 0},
281 {{{'.', 'i', 'd', 'a', 't', 'a', '$', '4'}},
282 u32(0),
283 u16(0),
284 u16(0),
286 0},
287 {{{'.', 'i', 'd', 'a', 't', 'a', '$', '5'}},
288 u32(0),
289 u16(0),
290 u16(0),
292 0},
293 {{{0, 0, 0, 0, 0, 0, 0, 0}},
294 u32(0),
295 u16(0),
296 u16(0),
298 0},
299 {{{0, 0, 0, 0, 0, 0, 0, 0}},
300 u32(0),
301 u16(0),
302 u16(0),
304 0},
305 };
306 // TODO: Name.Offset.Offset here and in the all similar places below
307 // suggests a names refactoring. Maybe StringTableOffset.Value?
308 SymbolTable[0].Name.Offset.Offset =
309 sizeof(uint32_t);
310 SymbolTable[5].Name.Offset.Offset =
311 sizeof(uint32_t) + ImportDescriptorSymbolName.length() + 1;
312 SymbolTable[6].Name.Offset.Offset =
313 sizeof(uint32_t) + ImportDescriptorSymbolName.length() + 1 +
315 append(Buffer, SymbolTable);
316
317 // String Table
318 writeStringTable(Buffer,
319 {ImportDescriptorSymbolName, NullImportDescriptorSymbolName,
320 NullThunkSymbolName});
321
322 StringRef F{reinterpret_cast<const char *>(Buffer.data()), Buffer.size()};
323 return {MemoryBufferRef(F, ImportName)};
324}
325
327ObjectFactory::createNullImportDescriptor(std::vector<uint8_t> &Buffer) {
328 const uint32_t NumberOfSections = 1;
329 const uint32_t NumberOfSymbols = 1;
330
331 // COFF Header
332 coff_file_header Header{
333 u16(Machine),
334 u16(NumberOfSections),
335 u32(0),
336 u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section)) +
337 // .idata$3
339 u32(NumberOfSymbols),
340 u16(0),
342 };
343 append(Buffer, Header);
344
345 // Section Header Table
346 const coff_section SectionTable[NumberOfSections] = {
347 {{'.', 'i', 'd', 'a', 't', 'a', '$', '3'},
348 u32(0),
349 u32(0),
351 u32(sizeof(coff_file_header) +
352 (NumberOfSections * sizeof(coff_section))),
353 u32(0),
354 u32(0),
355 u16(0),
356 u16(0),
359 };
360 append(Buffer, SectionTable);
361
362 // .idata$3
363 const coff_import_directory_table_entry ImportDescriptor{
364 u32(0), u32(0), u32(0), u32(0), u32(0),
365 };
366 append(Buffer, ImportDescriptor);
367
368 // Symbol Table
369 coff_symbol16 SymbolTable[NumberOfSymbols] = {
370 {{{0, 0, 0, 0, 0, 0, 0, 0}},
371 u32(0),
372 u16(1),
373 u16(0),
375 0},
376 };
377 SymbolTable[0].Name.Offset.Offset = sizeof(uint32_t);
378 append(Buffer, SymbolTable);
379
380 // String Table
382
383 StringRef F{reinterpret_cast<const char *>(Buffer.data()), Buffer.size()};
384 return {MemoryBufferRef(F, ImportName)};
385}
386
387NewArchiveMember ObjectFactory::createNullThunk(std::vector<uint8_t> &Buffer) {
388 const uint32_t NumberOfSections = 2;
389 const uint32_t NumberOfSymbols = 1;
390 uint32_t VASize = is32bit(Machine) ? 4 : 8;
391
392 // COFF Header
393 coff_file_header Header{
394 u16(Machine),
395 u16(NumberOfSections),
396 u32(0),
397 u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section)) +
398 // .idata$5
399 VASize +
400 // .idata$4
401 VASize),
402 u32(NumberOfSymbols),
403 u16(0),
405 };
406 append(Buffer, Header);
407
408 // Section Header Table
409 const coff_section SectionTable[NumberOfSections] = {
410 {{'.', 'i', 'd', 'a', 't', 'a', '$', '5'},
411 u32(0),
412 u32(0),
413 u32(VASize),
414 u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section)),
415 u32(0),
416 u32(0),
417 u16(0),
418 u16(0),
419 u32((is32bit(Machine) ? IMAGE_SCN_ALIGN_4BYTES
423 {{'.', 'i', 'd', 'a', 't', 'a', '$', '4'},
424 u32(0),
425 u32(0),
426 u32(VASize),
427 u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section) +
428 VASize),
429 u32(0),
430 u32(0),
431 u16(0),
432 u16(0),
433 u32((is32bit(Machine) ? IMAGE_SCN_ALIGN_4BYTES
437 };
438 append(Buffer, SectionTable);
439
440 // .idata$5, ILT
441 append(Buffer, u32(0));
442 if (!is32bit(Machine))
443 append(Buffer, u32(0));
444
445 // .idata$4, IAT
446 append(Buffer, u32(0));
447 if (!is32bit(Machine))
448 append(Buffer, u32(0));
449
450 // Symbol Table
451 coff_symbol16 SymbolTable[NumberOfSymbols] = {
452 {{{0, 0, 0, 0, 0, 0, 0, 0}},
453 u32(0),
454 u16(1),
455 u16(0),
457 0},
458 };
459 SymbolTable[0].Name.Offset.Offset = sizeof(uint32_t);
460 append(Buffer, SymbolTable);
461
462 // String Table
463 writeStringTable(Buffer, {NullThunkSymbolName});
464
465 StringRef F{reinterpret_cast<const char *>(Buffer.data()), Buffer.size()};
466 return {MemoryBufferRef{F, ImportName}};
467}
468
469NewArchiveMember ObjectFactory::createShortImport(StringRef Sym,
470 uint16_t Ordinal,
473 size_t ImpSize = ImportName.size() + Sym.size() + 2; // +2 for NULs
474 size_t Size = sizeof(coff_import_header) + ImpSize;
475 char *Buf = Alloc.Allocate<char>(Size);
476 memset(Buf, 0, Size);
477 char *P = Buf;
478
479 // Write short import library.
480 auto *Imp = reinterpret_cast<coff_import_header *>(P);
481 P += sizeof(*Imp);
482 Imp->Sig2 = 0xFFFF;
483 Imp->Machine = Machine;
484 Imp->SizeOfData = ImpSize;
485 if (Ordinal > 0)
486 Imp->OrdinalHint = Ordinal;
487 Imp->TypeInfo = (NameType << 2) | ImportType;
488
489 // Write symbol name and DLL name.
490 memcpy(P, Sym.data(), Sym.size());
491 P += Sym.size() + 1;
492 memcpy(P, ImportName.data(), ImportName.size());
493
494 return {MemoryBufferRef(StringRef(Buf, Size), ImportName)};
495}
496
497NewArchiveMember ObjectFactory::createWeakExternal(StringRef Sym,
498 StringRef Weak, bool Imp) {
499 std::vector<uint8_t> Buffer;
500 const uint32_t NumberOfSections = 1;
501 const uint32_t NumberOfSymbols = 5;
502
503 // COFF Header
504 coff_file_header Header{
505 u16(Machine),
506 u16(NumberOfSections),
507 u32(0),
508 u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section))),
509 u32(NumberOfSymbols),
510 u16(0),
511 u16(0),
512 };
513 append(Buffer, Header);
514
515 // Section Header Table
516 const coff_section SectionTable[NumberOfSections] = {
517 {{'.', 'd', 'r', 'e', 'c', 't', 'v', 'e'},
518 u32(0),
519 u32(0),
520 u32(0),
521 u32(0),
522 u32(0),
523 u32(0),
524 u16(0),
525 u16(0),
527 append(Buffer, SectionTable);
528
529 // Symbol Table
530 coff_symbol16 SymbolTable[NumberOfSymbols] = {
531 {{{'@', 'c', 'o', 'm', 'p', '.', 'i', 'd'}},
532 u32(0),
533 u16(0xFFFF),
534 u16(0),
536 0},
537 {{{'@', 'f', 'e', 'a', 't', '.', '0', '0'}},
538 u32(0),
539 u16(0xFFFF),
540 u16(0),
542 0},
543 {{{0, 0, 0, 0, 0, 0, 0, 0}},
544 u32(0),
545 u16(0),
546 u16(0),
548 0},
549 {{{0, 0, 0, 0, 0, 0, 0, 0}},
550 u32(0),
551 u16(0),
552 u16(0),
554 1},
555 {{{2, 0, 0, 0, IMAGE_WEAK_EXTERN_SEARCH_ALIAS, 0, 0, 0}},
556 u32(0),
557 u16(0),
558 u16(0),
560 0},
561 };
562 SymbolTable[2].Name.Offset.Offset = sizeof(uint32_t);
563
564 //__imp_ String Table
565 StringRef Prefix = Imp ? "__imp_" : "";
566 SymbolTable[3].Name.Offset.Offset =
567 sizeof(uint32_t) + Sym.size() + Prefix.size() + 1;
568 append(Buffer, SymbolTable);
569 writeStringTable(Buffer, {(Prefix + Sym).str(),
570 (Prefix + Weak).str()});
571
572 // Copied here so we can still use writeStringTable
573 char *Buf = Alloc.Allocate<char>(Buffer.size());
574 memcpy(Buf, Buffer.data(), Buffer.size());
575 return {MemoryBufferRef(StringRef(Buf, Buffer.size()), ImportName)};
576}
577
580 MachineTypes Machine, bool MinGW) {
581
582 std::vector<NewArchiveMember> Members;
583 ObjectFactory OF(llvm::sys::path::filename(ImportName), Machine);
584
585 std::vector<uint8_t> ImportDescriptor;
586 Members.push_back(OF.createImportDescriptor(ImportDescriptor));
587
588 std::vector<uint8_t> NullImportDescriptor;
589 Members.push_back(OF.createNullImportDescriptor(NullImportDescriptor));
590
591 std::vector<uint8_t> NullThunk;
592 Members.push_back(OF.createNullThunk(NullThunk));
593
594 for (COFFShortExport E : Exports) {
595 if (E.Private)
596 continue;
597
599 if (E.Data)
601 if (E.Constant)
603
604 StringRef SymbolName = E.SymbolName.empty() ? E.Name : E.SymbolName;
605 ImportNameType NameType = E.Noname
607 : getNameType(SymbolName, E.Name,
608 Machine, MinGW);
609 Expected<std::string> Name = E.ExtName.empty()
610 ? std::string(SymbolName)
611 : replace(SymbolName, E.Name, E.ExtName);
612
613 if (!Name)
614 return Name.takeError();
615
616 if (!E.AliasTarget.empty() && *Name != E.AliasTarget) {
617 Members.push_back(OF.createWeakExternal(E.AliasTarget, *Name, false));
618 Members.push_back(OF.createWeakExternal(E.AliasTarget, *Name, true));
619 continue;
620 }
621
622 Members.push_back(
623 OF.createShortImport(*Name, E.Ordinal, ImportType, NameType));
624 }
625
626 return writeArchive(Path, Members, /*WriteSymtab*/ true,
628 /*Deterministic*/ true, /*Thin*/ false);
629}
630
631} // namespace object
632} // namespace llvm
#define offsetof(TYPE, MEMBER)
This file defines the BumpPtrAllocator interface.
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
std::string Name
uint64_t Size
#define F(x, y, z)
Definition: MD5.cpp:55
#define P(N)
@ Exports
Definition: TextStubV5.cpp:108
@ Weak
Definition: TextStubV5.cpp:113
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:66
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
Tagged union holding either a T or a Error.
Definition: Error.h:470
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:558
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
Definition: StringRef.h:422
bool startswith(StringRef Prefix) const
Definition: StringRef.h:261
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:295
static constexpr size_t npos
Definition: StringRef.h:52
StringRef drop_back(size_t N=1) const
Return a StringRef equal to 'this' but with the last N elements dropped.
Definition: StringRef.h:603
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:131
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
MachineTypes
Definition: COFF.h:92
@ IMAGE_FILE_MACHINE_ARM64
Definition: COFF.h:100
@ IMAGE_FILE_MACHINE_AMD64
Definition: COFF.h:97
@ IMAGE_FILE_MACHINE_ARM64EC
Definition: COFF.h:101
@ IMAGE_FILE_MACHINE_I386
Definition: COFF.h:103
@ IMAGE_FILE_MACHINE_ARMNT
Definition: COFF.h:99
@ IMAGE_SCN_LNK_REMOVE
Definition: COFF.h:293
@ IMAGE_SCN_MEM_READ
Definition: COFF.h:321
@ IMAGE_SCN_LNK_INFO
Definition: COFF.h:292
@ IMAGE_SCN_CNT_INITIALIZED_DATA
Definition: COFF.h:289
@ IMAGE_SCN_ALIGN_8BYTES
Definition: COFF.h:303
@ IMAGE_SCN_ALIGN_4BYTES
Definition: COFF.h:302
@ IMAGE_SCN_ALIGN_2BYTES
Definition: COFF.h:301
@ IMAGE_SCN_MEM_WRITE
Definition: COFF.h:322
ImportType
Definition: COFF.h:686
@ IMPORT_CONST
Definition: COFF.h:689
@ IMPORT_CODE
Definition: COFF.h:687
@ IMPORT_DATA
Definition: COFF.h:688
@ IMAGE_REL_ARM64_ADDR32NB
Definition: COFF.h:388
@ IMAGE_REL_AMD64_ADDR32NB
Definition: COFF.h:349
@ IMAGE_SYM_CLASS_SECTION
Line number, reformatted as symbol.
Definition: COFF.h:233
@ IMAGE_SYM_CLASS_EXTERNAL
External symbol.
Definition: COFF.h:209
@ IMAGE_SYM_CLASS_NULL
No symbol.
Definition: COFF.h:207
@ IMAGE_SYM_CLASS_WEAK_EXTERNAL
Duplicate tag.
Definition: COFF.h:234
@ IMAGE_SYM_CLASS_STATIC
Static.
Definition: COFF.h:210
@ IMAGE_WEAK_EXTERN_SEARCH_ALIAS
Definition: COFF.h:442
@ IMAGE_REL_ARM_ADDR32NB
Definition: COFF.h:368
ImportNameType
Definition: COFF.h:692
@ IMPORT_ORDINAL
Import is by ordinal.
Definition: COFF.h:697
@ IMPORT_NAME
The import name is identical to the public symbol name.
Definition: COFF.h:699
@ IMPORT_NAME_UNDECORATE
The import name is the public symbol name, but skipping the leading ?, @, or optionally _,...
Definition: COFF.h:705
@ IMPORT_NAME_NOPREFIX
The import name is the public symbol name, but skipping the leading ?, @, or optionally _.
Definition: COFF.h:702
@ IMAGE_REL_I386_DIR32NB
Definition: COFF.h:336
@ C_Invalid
Definition: COFF.h:124
@ IMAGE_FILE_32BIT_MACHINE
Machine is based on a 32bit word architecture.
Definition: COFF.h:145
static void append(std::vector< uint8_t > &B, const T &Data)
static bool is32bit(MachineTypes Machine)
static Expected< std::string > replace(StringRef S, StringRef From, StringRef To)
static uint16_t getImgRelRelocation(MachineTypes Machine)
static void writeStringTable(std::vector< uint8_t > &B, ArrayRef< const std::string > Strings)
static const std::string NullImportDescriptorSymbolName
static ImportNameType getNameType(StringRef Sym, StringRef ExtName, MachineTypes Machine, bool MinGW)
Error writeImportLibrary(StringRef ImportName, StringRef Path, ArrayRef< COFFShortExport > Exports, COFF::MachineTypes Machine, bool MinGW)
void write32le(void *P, uint32_t V)
Definition: Endian.h:416
detail::packed_endian_specific_integral< uint16_t, little, unaligned > ulittle16_t
Definition: Endian.h:270
detail::packed_endian_specific_integral< uint32_t, little, unaligned > ulittle32_t
Definition: Endian.h:272
StringRef filename(StringRef path, Style style=Style::native)
Get filename.
Definition: Path.cpp:577
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:406
@ Length
Definition: DWP.cpp:406
Error writeArchive(StringRef ArcName, ArrayRef< NewArchiveMember > NewMembers, bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin, std::unique_ptr< MemoryBuffer > OldArchiveBuf=nullptr)
support::ulittle32_t Offset
Definition: COFF.h:246
Definition: COFF.h:555
StringTableOffset Offset
Definition: COFF.h:253
union llvm::object::coff_symbol::@330 Name