LLVM 18.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
37 switch (Machine) {
38 default:
39 llvm_unreachable("unsupported machine");
50 }
51}
52
53template <class T> static void append(std::vector<uint8_t> &B, const T &Data) {
54 size_t S = B.size();
55 B.resize(S + sizeof(T));
56 memcpy(&B[S], &Data, sizeof(T));
57}
58
59static void writeStringTable(std::vector<uint8_t> &B,
61 // The COFF string table consists of a 4-byte value which is the size of the
62 // table, including the length field itself. This value is followed by the
63 // string content itself, which is an array of null-terminated C-style
64 // strings. The termination is important as they are referenced to by offset
65 // by the symbol entity in the file format.
66
67 size_t Pos = B.size();
68 size_t Offset = B.size();
69
70 // Skip over the length field, we will fill it in later as we will have
71 // computed the length while emitting the string content itself.
72 Pos += sizeof(uint32_t);
73
74 for (const auto &S : Strings) {
75 B.resize(Pos + S.length() + 1);
76 std::copy(S.begin(), S.end(), std::next(B.begin(), Pos));
77 B[Pos + S.length()] = 0;
78 Pos += S.length() + 1;
79 }
80
81 // Backfill the length of the table now that it has been computed.
84}
85
87 MachineTypes Machine, bool MinGW) {
88 // A decorated stdcall function in MSVC is exported with the
89 // type IMPORT_NAME, and the exported function name includes the
90 // the leading underscore. In MinGW on the other hand, a decorated
91 // stdcall function still omits the underscore (IMPORT_NAME_NOPREFIX).
92 // See the comment in isDecorated in COFFModuleDefinition.cpp for more
93 // details.
94 if (ExtName.startswith("_") && ExtName.contains('@') && !MinGW)
95 return IMPORT_NAME;
96 if (Sym != ExtName)
98 if (Machine == IMAGE_FILE_MACHINE_I386 && Sym.startswith("_"))
100 return IMPORT_NAME;
101}
102
104 StringRef To) {
105 size_t Pos = S.find(From);
106
107 // From and To may be mangled, but substrings in S may not.
108 if (Pos == StringRef::npos && From.startswith("_") && To.startswith("_")) {
109 From = From.substr(1);
110 To = To.substr(1);
111 Pos = S.find(From);
112 }
113
114 if (Pos == StringRef::npos) {
115 return make_error<StringError>(
116 StringRef(Twine(S + ": replacing '" + From +
117 "' with '" + To + "' failed").str()), object_error::parse_failed);
118 }
119
120 return (Twine(S.substr(0, Pos)) + To + S.substr(Pos + From.size())).str();
121}
122
123static const std::string NullImportDescriptorSymbolName =
124 "__NULL_IMPORT_DESCRIPTOR";
125
126namespace {
127// This class constructs various small object files necessary to support linking
128// symbols imported from a DLL. The contents are pretty strictly defined and
129// nearly entirely static. The details of the structures files are defined in
130// WINNT.h and the PE/COFF specification.
131class ObjectFactory {
132 using u16 = support::ulittle16_t;
133 using u32 = support::ulittle32_t;
134 MachineTypes Machine;
135 BumpPtrAllocator Alloc;
136 StringRef ImportName;
137 StringRef Library;
138 std::string ImportDescriptorSymbolName;
139 std::string NullThunkSymbolName;
140
141public:
142 ObjectFactory(StringRef S, MachineTypes M)
143 : Machine(M), ImportName(S), Library(llvm::sys::path::stem(S)),
144 ImportDescriptorSymbolName(("__IMPORT_DESCRIPTOR_" + Library).str()),
145 NullThunkSymbolName(("\x7f" + Library + "_NULL_THUNK_DATA").str()) {}
146
147 // Creates an Import Descriptor. This is a small object file which contains a
148 // reference to the terminators and contains the library name (entry) for the
149 // import name table. It will force the linker to construct the necessary
150 // structure to import symbols from the DLL.
151 NewArchiveMember createImportDescriptor(std::vector<uint8_t> &Buffer);
152
153 // Creates a NULL import descriptor. This is a small object file whcih
154 // contains a NULL import descriptor. It is used to terminate the imports
155 // from a specific DLL.
156 NewArchiveMember createNullImportDescriptor(std::vector<uint8_t> &Buffer);
157
158 // Create a NULL Thunk Entry. This is a small object file which contains a
159 // NULL Import Address Table entry and a NULL Import Lookup Table Entry. It
160 // is used to terminate the IAT and ILT.
161 NewArchiveMember createNullThunk(std::vector<uint8_t> &Buffer);
162
163 // Create a short import file which is described in PE/COFF spec 7. Import
164 // Library Format.
165 NewArchiveMember createShortImport(StringRef Sym, uint16_t Ordinal,
167
168 // Create a weak external file which is described in PE/COFF Aux Format 3.
169 NewArchiveMember createWeakExternal(StringRef Sym, StringRef Weak, bool Imp);
170};
171} // namespace
172
174ObjectFactory::createImportDescriptor(std::vector<uint8_t> &Buffer) {
175 const uint32_t NumberOfSections = 2;
176 const uint32_t NumberOfSymbols = 7;
177 const uint32_t NumberOfRelocations = 3;
178
179 // COFF Header
180 coff_file_header Header{
181 u16(Machine),
182 u16(NumberOfSections),
183 u32(0),
184 u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section)) +
185 // .idata$2
187 NumberOfRelocations * sizeof(coff_relocation) +
188 // .idata$4
189 (ImportName.size() + 1)),
190 u32(NumberOfSymbols),
191 u16(0),
193 };
194 append(Buffer, Header);
195
196 // Section Header Table
197 const coff_section SectionTable[NumberOfSections] = {
198 {{'.', 'i', 'd', 'a', 't', 'a', '$', '2'},
199 u32(0),
200 u32(0),
202 u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section)),
203 u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section) +
205 u32(0),
206 u16(NumberOfRelocations),
207 u16(0),
210 {{'.', 'i', 'd', 'a', 't', 'a', '$', '6'},
211 u32(0),
212 u32(0),
213 u32(ImportName.size() + 1),
214 u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section) +
216 NumberOfRelocations * sizeof(coff_relocation)),
217 u32(0),
218 u32(0),
219 u16(0),
220 u16(0),
223 };
224 append(Buffer, SectionTable);
225
226 // .idata$2
227 const coff_import_directory_table_entry ImportDescriptor{
228 u32(0), u32(0), u32(0), u32(0), u32(0),
229 };
230 append(Buffer, ImportDescriptor);
231
232 const coff_relocation RelocationTable[NumberOfRelocations] = {
233 {u32(offsetof(coff_import_directory_table_entry, NameRVA)), u32(2),
234 u16(getImgRelRelocation(Machine))},
235 {u32(offsetof(coff_import_directory_table_entry, ImportLookupTableRVA)),
236 u32(3), u16(getImgRelRelocation(Machine))},
237 {u32(offsetof(coff_import_directory_table_entry, ImportAddressTableRVA)),
238 u32(4), u16(getImgRelRelocation(Machine))},
239 };
240 append(Buffer, RelocationTable);
241
242 // .idata$6
243 auto S = Buffer.size();
244 Buffer.resize(S + ImportName.size() + 1);
245 memcpy(&Buffer[S], ImportName.data(), ImportName.size());
246 Buffer[S + ImportName.size()] = '\0';
247
248 // Symbol Table
249 coff_symbol16 SymbolTable[NumberOfSymbols] = {
250 {{{0, 0, 0, 0, 0, 0, 0, 0}},
251 u32(0),
252 u16(1),
253 u16(0),
255 0},
256 {{{'.', 'i', 'd', 'a', 't', 'a', '$', '2'}},
257 u32(0),
258 u16(1),
259 u16(0),
261 0},
262 {{{'.', 'i', 'd', 'a', 't', 'a', '$', '6'}},
263 u32(0),
264 u16(2),
265 u16(0),
267 0},
268 {{{'.', 'i', 'd', 'a', 't', 'a', '$', '4'}},
269 u32(0),
270 u16(0),
271 u16(0),
273 0},
274 {{{'.', 'i', 'd', 'a', 't', 'a', '$', '5'}},
275 u32(0),
276 u16(0),
277 u16(0),
279 0},
280 {{{0, 0, 0, 0, 0, 0, 0, 0}},
281 u32(0),
282 u16(0),
283 u16(0),
285 0},
286 {{{0, 0, 0, 0, 0, 0, 0, 0}},
287 u32(0),
288 u16(0),
289 u16(0),
291 0},
292 };
293 // TODO: Name.Offset.Offset here and in the all similar places below
294 // suggests a names refactoring. Maybe StringTableOffset.Value?
295 SymbolTable[0].Name.Offset.Offset =
296 sizeof(uint32_t);
297 SymbolTable[5].Name.Offset.Offset =
298 sizeof(uint32_t) + ImportDescriptorSymbolName.length() + 1;
299 SymbolTable[6].Name.Offset.Offset =
300 sizeof(uint32_t) + ImportDescriptorSymbolName.length() + 1 +
302 append(Buffer, SymbolTable);
303
304 // String Table
305 writeStringTable(Buffer,
306 {ImportDescriptorSymbolName, NullImportDescriptorSymbolName,
307 NullThunkSymbolName});
308
309 StringRef F{reinterpret_cast<const char *>(Buffer.data()), Buffer.size()};
310 return {MemoryBufferRef(F, ImportName)};
311}
312
314ObjectFactory::createNullImportDescriptor(std::vector<uint8_t> &Buffer) {
315 const uint32_t NumberOfSections = 1;
316 const uint32_t NumberOfSymbols = 1;
317
318 // COFF Header
319 coff_file_header Header{
320 u16(Machine),
321 u16(NumberOfSections),
322 u32(0),
323 u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section)) +
324 // .idata$3
326 u32(NumberOfSymbols),
327 u16(0),
329 };
330 append(Buffer, Header);
331
332 // Section Header Table
333 const coff_section SectionTable[NumberOfSections] = {
334 {{'.', 'i', 'd', 'a', 't', 'a', '$', '3'},
335 u32(0),
336 u32(0),
338 u32(sizeof(coff_file_header) +
339 (NumberOfSections * sizeof(coff_section))),
340 u32(0),
341 u32(0),
342 u16(0),
343 u16(0),
346 };
347 append(Buffer, SectionTable);
348
349 // .idata$3
350 const coff_import_directory_table_entry ImportDescriptor{
351 u32(0), u32(0), u32(0), u32(0), u32(0),
352 };
353 append(Buffer, ImportDescriptor);
354
355 // Symbol Table
356 coff_symbol16 SymbolTable[NumberOfSymbols] = {
357 {{{0, 0, 0, 0, 0, 0, 0, 0}},
358 u32(0),
359 u16(1),
360 u16(0),
362 0},
363 };
364 SymbolTable[0].Name.Offset.Offset = sizeof(uint32_t);
365 append(Buffer, SymbolTable);
366
367 // String Table
369
370 StringRef F{reinterpret_cast<const char *>(Buffer.data()), Buffer.size()};
371 return {MemoryBufferRef(F, ImportName)};
372}
373
374NewArchiveMember ObjectFactory::createNullThunk(std::vector<uint8_t> &Buffer) {
375 const uint32_t NumberOfSections = 2;
376 const uint32_t NumberOfSymbols = 1;
377 uint32_t VASize = is64Bit(Machine) ? 8 : 4;
378
379 // COFF Header
380 coff_file_header Header{
381 u16(Machine),
382 u16(NumberOfSections),
383 u32(0),
384 u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section)) +
385 // .idata$5
386 VASize +
387 // .idata$4
388 VASize),
389 u32(NumberOfSymbols),
390 u16(0),
392 };
393 append(Buffer, Header);
394
395 // Section Header Table
396 const coff_section SectionTable[NumberOfSections] = {
397 {{'.', 'i', 'd', 'a', 't', 'a', '$', '5'},
398 u32(0),
399 u32(0),
400 u32(VASize),
401 u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section)),
402 u32(0),
403 u32(0),
404 u16(0),
405 u16(0),
406 u32((is64Bit(Machine) ? IMAGE_SCN_ALIGN_8BYTES
410 {{'.', 'i', 'd', 'a', 't', 'a', '$', '4'},
411 u32(0),
412 u32(0),
413 u32(VASize),
414 u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section) +
415 VASize),
416 u32(0),
417 u32(0),
418 u16(0),
419 u16(0),
420 u32((is64Bit(Machine) ? IMAGE_SCN_ALIGN_8BYTES
424 };
425 append(Buffer, SectionTable);
426
427 // .idata$5, ILT
428 append(Buffer, u32(0));
429 if (is64Bit(Machine))
430 append(Buffer, u32(0));
431
432 // .idata$4, IAT
433 append(Buffer, u32(0));
434 if (is64Bit(Machine))
435 append(Buffer, u32(0));
436
437 // Symbol Table
438 coff_symbol16 SymbolTable[NumberOfSymbols] = {
439 {{{0, 0, 0, 0, 0, 0, 0, 0}},
440 u32(0),
441 u16(1),
442 u16(0),
444 0},
445 };
446 SymbolTable[0].Name.Offset.Offset = sizeof(uint32_t);
447 append(Buffer, SymbolTable);
448
449 // String Table
450 writeStringTable(Buffer, {NullThunkSymbolName});
451
452 StringRef F{reinterpret_cast<const char *>(Buffer.data()), Buffer.size()};
453 return {MemoryBufferRef{F, ImportName}};
454}
455
456NewArchiveMember ObjectFactory::createShortImport(StringRef Sym,
457 uint16_t Ordinal,
460 size_t ImpSize = ImportName.size() + Sym.size() + 2; // +2 for NULs
461 size_t Size = sizeof(coff_import_header) + ImpSize;
462 char *Buf = Alloc.Allocate<char>(Size);
463 memset(Buf, 0, Size);
464 char *P = Buf;
465
466 // Write short import library.
467 auto *Imp = reinterpret_cast<coff_import_header *>(P);
468 P += sizeof(*Imp);
469 Imp->Sig2 = 0xFFFF;
470 Imp->Machine = Machine;
471 Imp->SizeOfData = ImpSize;
472 if (Ordinal > 0)
473 Imp->OrdinalHint = Ordinal;
474 Imp->TypeInfo = (NameType << 2) | ImportType;
475
476 // Write symbol name and DLL name.
477 memcpy(P, Sym.data(), Sym.size());
478 P += Sym.size() + 1;
479 memcpy(P, ImportName.data(), ImportName.size());
480
481 return {MemoryBufferRef(StringRef(Buf, Size), ImportName)};
482}
483
484NewArchiveMember ObjectFactory::createWeakExternal(StringRef Sym,
485 StringRef Weak, bool Imp) {
486 std::vector<uint8_t> Buffer;
487 const uint32_t NumberOfSections = 1;
488 const uint32_t NumberOfSymbols = 5;
489
490 // COFF Header
491 coff_file_header Header{
492 u16(Machine),
493 u16(NumberOfSections),
494 u32(0),
495 u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section))),
496 u32(NumberOfSymbols),
497 u16(0),
498 u16(0),
499 };
500 append(Buffer, Header);
501
502 // Section Header Table
503 const coff_section SectionTable[NumberOfSections] = {
504 {{'.', 'd', 'r', 'e', 'c', 't', 'v', 'e'},
505 u32(0),
506 u32(0),
507 u32(0),
508 u32(0),
509 u32(0),
510 u32(0),
511 u16(0),
512 u16(0),
514 append(Buffer, SectionTable);
515
516 // Symbol Table
517 coff_symbol16 SymbolTable[NumberOfSymbols] = {
518 {{{'@', 'c', 'o', 'm', 'p', '.', 'i', 'd'}},
519 u32(0),
520 u16(0xFFFF),
521 u16(0),
523 0},
524 {{{'@', 'f', 'e', 'a', 't', '.', '0', '0'}},
525 u32(0),
526 u16(0xFFFF),
527 u16(0),
529 0},
530 {{{0, 0, 0, 0, 0, 0, 0, 0}},
531 u32(0),
532 u16(0),
533 u16(0),
535 0},
536 {{{0, 0, 0, 0, 0, 0, 0, 0}},
537 u32(0),
538 u16(0),
539 u16(0),
541 1},
542 {{{2, 0, 0, 0, IMAGE_WEAK_EXTERN_SEARCH_ALIAS, 0, 0, 0}},
543 u32(0),
544 u16(0),
545 u16(0),
547 0},
548 };
549 SymbolTable[2].Name.Offset.Offset = sizeof(uint32_t);
550
551 //__imp_ String Table
552 StringRef Prefix = Imp ? "__imp_" : "";
553 SymbolTable[3].Name.Offset.Offset =
554 sizeof(uint32_t) + Sym.size() + Prefix.size() + 1;
555 append(Buffer, SymbolTable);
556 writeStringTable(Buffer, {(Prefix + Sym).str(),
557 (Prefix + Weak).str()});
558
559 // Copied here so we can still use writeStringTable
560 char *Buf = Alloc.Allocate<char>(Buffer.size());
561 memcpy(Buf, Buffer.data(), Buffer.size());
562 return {MemoryBufferRef(StringRef(Buf, Buffer.size()), ImportName)};
563}
564
567 MachineTypes Machine, bool MinGW) {
568
569 std::vector<NewArchiveMember> Members;
570 ObjectFactory OF(llvm::sys::path::filename(ImportName), Machine);
571
572 std::vector<uint8_t> ImportDescriptor;
573 Members.push_back(OF.createImportDescriptor(ImportDescriptor));
574
575 std::vector<uint8_t> NullImportDescriptor;
576 Members.push_back(OF.createNullImportDescriptor(NullImportDescriptor));
577
578 std::vector<uint8_t> NullThunk;
579 Members.push_back(OF.createNullThunk(NullThunk));
580
581 for (const COFFShortExport &E : Exports) {
582 if (E.Private)
583 continue;
584
586 if (E.Data)
588 if (E.Constant)
590
591 StringRef SymbolName = E.SymbolName.empty() ? E.Name : E.SymbolName;
592 ImportNameType NameType = E.Noname
594 : getNameType(SymbolName, E.Name,
595 Machine, MinGW);
596 Expected<std::string> Name = E.ExtName.empty()
597 ? std::string(SymbolName)
598 : replace(SymbolName, E.Name, E.ExtName);
599
600 if (!Name)
601 return Name.takeError();
602
603 if (!E.AliasTarget.empty() && *Name != E.AliasTarget) {
604 Members.push_back(OF.createWeakExternal(E.AliasTarget, *Name, false));
605 Members.push_back(OF.createWeakExternal(E.AliasTarget, *Name, true));
606 continue;
607 }
608
609 Members.push_back(
610 OF.createShortImport(*Name, E.Ordinal, ImportType, NameType));
611 }
612
613 return writeArchive(Path, Members, SymtabWritingMode::NormalSymtab,
615 /*Deterministic*/ true, /*Thin*/ false);
616}
617
618} // namespace object
619} // 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
Symbol * Sym
Definition: ELF_riscv.cpp:468
#define F(x, y, z)
Definition: MD5.cpp:55
#define P(N)
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:160
Tagged union holding either a T or a Error.
Definition: Error.h:474
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:575
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:428
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:301
static constexpr size_t npos
Definition: StringRef.h:52
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:104
@ IMAGE_FILE_MACHINE_ARM64X
Definition: COFF.h:102
@ IMAGE_FILE_MACHINE_ARMNT
Definition: COFF.h:99
@ IMAGE_SCN_LNK_REMOVE
Definition: COFF.h:307
@ IMAGE_SCN_MEM_READ
Definition: COFF.h:335
@ IMAGE_SCN_LNK_INFO
Definition: COFF.h:306
@ IMAGE_SCN_CNT_INITIALIZED_DATA
Definition: COFF.h:303
@ IMAGE_SCN_ALIGN_8BYTES
Definition: COFF.h:317
@ IMAGE_SCN_ALIGN_4BYTES
Definition: COFF.h:316
@ IMAGE_SCN_ALIGN_2BYTES
Definition: COFF.h:315
@ IMAGE_SCN_MEM_WRITE
Definition: COFF.h:336
ImportType
Definition: COFF.h:700
@ IMPORT_CONST
Definition: COFF.h:703
@ IMPORT_CODE
Definition: COFF.h:701
@ IMPORT_DATA
Definition: COFF.h:702
@ IMAGE_REL_ARM64_ADDR32NB
Definition: COFF.h:402
@ IMAGE_REL_AMD64_ADDR32NB
Definition: COFF.h:363
@ IMAGE_SYM_CLASS_SECTION
Line number, reformatted as symbol.
Definition: COFF.h:247
@ IMAGE_SYM_CLASS_EXTERNAL
External symbol.
Definition: COFF.h:223
@ IMAGE_SYM_CLASS_NULL
No symbol.
Definition: COFF.h:221
@ IMAGE_SYM_CLASS_WEAK_EXTERNAL
Duplicate tag.
Definition: COFF.h:248
@ IMAGE_SYM_CLASS_STATIC
Static.
Definition: COFF.h:224
@ IMAGE_WEAK_EXTERN_SEARCH_ALIAS
Definition: COFF.h:456
bool is64Bit(T Machine)
Definition: COFF.h:133
@ IMAGE_REL_ARM_ADDR32NB
Definition: COFF.h:382
ImportNameType
Definition: COFF.h:706
@ IMPORT_ORDINAL
Import is by ordinal.
Definition: COFF.h:711
@ IMPORT_NAME
The import name is identical to the public symbol name.
Definition: COFF.h:713
@ IMPORT_NAME_UNDECORATE
The import name is the public symbol name, but skipping the leading ?, @, or optionally _,...
Definition: COFF.h:719
@ IMPORT_NAME_NOPREFIX
The import name is the public symbol name, but skipping the leading ?, @, or optionally _.
Definition: COFF.h:716
@ IMAGE_REL_I386_DIR32NB
Definition: COFF.h:350
@ C_Invalid
Definition: COFF.h:138
@ IMAGE_FILE_32BIT_MACHINE
Machine is based on a 32bit word architecture.
Definition: COFF.h:159
static void append(std::vector< uint8_t > &B, const T &Data)
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:414
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 stem(StringRef path, Style style=Style::native)
Get stem.
Definition: Path.cpp:581
StringRef filename(StringRef path, Style style=Style::native)
Get filename.
Definition: Path.cpp:579
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:440
@ Length
Definition: DWP.cpp:440
Error writeArchive(StringRef ArcName, ArrayRef< NewArchiveMember > NewMembers, SymtabWritingMode WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin, std::unique_ptr< MemoryBuffer > OldArchiveBuf=nullptr, bool IsEC=false)
support::ulittle32_t Offset
Definition: COFF.h:246
Definition: COFF.h:555
union llvm::object::coff_symbol::@342 Name
StringTableOffset Offset
Definition: COFF.h:253