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 =
141template <
class T>
static void append(std::vector<uint8_t> &
B,
const T &
Data) {
143 B.resize(S +
sizeof(
T));
144 memcpy(&
B[S], &
Data,
sizeof(
T));
155 size_t Pos =
B.size();
162 for (
const auto &S : Strings) {
163 B.resize(Pos + S.length() + 1);
164 std::copy(S.begin(), S.end(), std::next(
B.begin(), Pos));
165 B[Pos + S.length()] = 0;
166 Pos += S.length() + 1;
203 return make_error<StringError>(
223 std::string ImportDescriptorSymbolName;
224 std::string NullThunkSymbolName;
228 : NativeMachine(M), ImportName(S), Library(
llvm::sys::path::stem(S)),
265ObjectFactory::createImportDescriptor(std::vector<uint8_t> &Buffer) {
266 const uint32_t NumberOfSections = 2;
268 const uint32_t NumberOfRelocations = 3;
273 u16(NumberOfSections),
275 u32(
sizeof(Header) + (NumberOfSections *
sizeof(
coff_section)) +
280 (ImportName.
size() + 1)),
281 u32(NumberOfSymbols),
289 {{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'2'},
297 u16(NumberOfRelocations),
301 {{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'6'},
304 u32(ImportName.
size() + 1),
315 append(Buffer, SectionTable);
319 u32(0), u32(0), u32(0), u32(0), u32(0),
321 append(Buffer, ImportDescriptor);
331 append(Buffer, RelocationTable);
334 auto S = Buffer.size();
335 Buffer.resize(S + ImportName.
size() + 1);
336 memcpy(&Buffer[S], ImportName.
data(), ImportName.
size());
337 Buffer[S + ImportName.
size()] =
'\0';
341 {{{0, 0, 0, 0, 0, 0, 0, 0}},
347 {{{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'2'}},
353 {{{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'6'}},
359 {{{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'4'}},
365 {{{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'5'}},
371 {{{0, 0, 0, 0, 0, 0, 0, 0}},
377 {{{0, 0, 0, 0, 0, 0, 0, 0}},
389 sizeof(
uint32_t) + ImportDescriptorSymbolName.length() + 1;
391 sizeof(
uint32_t) + ImportDescriptorSymbolName.length() + 1 +
393 append(Buffer, SymbolTable);
398 NullThunkSymbolName});
400 StringRef F{
reinterpret_cast<const char *
>(Buffer.data()), Buffer.size()};
405ObjectFactory::createNullImportDescriptor(std::vector<uint8_t> &Buffer) {
406 const uint32_t NumberOfSections = 1;
412 u16(NumberOfSections),
414 u32(
sizeof(Header) + (NumberOfSections *
sizeof(
coff_section)) +
417 u32(NumberOfSymbols),
425 {{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'3'},
438 append(Buffer, SectionTable);
442 u32(0), u32(0), u32(0), u32(0), u32(0),
444 append(Buffer, ImportDescriptor);
448 {{{0, 0, 0, 0, 0, 0, 0, 0}},
456 append(Buffer, SymbolTable);
461 StringRef F{
reinterpret_cast<const char *
>(Buffer.data()), Buffer.size()};
465NewArchiveMember ObjectFactory::createNullThunk(std::vector<uint8_t> &Buffer) {
466 const uint32_t NumberOfSections = 2;
473 u16(NumberOfSections),
475 u32(
sizeof(Header) + (NumberOfSections *
sizeof(
coff_section)) +
480 u32(NumberOfSymbols),
488 {{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'5'},
500 {{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'4'},
514 append(Buffer, SectionTable);
528 {{{0, 0, 0, 0, 0, 0, 0, 0}},
536 append(Buffer, SymbolTable);
541 StringRef F{
reinterpret_cast<const char *
>(Buffer.data()), Buffer.size()};
549 size_t ImpSize = ImportName.
size() +
Sym.size() + 2;
550 if (!ExportName.
empty())
551 ImpSize += ExportName.
size() + 1;
554 memset(Buf, 0,
Size);
562 Imp->SizeOfData = ImpSize;
564 Imp->OrdinalHint = Ordinal;
568 memcpy(
P,
Sym.data(),
Sym.size());
570 memcpy(
P, ImportName.
data(), ImportName.
size());
571 if (!ExportName.
empty()) {
572 P += ImportName.
size() + 1;
573 memcpy(
P, ExportName.
data(), ExportName.
size());
582 std::vector<uint8_t> Buffer;
583 const uint32_t NumberOfSections = 1;
589 u16(NumberOfSections),
591 u32(
sizeof(Header) + (NumberOfSections *
sizeof(
coff_section))),
592 u32(NumberOfSymbols),
600 {{
'.',
'd',
'r',
'e',
'c',
't',
'v',
'e'},
610 append(Buffer, SectionTable);
614 {{{
'@',
'c',
'o',
'm',
'p',
'.',
'i',
'd'}},
620 {{{
'@',
'f',
'e',
'a',
't',
'.',
'0',
'0'}},
626 {{{0, 0, 0, 0, 0, 0, 0, 0}},
632 {{{0, 0, 0, 0, 0, 0, 0, 0}},
651 append(Buffer, SymbolTable);
656 char *Buf =
Alloc.Allocate<
char>(Buffer.size());
657 memcpy(Buf, Buffer.data(), Buffer.size());
672 std::vector<NewArchiveMember> Members;
675 std::vector<uint8_t> ImportDescriptor;
676 Members.push_back(OF.createImportDescriptor(ImportDescriptor));
678 std::vector<uint8_t> NullImportDescriptor;
679 Members.push_back(OF.createNullImportDescriptor(NullImportDescriptor));
681 std::vector<uint8_t> NullThunk;
682 Members.push_back(OF.createNullThunk(NullThunk));
703 StringRef SymbolName = E.SymbolName.empty() ? E.Name : E.SymbolName;
706 if (E.ExtName.empty()) {
707 Name = std::string(SymbolName);
713 Name.swap(*ReplacedName);
717 std::string ExportName;
720 }
else if (!E.ExportAs.empty()) {
722 ExportName = E.ExportAs;
723 }
else if (!E.ImportName.empty()) {
736 ExportName = E.ImportName;
737 }
else if (
Name == E.ImportName)
753 if (std::optional<std::string> MangledName =
755 if (!E.Noname && ExportName.empty()) {
757 ExportName.swap(
Name);
759 Name = std::move(*MangledName);
760 }
else if (!E.Noname && ExportName.empty()) {
761 std::optional<std::string> DemangledName =
764 return make_error<StringError>(
769 ExportName = std::move(*DemangledName);
774 Members.push_back(OF.createShortImport(
Name, E.Ordinal,
ImportType,
777 for (
const auto &
D : Renames) {
778 auto It = RegularImports.
find(
D.Export->ImportName);
779 if (It != RegularImports.
end()) {
784 Members.push_back(OF.createWeakExternal(Symbol,
D.Name,
false, M));
785 Members.push_back(OF.createWeakExternal(Symbol,
D.Name,
true, M));
787 Members.push_back(OF.createShortImport(
D.Name,
D.Export->Ordinal,
789 D.Export->ImportName, M));
797 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_REL_MIPS_REFWORDNB
@ IMAGE_FILE_MACHINE_ARM64
@ IMAGE_FILE_MACHINE_AMD64
@ IMAGE_FILE_MACHINE_ARM64EC
@ IMAGE_FILE_MACHINE_R4000
@ 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
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
Error writeImportLibrary(StringRef ImportName, StringRef Path, ArrayRef< COFFShortExport > Exports, COFF::MachineTypes Machine, bool MinGW, ArrayRef< COFFShortExport > NativeExports={})
Writes a COFF import library containing entries described by the Exports array.
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)
Returns the ARM64EC mangled function name unless the input is already mangled.
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)
Returns the ARM64EC demangled function name, unless the input is not mangled.
support::ulittle32_t Offset
union llvm::object::coff_symbol::@362 Name