Skip to content

Commit

Permalink
[llvm-lib][Object][COFF] Use ARM64 machine type for import library de…
Browse files Browse the repository at this point in the history
…scriptor objects. (#78537)
  • Loading branch information
cjacek committed Jan 18, 2024
1 parent 5c150e7 commit 80fcf48
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 31 deletions.
61 changes: 35 additions & 26 deletions llvm/lib/Object/COFFImportFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ namespace {
class ObjectFactory {
using u16 = support::ulittle16_t;
using u32 = support::ulittle32_t;
MachineTypes Machine;
MachineTypes NativeMachine;
BumpPtrAllocator Alloc;
StringRef ImportName;
StringRef Library;
Expand All @@ -159,7 +159,7 @@ class ObjectFactory {

public:
ObjectFactory(StringRef S, MachineTypes M)
: Machine(M), ImportName(S), Library(llvm::sys::path::stem(S)),
: NativeMachine(M), ImportName(S), Library(llvm::sys::path::stem(S)),
ImportDescriptorSymbolName(("__IMPORT_DESCRIPTOR_" + Library).str()),
NullThunkSymbolName(("\x7f" + Library + "_NULL_THUNK_DATA").str()) {}

Expand All @@ -182,10 +182,14 @@ class ObjectFactory {
// Create a short import file which is described in PE/COFF spec 7. Import
// Library Format.
NewArchiveMember createShortImport(StringRef Sym, uint16_t Ordinal,
ImportType Type, ImportNameType NameType);
ImportType Type, ImportNameType NameType,
MachineTypes Machine);

// Create a weak external file which is described in PE/COFF Aux Format 3.
NewArchiveMember createWeakExternal(StringRef Sym, StringRef Weak, bool Imp);
NewArchiveMember createWeakExternal(StringRef Sym, StringRef Weak, bool Imp,
MachineTypes Machine);

bool is64Bit() const { return COFF::is64Bit(NativeMachine); }
};
} // namespace

Expand All @@ -197,7 +201,7 @@ ObjectFactory::createImportDescriptor(std::vector<uint8_t> &Buffer) {

// COFF Header
coff_file_header Header{
u16(Machine),
u16(NativeMachine),
u16(NumberOfSections),
u32(0),
u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section)) +
Expand All @@ -208,7 +212,7 @@ ObjectFactory::createImportDescriptor(std::vector<uint8_t> &Buffer) {
(ImportName.size() + 1)),
u32(NumberOfSymbols),
u16(0),
u16(is64Bit(Machine) ? C_Invalid : IMAGE_FILE_32BIT_MACHINE),
u16(is64Bit() ? C_Invalid : IMAGE_FILE_32BIT_MACHINE),
};
append(Buffer, Header);

Expand Down Expand Up @@ -250,11 +254,11 @@ ObjectFactory::createImportDescriptor(std::vector<uint8_t> &Buffer) {

const coff_relocation RelocationTable[NumberOfRelocations] = {
{u32(offsetof(coff_import_directory_table_entry, NameRVA)), u32(2),
u16(getImgRelRelocation(Machine))},
u16(getImgRelRelocation(NativeMachine))},
{u32(offsetof(coff_import_directory_table_entry, ImportLookupTableRVA)),
u32(3), u16(getImgRelRelocation(Machine))},
u32(3), u16(getImgRelRelocation(NativeMachine))},
{u32(offsetof(coff_import_directory_table_entry, ImportAddressTableRVA)),
u32(4), u16(getImgRelRelocation(Machine))},
u32(4), u16(getImgRelRelocation(NativeMachine))},
};
append(Buffer, RelocationTable);

