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";
51 return "COFF-import-file-<unknown arch>";
60 return !s.
empty() && chars.contains(s[0]) ? s.
substr(1) : s;
77 name =
name.split(
'\0').second.split(
'\0').first;
98 if (std::optional<std::string> DemangledName =
125template <
class T>
static void append(std::vector<uint8_t> &
B,
const T &
Data) {
127 B.resize(S +
sizeof(
T));
128 memcpy(&
B[S], &
Data,
sizeof(
T));
139 size_t Pos =
B.size();
146 for (
const auto &S : Strings) {
147 B.resize(Pos + S.length() + 1);
148 std::copy(S.begin(), S.end(), std::next(
B.begin(), Pos));
149 B[Pos + S.length()] = 0;
150 Pos += S.length() + 1;
187 return make_error<StringError>(
207 std::string ImportDescriptorSymbolName;
208 std::string NullThunkSymbolName;
212 : NativeMachine(M), ImportName(S), Library(
llvm::sys::path::stem(S)),
249ObjectFactory::createImportDescriptor(std::vector<uint8_t> &Buffer) {
250 const uint32_t NumberOfSections = 2;
252 const uint32_t NumberOfRelocations = 3;
257 u16(NumberOfSections),
259 u32(
sizeof(Header) + (NumberOfSections *
sizeof(
coff_section)) +
264 (ImportName.
size() + 1)),
265 u32(NumberOfSymbols),
273 {{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'2'},
281 u16(NumberOfRelocations),
285 {{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'6'},
288 u32(ImportName.
size() + 1),
299 append(Buffer, SectionTable);
303 u32(0), u32(0), u32(0), u32(0), u32(0),
305 append(Buffer, ImportDescriptor);
315 append(Buffer, RelocationTable);
318 auto S = Buffer.size();
319 Buffer.resize(S + ImportName.
size() + 1);
320 memcpy(&Buffer[S], ImportName.
data(), ImportName.
size());
321 Buffer[S + ImportName.
size()] =
'\0';
325 {{{0, 0, 0, 0, 0, 0, 0, 0}},
331 {{{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'2'}},
337 {{{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'6'}},
343 {{{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'4'}},
349 {{{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'5'}},
355 {{{0, 0, 0, 0, 0, 0, 0, 0}},
361 {{{0, 0, 0, 0, 0, 0, 0, 0}},
373 sizeof(
uint32_t) + ImportDescriptorSymbolName.length() + 1;
375 sizeof(
uint32_t) + ImportDescriptorSymbolName.length() + 1 +
377 append(Buffer, SymbolTable);
382 NullThunkSymbolName});
384 StringRef F{
reinterpret_cast<const char *
>(Buffer.data()), Buffer.size()};
389ObjectFactory::createNullImportDescriptor(std::vector<uint8_t> &Buffer) {
390 const uint32_t NumberOfSections = 1;
396 u16(NumberOfSections),
398 u32(
sizeof(Header) + (NumberOfSections *
sizeof(
coff_section)) +
401 u32(NumberOfSymbols),
409 {{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'3'},
422 append(Buffer, SectionTable);
426 u32(0), u32(0), u32(0), u32(0), u32(0),
428 append(Buffer, ImportDescriptor);
432 {{{0, 0, 0, 0, 0, 0, 0, 0}},
440 append(Buffer, SymbolTable);
445 StringRef F{
reinterpret_cast<const char *
>(Buffer.data()), Buffer.size()};
449NewArchiveMember ObjectFactory::createNullThunk(std::vector<uint8_t> &Buffer) {
450 const uint32_t NumberOfSections = 2;
457 u16(NumberOfSections),
459 u32(
sizeof(Header) + (NumberOfSections *
sizeof(
coff_section)) +
464 u32(NumberOfSymbols),
472 {{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'5'},
484 {{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'4'},
498 append(Buffer, SectionTable);
512 {{{0, 0, 0, 0, 0, 0, 0, 0}},
520 append(Buffer, SymbolTable);
525 StringRef F{
reinterpret_cast<const char *
>(Buffer.data()), Buffer.size()};
533 size_t ImpSize = ImportName.
size() +
Sym.size() + 2;
534 if (!ExportName.
empty())
535 ImpSize += ExportName.
size() + 1;
538 memset(Buf, 0,
Size);
546 Imp->SizeOfData = ImpSize;
548 Imp->OrdinalHint = Ordinal;
552 memcpy(
P,
Sym.data(),
Sym.size());
554 memcpy(
P, ImportName.
data(), ImportName.
size());
555 if (!ExportName.
empty()) {
556 P += ImportName.
size() + 1;
557 memcpy(
P, ExportName.
data(), ExportName.
size());
566 std::vector<uint8_t> Buffer;
567 const uint32_t NumberOfSections = 1;
573 u16(NumberOfSections),
575 u32(
sizeof(Header) + (NumberOfSections *
sizeof(
coff_section))),
576 u32(NumberOfSymbols),
584 {{
'.',
'd',
'r',
'e',
'c',
't',
'v',
'e'},
594 append(Buffer, SectionTable);
598 {{{
'@',
'c',
'o',
'm',
'p',
'.',
'i',
'd'}},
604 {{{
'@',
'f',
'e',
'a',
't',
'.',
'0',
'0'}},
610 {{{0, 0, 0, 0, 0, 0, 0, 0}},
616 {{{0, 0, 0, 0, 0, 0, 0, 0}},
635 append(Buffer, SymbolTable);
640 char *Buf =
Alloc.Allocate<
char>(Buffer.size());
641 memcpy(Buf, Buffer.data(), Buffer.size());
656 std::vector<NewArchiveMember> Members;
659 std::vector<uint8_t> ImportDescriptor;
660 Members.push_back(OF.createImportDescriptor(ImportDescriptor));
662 std::vector<uint8_t> NullImportDescriptor;
663 Members.push_back(OF.createNullImportDescriptor(NullImportDescriptor));
665 std::vector<uint8_t> NullThunk;
666 Members.push_back(OF.createNullThunk(NullThunk));
680 StringRef SymbolName = E.SymbolName.empty() ? E.Name : E.SymbolName;
683 if (E.ExtName.empty()) {
684 Name = std::string(SymbolName);
687 replace(SymbolName, E.Name, E.ExtName);
690 Name.swap(*ReplacedName);
693 if (!E.ImportName.empty() &&
Name != E.ImportName) {
694 Members.push_back(OF.createWeakExternal(E.ImportName,
Name,
false, M));
695 Members.push_back(OF.createWeakExternal(E.ImportName,
Name,
true, M));
700 std::string ExportName;
703 }
else if (!E.ExportAs.empty()) {
705 ExportName = E.ExportAs;
712 if (std::optional<std::string> MangledName =
714 if (!E.Noname && ExportName.empty()) {
716 ExportName.swap(
Name);
718 Name = std::move(*MangledName);
719 }
else if (!E.Noname && ExportName.empty()) {
725 Members.push_back(OF.createShortImport(
Name, E.Ordinal,
ImportType,
733 if (
Error e = addExports(NativeExports, NativeMachine))
#define offsetof(TYPE, MEMBER)
This file defines the BumpPtrAllocator interface.
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
COFF::MachineTypes Machine
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Allocate memory in an ever growing pool, as if by bump-pointer.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
const char * getBufferStart() const
StringRef getBuffer() const
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
static constexpr size_t npos
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
const coff_import_header * getCOFFImportHeader() const
StringRef getFileFormatName() const
StringRef getExportName() const
Error printSymbolName(raw_ostream &OS, DataRefImpl Symb) const override
uint16_t getMachine() const
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ IMAGE_FILE_MACHINE_ARM64
@ IMAGE_FILE_MACHINE_AMD64
@ IMAGE_FILE_MACHINE_ARM64EC
@ IMAGE_FILE_MACHINE_I386
@ IMAGE_FILE_MACHINE_ARM64X
@ IMAGE_FILE_MACHINE_ARMNT
@ IMAGE_SCN_CNT_INITIALIZED_DATA
@ IMAGE_REL_ARM64_ADDR32NB
@ IMAGE_REL_AMD64_ADDR32NB
@ IMAGE_SYM_CLASS_SECTION
Line number, reformatted as symbol.
@ IMAGE_SYM_CLASS_EXTERNAL
External symbol.
@ IMAGE_SYM_CLASS_NULL
No symbol.
@ IMAGE_SYM_CLASS_WEAK_EXTERNAL
Duplicate tag.
@ IMAGE_SYM_CLASS_STATIC
Static.
@ IMAGE_WEAK_EXTERN_SEARCH_ALIAS
bool isArm64EC(T Machine)
@ IMPORT_ORDINAL
Import is by ordinal.
@ IMPORT_NAME_EXPORTAS
The import name is specified as a separate string in the import library object file.
@ IMPORT_NAME
The import name is identical to the public symbol name.
@ IMPORT_NAME_UNDECORATE
The import name is the public symbol name, but skipping the leading ?, @, or optionally _,...
@ IMPORT_NAME_NOPREFIX
The import name is the public symbol name, but skipping the leading ?, @, or optionally _.
@ IMAGE_FILE_32BIT_MACHINE
Machine is based on a 32bit word architecture.
static void append(std::vector< uint8_t > &B, const T &Data)
constexpr std::string_view NullImportDescriptorSymbolName
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)
static uint16_t getImgRelRelocation(MachineTypes Machine)
constexpr std::string_view NullThunkDataPrefix
constexpr std::string_view NullThunkDataSuffix
static ImportNameType getNameType(StringRef Sym, StringRef ExtName, MachineTypes Machine, bool MinGW)
static void writeStringTable(std::vector< uint8_t > &B, ArrayRef< const std::string_view > Strings)
constexpr std::string_view ImportDescriptorPrefix
void write32le(void *P, uint32_t V)
detail::packed_endian_specific_integral< uint16_t, llvm::endianness::little, unaligned > ulittle16_t
detail::packed_endian_specific_integral< uint32_t, llvm::endianness::little, unaligned > ulittle32_t
StringRef filename(StringRef path, Style style=Style::native)
Get filename.
This is an optimization pass for GlobalISel generic memory operations.
std::optional< std::string > getArm64ECMangledFunctionName(StringRef Name)
Error writeArchive(StringRef ArcName, ArrayRef< NewArchiveMember > NewMembers, SymtabWritingMode WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin, std::unique_ptr< MemoryBuffer > OldArchiveBuf=nullptr, std::optional< bool > IsEC=std::nullopt)
std::optional< std::string > getArm64ECDemangledFunctionName(StringRef Name)
support::ulittle32_t Offset
union llvm::object::coff_symbol::@346 Name