41 return "COFF-import-file-i386";
43 return "COFF-import-file-x86-64";
45 return "COFF-import-file-ARM";
47 return "COFF-import-file-ARM64";
49 return "COFF-import-file-ARM64EC";
51 return "COFF-import-file-ARM64X";
53 return "COFF-import-file-<unknown arch>";
59 return !s.
empty() && chars.contains(s[0]) ? s.
substr(1) : s;
91 name =
name.split(
'\0').second.split(
'\0').first;
112 if (std::optional<std::string> DemangledName =
139template <
class T>
static void append(std::vector<uint8_t> &
B,
const T &
Data) {
141 B.resize(S +
sizeof(
T));
142 memcpy(&
B[S], &
Data,
sizeof(
T));
153 size_t Pos =
B.size();
160 for (
const auto &S : Strings) {
161 B.resize(Pos + S.length() + 1);
162 std::copy(S.begin(), S.end(), std::next(
B.begin(), Pos));
163 B[Pos + S.length()] = 0;
164 Pos += S.length() + 1;
201 return make_error<StringError>(
221 std::string ImportDescriptorSymbolName;
222 std::string NullThunkSymbolName;
226 : NativeMachine(M), ImportName(S), Library(
llvm::sys::path::stem(S)),
263ObjectFactory::createImportDescriptor(std::vector<uint8_t> &Buffer) {
264 const uint32_t NumberOfSections = 2;
266 const uint32_t NumberOfRelocations = 3;
271 u16(NumberOfSections),
273 u32(
sizeof(Header) + (NumberOfSections *
sizeof(
coff_section)) +
278 (ImportName.
size() + 1)),
279 u32(NumberOfSymbols),
287 {{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'2'},
295 u16(NumberOfRelocations),
299 {{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'6'},
302 u32(ImportName.
size() + 1),
313 append(Buffer, SectionTable);
317 u32(0), u32(0), u32(0), u32(0), u32(0),
319 append(Buffer, ImportDescriptor);
329 append(Buffer, RelocationTable);
332 auto S = Buffer.size();
333 Buffer.resize(S + ImportName.
size() + 1);
334 memcpy(&Buffer[S], ImportName.
data(), ImportName.
size());
335 Buffer[S + ImportName.
size()] =
'\0';
339 {{{0, 0, 0, 0, 0, 0, 0, 0}},
345 {{{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'2'}},
351 {{{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'6'}},
357 {{{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'4'}},
363 {{{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'5'}},
369 {{{0, 0, 0, 0, 0, 0, 0, 0}},
375 {{{0, 0, 0, 0, 0, 0, 0, 0}},
387 sizeof(
uint32_t) + ImportDescriptorSymbolName.length() + 1;
389 sizeof(
uint32_t) + ImportDescriptorSymbolName.length() + 1 +
391 append(Buffer, SymbolTable);
396 NullThunkSymbolName});
398 StringRef F{
reinterpret_cast<const char *
>(Buffer.data()), Buffer.size()};
403ObjectFactory::createNullImportDescriptor(std::vector<uint8_t> &Buffer) {
404 const uint32_t NumberOfSections = 1;
410 u16(NumberOfSections),
412 u32(
sizeof(Header) + (NumberOfSections *
sizeof(
coff_section)) +
415 u32(NumberOfSymbols),
423 {{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'3'},
436 append(Buffer, SectionTable);
440 u32(0), u32(0), u32(0), u32(0), u32(0),
442 append(Buffer, ImportDescriptor);
446 {{{0, 0, 0, 0, 0, 0, 0, 0}},
454 append(Buffer, SymbolTable);
459 StringRef F{
reinterpret_cast<const char *
>(Buffer.data()), Buffer.size()};
463NewArchiveMember ObjectFactory::createNullThunk(std::vector<uint8_t> &Buffer) {
464 const uint32_t NumberOfSections = 2;
471 u16(NumberOfSections),
473 u32(
sizeof(Header) + (NumberOfSections *
sizeof(
coff_section)) +
478 u32(NumberOfSymbols),
486 {{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'5'},
498 {{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'4'},
512 append(Buffer, SectionTable);
526 {{{0, 0, 0, 0, 0, 0, 0, 0}},
534 append(Buffer, SymbolTable);
539 StringRef F{
reinterpret_cast<const char *
>(Buffer.data()), Buffer.size()};
547 size_t ImpSize = ImportName.
size() +
Sym.size() + 2;
548 if (!ExportName.
empty())
549 ImpSize += ExportName.
size() + 1;
552 memset(Buf, 0,
Size);
560 Imp->SizeOfData = ImpSize;
562 Imp->OrdinalHint = Ordinal;
566 memcpy(
P,
Sym.data(),
Sym.size());
568 memcpy(
P, ImportName.
data(), ImportName.
size());
569 if (!ExportName.
empty()) {
570 P += ImportName.
size() + 1;
571 memcpy(
P, ExportName.
data(), ExportName.
size());
580 std::vector<uint8_t> Buffer;
581 const uint32_t NumberOfSections = 1;
587 u16(NumberOfSections),
589 u32(
sizeof(Header) + (NumberOfSections *
sizeof(
coff_section))),
590 u32(NumberOfSymbols),
598 {{
'.',
'd',
'r',
'e',
'c',
't',
'v',
'e'},
608 append(Buffer, SectionTable);
612 {{{
'@',
'c',
'o',
'm',
'p',
'.',
'i',
'd'}},
618 {{{
'@',
'f',
'e',
'a',
't',
'.',
'0',
'0'}},
624 {{{0, 0, 0, 0, 0, 0, 0, 0}},
630 {{{0, 0, 0, 0, 0, 0, 0, 0}},
649 append(Buffer, SymbolTable);
654 char *Buf =
Alloc.Allocate<
char>(Buffer.size());
655 memcpy(Buf, Buffer.data(), Buffer.size());
670 std::vector<NewArchiveMember> Members;
673 std::vector<uint8_t> ImportDescriptor;
674 Members.push_back(OF.createImportDescriptor(ImportDescriptor));
676 std::vector<uint8_t> NullImportDescriptor;
677 Members.push_back(OF.createNullImportDescriptor(NullImportDescriptor));
679 std::vector<uint8_t> NullThunk;
680 Members.push_back(OF.createNullThunk(NullThunk));
701 StringRef SymbolName = E.SymbolName.empty() ? E.Name : E.SymbolName;
704 if (E.ExtName.empty()) {
705 Name = std::string(SymbolName);
708 replace(SymbolName, E.Name, E.ExtName);
711 Name.swap(*ReplacedName);
715 std::string ExportName;
718 }
else if (!E.ExportAs.empty()) {
720 ExportName = E.ExportAs;
721 }
else if (!E.ImportName.empty()) {
734 ExportName = E.ImportName;
735 }
else if (
Name == E.ImportName)
751 if (std::optional<std::string> MangledName =
753 if (!E.Noname && ExportName.empty()) {
755 ExportName.swap(
Name);
757 Name = std::move(*MangledName);
758 }
else if (!E.Noname && ExportName.empty()) {
765 Members.push_back(OF.createShortImport(
Name, E.Ordinal,
ImportType,
768 for (
const auto &
D : Renames) {
769 auto It = RegularImports.
find(
D.Export->ImportName);
770 if (It != RegularImports.
end()) {
775 Members.push_back(OF.createWeakExternal(Symbol,
D.Name,
false, M));
776 Members.push_back(OF.createWeakExternal(Symbol,
D.Name,
true, M));
778 Members.push_back(OF.createShortImport(
D.Name,
D.Export->Ordinal,
780 D.Export->ImportName, M));
788 if (
Error e = addExports(NativeExports, NativeMachine))
This file defines the StringMap class.
#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< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
COFF::MachineTypes Machine
This file defines the SmallVector class.
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
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
iterator find(StringRef Key)
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 StringRef applyNameType(ImportNameType Type, StringRef name)
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, function_ref< void(Error)> Warn=warnToStderr)
@ Export
Export information to summary.
std::optional< std::string > getArm64ECDemangledFunctionName(StringRef Name)
support::ulittle32_t Offset
union llvm::object::coff_symbol::@359 Name