Expand Down Expand Up @@ -336,15 +340,15 @@ ObjectFactory::createNullImportDescriptor(std::vector<uint8_t> &Buffer) {

// COFF Header
coff_file_header Header{
u16(Machine),
u16(NativeMachine),
u16(NumberOfSections),
u32(0),
u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section)) +
// .idata$3
sizeof(coff_import_directory_table_entry)),
u32(NumberOfSymbols),
u16(0),
u16(is64Bit(Machine) ? C_Invalid : IMAGE_FILE_32BIT_MACHINE),
u16(is64Bit() ? C_Invalid : IMAGE_FILE_32BIT_MACHINE),
};
append(Buffer, Header);

Expand Down Expand Up @@ -393,11 +397,11 @@ ObjectFactory::createNullImportDescriptor(std::vector<uint8_t> &Buffer) {
NewArchiveMember ObjectFactory::createNullThunk(std::vector<uint8_t> &Buffer) {
const uint32_t NumberOfSections = 2;
const uint32_t NumberOfSymbols = 1;
uint32_t VASize = is64Bit(Machine) ? 8 : 4;
uint32_t VASize = is64Bit() ? 8 : 4;

// COFF Header
coff_file_header Header{
u16(Machine),
u16(NativeMachine),
u16(NumberOfSections),
u32(0),
u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section)) +
Expand All @@ -407,7 +411,7 @@ NewArchiveMember ObjectFactory::createNullThunk(std::vector<uint8_t> &Buffer) {
VASize),
u32(NumberOfSymbols),
u16(0),
u16(is64Bit(Machine) ? C_Invalid : IMAGE_FILE_32BIT_MACHINE),
u16(is64Bit() ? C_Invalid : IMAGE_FILE_32BIT_MACHINE),
};
append(Buffer, Header);

