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;
104template <
class T>
static void append(std::vector<uint8_t> &
B,
const T &
Data) {
106 B.resize(S +
sizeof(
T));
107 memcpy(&
B[S], &
Data,
sizeof(
T));
118 size_t Pos =
B.size();
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;
166 return make_error<StringError>(
186 std::string ImportDescriptorSymbolName;
187 std::string NullThunkSymbolName;
191 : NativeMachine(M), ImportName(S), Library(
llvm::sys::path::stem(S)),
228ObjectFactory::createImportDescriptor(std::vector<uint8_t> &Buffer) {
229 const uint32_t NumberOfSections = 2;
231 const uint32_t NumberOfRelocations = 3;
236 u16(NumberOfSections),
238 u32(
sizeof(Header) + (NumberOfSections *
sizeof(
coff_section)) +
243 (ImportName.
size() + 1)),
244 u32(NumberOfSymbols),
252 {{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'2'},
260 u16(NumberOfRelocations),
264 {{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'6'},
267 u32(ImportName.
size() + 1),
278 append(Buffer, SectionTable);
282 u32(0), u32(0), u32(0), u32(0), u32(0),
284 append(Buffer, ImportDescriptor);
294 append(Buffer, RelocationTable);
297 auto S = Buffer.size();
298 Buffer.resize(S + ImportName.
size() + 1);
299 memcpy(&Buffer[S], ImportName.
data(), ImportName.
size());
300 Buffer[S + ImportName.
size()] =
'\0';
304 {{{0, 0, 0, 0, 0, 0, 0, 0}},
310 {{{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'2'}},
316 {{{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'6'}},
322 {{{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'4'}},
328 {{{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'5'}},
334 {{{0, 0, 0, 0, 0, 0, 0, 0}},
340 {{{0, 0, 0, 0, 0, 0, 0, 0}},
352 sizeof(
uint32_t) + ImportDescriptorSymbolName.length() + 1;
354 sizeof(
uint32_t) + ImportDescriptorSymbolName.length() + 1 +
356 append(Buffer, SymbolTable);
361 NullThunkSymbolName});
363 StringRef F{
reinterpret_cast<const char *
>(Buffer.data()), Buffer.size()};
368ObjectFactory::createNullImportDescriptor(std::vector<uint8_t> &Buffer) {
369 const uint32_t NumberOfSections = 1;
375 u16(NumberOfSections),
377 u32(
sizeof(Header) + (NumberOfSections *
sizeof(
coff_section)) +
380 u32(NumberOfSymbols),
388 {{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'3'},
401 append(Buffer, SectionTable);
405 u32(0), u32(0), u32(0), u32(0), u32(0),
407 append(Buffer, ImportDescriptor);
411 {{{0, 0, 0, 0, 0, 0, 0, 0}},
419 append(Buffer, SymbolTable);
424 StringRef F{
reinterpret_cast<const char *
>(Buffer.data()), Buffer.size()};
428NewArchiveMember ObjectFactory::createNullThunk(std::vector<uint8_t> &Buffer) {
429 const uint32_t NumberOfSections = 2;
436 u16(NumberOfSections),
438 u32(
sizeof(Header) + (NumberOfSections *
sizeof(
coff_section)) +
443 u32(NumberOfSymbols),
451 {{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'5'},
463 {{
'.',
'i',
'd',
'a',
't',
'a',
'$',
'4'},
477 append(Buffer, SectionTable);
491 {{{0, 0, 0, 0, 0, 0, 0, 0}},
499 append(Buffer, SymbolTable);
504 StringRef F{
reinterpret_cast<const char *
>(Buffer.data()), Buffer.size()};
512 size_t ImpSize = ImportName.
size() +
Sym.size() + 2;
513 if (!ExportName.
empty())
514 ImpSize += ExportName.
size() + 1;
517 memset(Buf, 0,
Size);
525 Imp->SizeOfData = ImpSize;
527 Imp->OrdinalHint = Ordinal;
531 memcpy(
P,
Sym.data(),
Sym.size());
533 memcpy(
P, ImportName.
data(), ImportName.
size());
534 if (!ExportName.
empty()) {
535 P += ImportName.
size() + 1;
536 memcpy(
P, ExportName.
data(), ExportName.
size());
545 std::vector<uint8_t> Buffer;
546 const uint32_t NumberOfSections = 1;
552 u16(NumberOfSections),
554 u32(
sizeof(Header) + (NumberOfSections *
sizeof(
coff_section))),
555 u32(NumberOfSymbols),
563 {{
'.',
'd',
'r',
'e',
'c',
't',
'v',
'e'},
573 append(Buffer, SectionTable);
577 {{{
'@',
'c',
'o',
'm',
'p',
'.',
'i',
'd'}},
583 {{{
'@',
'f',
'e',
'a',
't',
'.',
'0',
'0'}},
589 {{{0, 0, 0, 0, 0, 0, 0, 0}},
595 {{{0, 0, 0, 0, 0, 0, 0, 0}},
614 append(Buffer, SymbolTable);
619 char *Buf =
Alloc.Allocate<
char>(Buffer.size());
620 memcpy(Buf, Buffer.data(), Buffer.size());
632 std::vector<NewArchiveMember> Members;
635 std::vector<uint8_t> ImportDescriptor;
636 Members.push_back(OF.createImportDescriptor(ImportDescriptor));
638 std::vector<uint8_t> NullImportDescriptor;
639 Members.push_back(OF.createNullImportDescriptor(NullImportDescriptor));
641 std::vector<uint8_t> NullThunk;
642 Members.push_back(OF.createNullThunk(NullThunk));
656 StringRef SymbolName =
E.SymbolName.empty() ?
E.Name :
E.SymbolName;
659 if (
E.ExtName.empty()) {
660 Name = std::string(SymbolName);
666 Name.swap(*ReplacedName);
669 if (!
E.AliasTarget.empty() &&
Name !=
E.AliasTarget) {
670 Members.push_back(OF.createWeakExternal(
E.AliasTarget,
Name,
false, M));
671 Members.push_back(OF.createWeakExternal(
E.AliasTarget,
Name,
true, M));
676 std::string ExportName;
679 }
else if (!
E.ExportAs.empty()) {
681 ExportName =
E.ExportAs;
688 if (std::optional<std::string> MangledName =
690 if (ExportName.empty()) {
692 ExportName.swap(
Name);
694 Name = std::move(*MangledName);
695 }
else if (ExportName.empty()) {
709 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")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-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.
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
uint16_t getMachine() const
#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
std::optional< std::string > getArm64ECMangledFunctionName(StringRef Name)
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)
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.
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
union llvm::object::coff_symbol::@344 Name