LLVM 19.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 (getMachine()) {
39 return "COFF-import-file-i386";
41 return "COFF-import-file-x86-64";
43 return "COFF-import-file-ARM";
45 return "COFF-import-file-ARM64";
47 return "COFF-import-file-ARM64EC";
49 return "COFF-import-file-ARM64X";
50 default:
51 return "COFF-import-file-<unknown arch>";
52 }
53}
54
57 StringRef name = Data.getBuffer().substr(sizeof(*hdr)).split('\0').first;
58
59 auto ltrim1 = [](StringRef s, StringRef chars) {
60 return !s.empty() && chars.contains(s[0]) ? s.substr(1) : s;
61 };
62
63 switch (hdr->getNameType()) {
64 case IMPORT_ORDINAL:
65 name = "";
66 break;
68 name = ltrim1(name, "?@_");
69 break;
71 name = ltrim1(name, "?@_");
72 name = name.substr(0, name.find('@'));
73 break;
75 // Skip DLL name
76 name = Data.getBuffer().substr(sizeof(*hdr) + name.size() + 1);
77 name = name.split('\0').second.split('\0').first;
78 break;
79 }
80 default:
81 break;
82 }
83
84 return name;
85}
86
88 switch (Machine) {
89 default:
90 llvm_unreachable("unsupported machine");
101 }
102}
103
104template <class T> static void append(std::vector<uint8_t> &B, const T &Data) {
105 size_t S = B.size();
106 B.resize(S + sizeof(T));
107 memcpy(&B[S], &Data, sizeof(T));
108}
109
110static void writeStringTable(std::vector<uint8_t> &B,
112 // The COFF string table consists of a 4-byte value which is the size of the
113 // table, including the length field itself. This value is followed by the
114 // string content itself, which is an array of null-terminated C-style
115 // strings. The termination is important as they are referenced to by offset
116 // by the symbol entity in the file format.
117
118 size_t Pos = B.size();
119 size_t Offset = B.size();
120
121 // Skip over the length field, we will fill it in later as we will have
122 // computed the length while emitting the string content itself.
123 Pos += sizeof(uint32_t);
124
125 for (const auto &S : Strings) {
126 B.resize(Pos + S.length() + 1);
127 std::copy(S.begin(), S.end(), std::next(B.begin(), Pos));
128 B[Pos + S.length()] = 0;
129 Pos += S.length() + 1;
130 }
131
132 // Backfill the length of the table now that it has been computed.
135}
136
138 MachineTypes Machine, bool MinGW) {
139 // A decorated stdcall function in MSVC is exported with the
140 // type IMPORT_NAME, and the exported function name includes the
141 // the leading underscore. In MinGW on the other hand, a decorated
142 // stdcall function still omits the underscore (IMPORT_NAME_NOPREFIX).
143 // See the comment in isDecorated in COFFModuleDefinition.cpp for more
144 // details.
145 if (ExtName.starts_with("_") && ExtName.contains('@') && !MinGW)
146 return IMPORT_NAME;
147 if (Sym != ExtName)
149 if (Machine == IMAGE_FILE_MACHINE_I386 && Sym.starts_with("_"))
151 return IMPORT_NAME;
152}
153
155 StringRef To) {
156 size_t Pos = S.find(From);
157
158 // From and To may be mangled, but substrings in S may not.
159 if (Pos == StringRef::npos && From.starts_with("_") && To.starts_with("_")) {
160 From = From.substr(1);
161 To = To.substr(1);
162 Pos = S.find(From);
163 }
164
165 if (Pos == StringRef::npos) {
166 return make_error<StringError>(
167 StringRef(Twine(S + ": replacing '" + From +
168 "' with '" + To + "' failed").str()), object_error::parse_failed);
169 }
170
171 return (Twine(S.substr(0, Pos)) + To + S.substr(Pos + From.size())).str();
172}
173
174static const std::string NullImportDescriptorSymbolName =
175 "__NULL_IMPORT_DESCRIPTOR";
176
177namespace {
178// This class constructs various small object files necessary to support linking
179// symbols imported from a DLL. The contents are pretty strictly defined and
180// nearly entirely static. The details of the structures files are defined in
181// WINNT.h and the PE/COFF specification.
182class ObjectFactory {
183 using u16 = support::ulittle16_t;
184 using u32 = support::ulittle32_t;
185 MachineTypes NativeMachine;
186 BumpPtrAllocator Alloc;
187 StringRef ImportName;
188 StringRef Library;
189 std::string ImportDescriptorSymbolName;
190 std::string NullThunkSymbolName;
191
192public:
193 ObjectFactory(StringRef S, MachineTypes M)
194 : NativeMachine(M), ImportName(S), Library(llvm::sys::path::stem(S)),
195 ImportDescriptorSymbolName(("__IMPORT_DESCRIPTOR_" + Library).str()),
196 NullThunkSymbolName(("\x7f" + Library + "_NULL_THUNK_DATA").str()) {}
197
198 // Creates an Import Descriptor. This is a small object file which contains a
199 // reference to the terminators and contains the library name (entry) for the
200 // import name table. It will force the linker to construct the necessary
201 // structure to import symbols from the DLL.
202 NewArchiveMember createImportDescriptor(std::vector<uint8_t> &Buffer);
203
204 // Creates a NULL import descriptor. This is a small object file whcih
205 // contains a NULL import descriptor. It is used to terminate the imports
206 // from a specific DLL.
207 NewArchiveMember createNullImportDescriptor(std::vector<uint8_t> &Buffer);
208
209 // Create a NULL Thunk Entry. This is a small object file which contains a
210 // NULL Import Address Table entry and a NULL Import Lookup Table Entry. It
211 // is used to terminate the IAT and ILT.
212 NewArchiveMember createNullThunk(std::vector<uint8_t> &Buffer);
213
214 // Create a short import file which is described in PE/COFF spec 7. Import
215 // Library Format.
216 NewArchiveMember createShortImport(StringRef Sym, uint16_t Ordinal,
218 StringRef ExportName,
220
221 // Create a weak external file which is described in PE/COFF Aux Format 3.
222 NewArchiveMember createWeakExternal(StringRef Sym, StringRef Weak, bool Imp,
224
225 bool is64Bit() const { return COFF::is64Bit(NativeMachine); }
226};
227} // namespace
228
230ObjectFactory::createImportDescriptor(std::vector<uint8_t> &Buffer) {
231 const uint32_t NumberOfSections = 2;
232 const uint32_t NumberOfSymbols = 7;
233 const uint32_t NumberOfRelocations = 3;
234
235 // COFF Header
236 coff_file_header Header{
237 u16(NativeMachine),
238 u16(NumberOfSections),
239 u32(0),
240 u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section)) +
241 // .idata$2
243 NumberOfRelocations * sizeof(coff_relocation) +
244 // .idata$4
245 (ImportName.size() + 1)),
246 u32(NumberOfSymbols),
247 u16(0),
249 };
250 append(Buffer, Header);
251
252 // Section Header Table
253 const coff_section SectionTable[NumberOfSections] = {
254 {{'.', 'i', 'd', 'a', 't', 'a', '$', '2'},
255 u32(0),
256 u32(0),
258 u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section)),
259 u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section) +
261 u32(0),
262 u16(NumberOfRelocations),
263 u16(0),
266 {{'.', 'i', 'd', 'a', 't', 'a', '$', '6'},
267 u32(0),
268 u32(0),
269 u32(ImportName.size() + 1),
270 u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section) +
272 NumberOfRelocations * sizeof(coff_relocation)),
273 u32(0),
274 u32(0),
275 u16(0),
276 u16(0),
279 };
280 append(Buffer, SectionTable);
281
282 // .idata$2
283 const coff_import_directory_table_entry ImportDescriptor{
284 u32(0), u32(0), u32(0), u32(0), u32(0),
285 };
286 append(Buffer, ImportDescriptor);
287
288 const coff_relocation RelocationTable[NumberOfRelocations] = {
289 {u32(offsetof(coff_import_directory_table_entry, NameRVA)), u32(2),
290 u16(getImgRelRelocation(NativeMachine))},
291 {u32(offsetof(coff_import_directory_table_entry, ImportLookupTableRVA)),
292 u32(3), u16(getImgRelRelocation(NativeMachine))},
293 {u32(offsetof(coff_import_directory_table_entry, ImportAddressTableRVA)),
294 u32(4), u16(getImgRelRelocation(NativeMachine))},
295 };
296 append(Buffer, RelocationTable);
297
298 // .idata$6
299 auto S = Buffer.size();
300 Buffer.resize(S + ImportName.size() + 1);
301 memcpy(&Buffer[S], ImportName.data(), ImportName.size());
302 Buffer[S + ImportName.size()] = '\0';
303
304 // Symbol Table
305 coff_symbol16 SymbolTable[NumberOfSymbols] = {
306 {{{0, 0, 0, 0, 0, 0, 0, 0}},
307 u32(0),
308 u16(1),
309 u16(0),
311 0},
312 {{{'.', 'i', 'd', 'a', 't', 'a', '$', '2'}},
313 u32(0),
314 u16(1),
315 u16(0),
317 0},
318 {{{'.', 'i', 'd', 'a', 't', 'a', '$', '6'}},
319 u32(0),
320 u16(2),
321 u16(0),
323 0},
324 {{{'.', 'i', 'd', 'a', 't', 'a', '$', '4'}},
325 u32(0),
326 u16(0),
327 u16(0),
329 0},
330 {{{'.', 'i', 'd', 'a', 't', 'a', '$', '5'}},
331 u32(0),
332 u16(0),
333 u16(0),
335 0},
336 {{{0, 0, 0, 0, 0, 0, 0, 0}},
337 u32(0),
338 u16(0),
339 u16(0),
341 0},
342 {{{0, 0, 0, 0, 0, 0, 0, 0}},
343 u32(0),
344 u16(0),
345 u16(0),
347 0},
348 };
349 // TODO: Name.Offset.Offset here and in the all similar places below
350 // suggests a names refactoring. Maybe StringTableOffset.Value?
351 SymbolTable[0].Name.Offset.Offset =
352 sizeof(uint32_t);
353 SymbolTable[5].Name.Offset.Offset =
354 sizeof(uint32_t) + ImportDescriptorSymbolName.length() + 1;
355 SymbolTable[6].Name.Offset.Offset =
356 sizeof(uint32_t) + ImportDescriptorSymbolName.length() + 1 +
358 append(Buffer, SymbolTable);
359
360 // String Table
361 writeStringTable(Buffer,
362 {ImportDescriptorSymbolName, NullImportDescriptorSymbolName,
363 NullThunkSymbolName});
364
365 StringRef F{reinterpret_cast<const char *>(Buffer.data()), Buffer.size()};
366 return {MemoryBufferRef(F, ImportName)};
367}
368
370ObjectFactory::createNullImportDescriptor(std::vector<uint8_t> &Buffer) {
371 const uint32_t NumberOfSections = 1;
372 const uint32_t NumberOfSymbols = 1;
373
374 // COFF Header
375 coff_file_header Header{
376 u16(NativeMachine),
377 u16(NumberOfSections),
378 u32(0),
379 u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section)) +
380 // .idata$3
382 u32(NumberOfSymbols),
383 u16(0),
385 };
386 append(Buffer, Header);
387
388 // Section Header Table
389 const coff_section SectionTable[NumberOfSections] = {
390 {{'.', 'i', 'd', 'a', 't', 'a', '$', '3'},
391 u32(0),
392 u32(0),
394 u32(sizeof(coff_file_header) +
395 (NumberOfSections * sizeof(coff_section))),
396 u32(0),
397 u32(0),
398 u16(0),
399 u16(0),
402 };
403 append(Buffer, SectionTable);
404
405 // .idata$3
406 const coff_import_directory_table_entry ImportDescriptor{
407 u32(0), u32(0), u32(0), u32(0), u32(0),
408 };
409 append(Buffer, ImportDescriptor);
410
411 // Symbol Table
412 coff_symbol16 SymbolTable[NumberOfSymbols] = {
413 {{{0, 0, 0, 0, 0, 0, 0, 0}},
414 u32(0),
415 u16(1),
416 u16(0),
418 0},
419 };
420 SymbolTable[0].Name.Offset.Offset = sizeof(uint32_t);
421 append(Buffer, SymbolTable);
422
423 // String Table
425
426 StringRef F{reinterpret_cast<const char *>(Buffer.data()), Buffer.size()};
427 return {MemoryBufferRef(F, ImportName)};
428}
429
430NewArchiveMember ObjectFactory::createNullThunk(std::vector<uint8_t> &Buffer) {
431 const uint32_t NumberOfSections = 2;
432 const uint32_t NumberOfSymbols = 1;
433 uint32_t VASize = is64Bit() ? 8 : 4;
434
435 // COFF Header
436 coff_file_header Header{
437 u16(NativeMachine),
438 u16(NumberOfSections),
439 u32(0),
440 u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section)) +
441 // .idata$5
442 VASize +
443 // .idata$4
444 VASize),
445 u32(NumberOfSymbols),
446 u16(0),
448 };
449 append(Buffer, Header);
450
451 // Section Header Table
452 const coff_section SectionTable[NumberOfSections] = {
453 {{'.', 'i', 'd', 'a', 't', 'a', '$', '5'},
454 u32(0),
455 u32(0),
456 u32(VASize),
457 u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section)),
458 u32(0),
459 u32(0),
460 u16(0),
461 u16(0),
465 {{'.', 'i', 'd', 'a', 't', 'a', '$', '4'},
466 u32(0),
467 u32(0),
468 u32(VASize),
469 u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section) +
470 VASize),
471 u32(0),
472 u32(0),
473 u16(0),
474 u16(0),
478 };
479 append(Buffer, SectionTable);
480
481 // .idata$5, ILT
482 append(Buffer, u32(0));
483 if (is64Bit())
484 append(Buffer, u32(0));
485
486 // .idata$4, IAT
487 append(Buffer, u32(0));
488 if (is64Bit())
489 append(Buffer, u32(0));
490
491 // Symbol Table
492 coff_symbol16 SymbolTable[NumberOfSymbols] = {
493 {{{0, 0, 0, 0, 0, 0, 0, 0}},
494 u32(0),
495 u16(1),
496 u16(0),
498 0},
499 };
500 SymbolTable[0].Name.Offset.Offset = sizeof(uint32_t);
501 append(Buffer, SymbolTable);
502
503 // String Table
504 writeStringTable(Buffer, {NullThunkSymbolName});
505
506 StringRef F{reinterpret_cast<const char *>(Buffer.data()), Buffer.size()};
507 return {MemoryBufferRef{F, ImportName}};
508}
509
511ObjectFactory::createShortImport(StringRef Sym, uint16_t Ordinal,
513 StringRef ExportName, MachineTypes Machine) {
514 size_t ImpSize = ImportName.size() + Sym.size() + 2; // +2 for NULs
515 if (!ExportName.empty())
516 ImpSize += ExportName.size() + 1;
517 size_t Size = sizeof(coff_import_header) + ImpSize;
518 char *Buf = Alloc.Allocate<char>(Size);
519 memset(Buf, 0, Size);
520 char *P = Buf;
521
522 // Write short import library.
523 auto *Imp = reinterpret_cast<coff_import_header *>(P);
524 P += sizeof(*Imp);
525 Imp->Sig2 = 0xFFFF;
526 Imp->Machine = Machine;
527 Imp->SizeOfData = ImpSize;
528 if (Ordinal > 0)
529 Imp->OrdinalHint = Ordinal;
530 Imp->TypeInfo = (NameType << 2) | ImportType;
531
532 // Write symbol name and DLL name.
533 memcpy(P, Sym.data(), Sym.size());
534 P += Sym.size() + 1;
535 memcpy(P, ImportName.data(), ImportName.size());
536 if (!ExportName.empty()) {
537 P += ImportName.size() + 1;
538 memcpy(P, ExportName.data(), ExportName.size());
539 }
540
541 return {MemoryBufferRef(StringRef(Buf, Size), ImportName)};
542}
543
544NewArchiveMember ObjectFactory::createWeakExternal(StringRef Sym,
545 StringRef Weak, bool Imp,
547 std::vector<uint8_t> Buffer;
548 const uint32_t NumberOfSections = 1;
549 const uint32_t NumberOfSymbols = 5;
550
551 // COFF Header
552 coff_file_header Header{
553 u16(Machine),
554 u16(NumberOfSections),
555 u32(0),
556 u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section))),
557 u32(NumberOfSymbols),
558 u16(0),
559 u16(0),
560 };
561 append(Buffer, Header);
562
563 // Section Header Table
564 const coff_section SectionTable[NumberOfSections] = {
565 {{'.', 'd', 'r', 'e', 'c', 't', 'v', 'e'},
566 u32(0),
567 u32(0),
568 u32(0),
569 u32(0),
570 u32(0),
571 u32(0),
572 u16(0),
573 u16(0),
575 append(Buffer, SectionTable);
576
577 // Symbol Table
578 coff_symbol16 SymbolTable[NumberOfSymbols] = {
579 {{{'@', 'c', 'o', 'm', 'p', '.', 'i', 'd'}},
580 u32(0),
581 u16(0xFFFF),
582 u16(0),
584 0},
585 {{{'@', 'f', 'e', 'a', 't', '.', '0', '0'}},
586 u32(0),
587 u16(0xFFFF),
588 u16(0),
590 0},
591 {{{0, 0, 0, 0, 0, 0, 0, 0}},
592 u32(0),
593 u16(0),
594 u16(0),
596 0},
597 {{{0, 0, 0, 0, 0, 0, 0, 0}},
598 u32(0),
599 u16(0),
600 u16(0),
602 1},
603 {{{2, 0, 0, 0, IMAGE_WEAK_EXTERN_SEARCH_ALIAS, 0, 0, 0}},
604 u32(0),
605 u16(0),
606 u16(0),
608 0},
609 };
610 SymbolTable[2].Name.Offset.Offset = sizeof(uint32_t);
611
612 //__imp_ String Table
613 StringRef Prefix = Imp ? "__imp_" : "";
614 SymbolTable[3].Name.Offset.Offset =
615 sizeof(uint32_t) + Sym.size() + Prefix.size() + 1;
616 append(Buffer, SymbolTable);
617 writeStringTable(Buffer, {(Prefix + Sym).str(),
618 (Prefix + Weak).str()});
619
620 // Copied here so we can still use writeStringTable
621 char *Buf = Alloc.Allocate<char>(Buffer.size());
622 memcpy(Buf, Buffer.data(), Buffer.size());
623 return {MemoryBufferRef(StringRef(Buf, Buffer.size()), ImportName)};
624}
625
628 MachineTypes Machine, bool MinGW,
629 ArrayRef<COFFShortExport> NativeExports) {
630
631 MachineTypes NativeMachine =
633
634 std::vector<NewArchiveMember> Members;
635 ObjectFactory OF(llvm::sys::path::filename(ImportName), NativeMachine);
636
637 std::vector<uint8_t> ImportDescriptor;
638 Members.push_back(OF.createImportDescriptor(ImportDescriptor));
639
640 std::vector<uint8_t> NullImportDescriptor;
641 Members.push_back(OF.createNullImportDescriptor(NullImportDescriptor));
642
643 std::vector<uint8_t> NullThunk;
644 Members.push_back(OF.createNullThunk(NullThunk));
645
646 auto addExports = [&](ArrayRef<COFFShortExport> Exp,
647 MachineTypes M) -> Error {
648 for (const COFFShortExport &E : Exp) {
649 if (E.Private)
650 continue;
651
653 if (E.Data)
655 if (E.Constant)
657
658 StringRef SymbolName = E.SymbolName.empty() ? E.Name : E.SymbolName;
659 std::string Name;
660
661 if (E.ExtName.empty()) {
662 Name = std::string(SymbolName);
663 } else {
664 Expected<std::string> ReplacedName =
665 replace(SymbolName, E.Name, E.ExtName);
666 if (!ReplacedName)
667 return ReplacedName.takeError();
668 Name.swap(*ReplacedName);
669 }
670
671 if (!E.AliasTarget.empty() && Name != E.AliasTarget) {
672 Members.push_back(OF.createWeakExternal(E.AliasTarget, Name, false, M));
673 Members.push_back(OF.createWeakExternal(E.AliasTarget, Name, true, M));
674 continue;
675 }
676
678 std::string ExportName;
679 if (E.Noname) {
681 } else if (!E.ExportAs.empty()) {
683 ExportName = E.ExportAs;
684 } else {
685 NameType = getNameType(SymbolName, E.Name, M, MinGW);
686 }
687
688 // On ARM64EC, use EXPORTAS to import demangled name for mangled symbols.
689 if (ImportType == IMPORT_CODE && isArm64EC(M)) {
690 if (std::optional<std::string> MangledName =
692 if (ExportName.empty()) {
694 ExportName.swap(Name);
695 }
696 Name = std::move(*MangledName);
697 } else if (ExportName.empty()) {
699 ExportName = std::move(*getArm64ECDemangledFunctionName(Name));
700 }
701 }
702
703 Members.push_back(OF.createShortImport(Name, E.Ordinal, ImportType,
704 NameType, ExportName, M));
705 }
706 return Error::success();
707 };
708
709 if (Error e = addExports(Exports, Machine))
710 return e;
711 if (Error e = addExports(NativeExports, NativeMachine))
712 return e;
713
714 return writeArchive(Path, Members, SymtabWritingMode::NormalSymtab,
716 /*Deterministic*/ true, /*Thin*/ false,
717 /*OldArchiveBuf*/ nullptr, isArm64EC(Machine));
718}
719
720} // namespace object
721} // 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")
COFF::MachineTypes Machine
Definition: COFFYAML.cpp:371
std::string Name
uint64_t Size
Symbol * Sym
Definition: ELF_riscv.cpp:479
#define F(x, y, z)
Definition: MD5.cpp:55
#define P(N)
static const char * name
Definition: SMEABIPass.cpp:49
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
static ErrorSuccess success()
Create a success value.
Definition: Error.h:334
Tagged union holding either a T or a Error.
Definition: Error.h:474
Error takeError()
Take ownership of the stored error.
Definition: Error.h:601
StringRef getBuffer() const
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:696
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:567
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:257
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:131
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
Definition: StringRef.h:420
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:293
static constexpr size_t npos
Definition: StringRef.h:52
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
MemoryBufferRef Data
Definition: Binary.h:37
const coff_import_header * getCOFFImportHeader() const
StringRef getFileFormatName() const
StringRef getExportName() const
#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
bool isArm64EC(T Machine)
Definition: COFF.h:124
ImportNameType
Definition: COFF.h:706
@ IMPORT_ORDINAL
Import is by ordinal.
Definition: COFF.h:711
@ IMPORT_NAME_EXPORTAS
The import name is specified as a separate string in the import library object file.
Definition: COFF.h:722
@ 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)
std::optional< std::string > getArm64ECMangledFunctionName(StringRef Name)
Definition: COFF.h:1366
Error writeImportLibrary(StringRef ImportName, StringRef Path, ArrayRef< COFFShortExport > Exports, COFF::MachineTypes Machine, bool MinGW, ArrayRef< COFFShortExport > NativeExports=std::nullopt)
Writes a COFF import library containing entries described by the Exports array.
static Expected< std::string > replace(StringRef S, StringRef From, StringRef To)
std::optional< std::string > getArm64ECDemangledFunctionName(StringRef Name)
Definition: COFF.h:1394
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)
void write32le(void *P, uint32_t V)
Definition: Endian.h:452
detail::packed_endian_specific_integral< uint16_t, llvm::endianness::little, unaligned > ulittle16_t
Definition: Endian.h:266
detail::packed_endian_specific_integral< uint32_t, llvm::endianness::little, unaligned > ulittle32_t
Definition: Endian.h:269
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:456
@ Length
Definition: DWP.cpp:456
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
StringTableOffset Offset
Definition: COFF.h:253
union llvm::object::coff_symbol::@344 Name