Expand All @@ -422,8 +426,7 @@ NewArchiveMember ObjectFactory::createNullThunk(std::vector<uint8_t> &Buffer) {
u32(0),
u16(0),
u16(0),
u32((is64Bit(Machine) ? IMAGE_SCN_ALIGN_8BYTES
: IMAGE_SCN_ALIGN_4BYTES) |
u32((is64Bit() ? IMAGE_SCN_ALIGN_8BYTES : IMAGE_SCN_ALIGN_4BYTES) |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ |
IMAGE_SCN_MEM_WRITE)},
{{'.', 'i', 'd', 'a', 't', 'a', '$', '4'},
Expand All @@ -436,21 +439,20 @@ NewArchiveMember ObjectFactory::createNullThunk(std::vector<uint8_t> &Buffer) {
u32(0),
u16(0),
u16(0),
u32((is64Bit(Machine) ? IMAGE_SCN_ALIGN_8BYTES
: IMAGE_SCN_ALIGN_4BYTES) |
u32((is64Bit() ? IMAGE_SCN_ALIGN_8BYTES : IMAGE_SCN_ALIGN_4BYTES) |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ |
IMAGE_SCN_MEM_WRITE)},
};
append(Buffer, SectionTable);

// .idata$5, ILT
append(Buffer, u32(0));
if (is64Bit(Machine))
if (is64Bit())
append(Buffer, u32(0));

// .idata$4, IAT
append(Buffer, u32(0));
if (is64Bit(Machine))
if (is64Bit())
append(Buffer, u32(0));

// Symbol Table
Expand All @@ -475,7 +477,8 @@ NewArchiveMember ObjectFactory::createNullThunk(std::vector<uint8_t> &Buffer) {
NewArchiveMember ObjectFactory::createShortImport(StringRef Sym,
uint16_t Ordinal,
ImportType ImportType,
ImportNameType NameType) {
ImportNameType NameType,
MachineTypes Machine) {
size_t ImpSize = ImportName.size() + Sym.size() + 2; // +2 for NULs
size_t Size = sizeof(coff_import_header) + ImpSize;
char *Buf = Alloc.Allocate<char>(Size);
Expand All @@ -501,7 +504,8 @@ NewArchiveMember ObjectFactory::createShortImport(StringRef Sym,
}

NewArchiveMember ObjectFactory::createWeakExternal(StringRef Sym,
StringRef Weak, bool Imp) {
StringRef Weak, bool Imp,
MachineTypes Machine) {
std::vector<uint8_t> Buffer;
const uint32_t NumberOfSections = 1;
const uint32_t NumberOfSymbols = 5;
Expand Down Expand Up @@ -585,8 +589,11 @@ Error writeImportLibrary(StringRef ImportName, StringRef Path,
ArrayRef<COFFShortExport> Exports,
MachineTypes Machine, bool MinGW) {

MachineTypes NativeMachine =
isArm64EC(Machine) ? IMAGE_FILE_MACHINE_ARM64 : Machine;

std::vector<NewArchiveMember> Members;
ObjectFactory OF(llvm::sys::path::filename(ImportName), Machine);
ObjectFactory OF(llvm::sys::path::filename(ImportName), NativeMachine);

std::vector<uint8_t> ImportDescriptor;
Members.push_back(OF.createImportDescriptor(ImportDescriptor));
Expand Down Expand Up @@ -620,13 +627,15 @@ Error writeImportLibrary(StringRef ImportName, StringRef Path,
return Name.takeError();

if (!E.AliasTarget.empty() && *Name != E.AliasTarget) {
Members.push_back(OF.createWeakExternal(E.AliasTarget, *Name, false));
Members.push_back(OF.createWeakExternal(E.AliasTarget, *Name, true));
Members.push_back(
OF.createWeakExternal(E.AliasTarget, *Name, false, Machine));
Members.push_back(
OF.createWeakExternal(E.AliasTarget, *Name, true, Machine));
continue;
}

Members.push_back(
OF.createShortImport(*Name, E.Ordinal, ImportType, NameType));
OF.createShortImport(*Name, E.Ordinal, ImportType, NameType, Machine));
}

return writeArchive(Path, Members, SymtabWritingMode::NormalSymtab,
Expand Down
12 changes: 7 additions & 5 deletions llvm/test/tools/llvm-lib/arm64ec-implib.test
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,30 @@ RUN: llvm-lib -machine:arm64ec -def:test.def -out:test.lib

RUN: llvm-nm --print-armap test.lib | FileCheck -check-prefix=ARMAP %s

ARMAP: Archive EC map
ARMAP: Archive map
ARMAP-NEXT: __IMPORT_DESCRIPTOR_test in test.dll
ARMAP-NEXT: __NULL_IMPORT_DESCRIPTOR in test.dll
ARMAP-NEXT: test_NULL_THUNK_DATA in test.dll
ARMAP-EMPTY:
ARMAP-NEXT: Archive EC map
ARMAP-NEXT: __imp_dataexp in test.dll
ARMAP-NEXT: __imp_funcexp in test.dll
ARMAP-NEXT: funcexp in test.dll
ARMAP-NEXT: test_NULL_THUNK_DATA in test.dll

RUN: llvm-readobj test.lib | FileCheck -check-prefix=READOBJ %s

READOBJ: File: test.lib(test.dll)
READOBJ-NEXT: Format: COFF-ARM64EC
READOBJ-NEXT: Format: COFF-ARM64{{$}}
READOBJ-NEXT: Arch: aarch64
READOBJ-NEXT: AddressSize: 64bit
READOBJ-EMPTY:
READOBJ-NEXT: File: test.lib(test.dll)
READOBJ-NEXT: Format: COFF-ARM64EC
READOBJ-NEXT: Format: COFF-ARM64{{$}}
READOBJ-NEXT: Arch: aarch64
READOBJ-NEXT: AddressSize: 64bit
READOBJ-EMPTY:
READOBJ-NEXT: File: test.lib(test.dll)
READOBJ-NEXT: Format: COFF-ARM64EC
READOBJ-NEXT: Format: COFF-ARM64{{$}}
READOBJ-NEXT: Arch: aarch64
READOBJ-NEXT: AddressSize: 64bit
READOBJ-EMPTY:
Expand Down

0 comments on commit 80fcf48

Please sign in to comment.