[llvm] [llvm-lib][Object][COFF] Use ARM64 machine type for import library descriptor objects. (PR #78537)
Jacek Caban via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 17 19:04:10 PST 2024
https://github.com/cjacek updated https://github.com/llvm/llvm-project/pull/78537
>From 7a579af0d20eee6b5cd9ac276157331c8e4c0b11 Mon Sep 17 00:00:00 2001
From: Jacek Caban <jacek at codeweavers.com>
Date: Wed, 17 Jan 2024 18:43:29 +0100
Subject: [PATCH 1/2] [llvm-lib][Object][COFF] Use ARM64 machine type for
import library descriptor objects.
---
llvm/lib/Object/COFFImportFile.cpp | 61 +++++++++++---------
llvm/test/tools/llvm-lib/arm64ec-implib.test | 14 +++--
2 files changed, 43 insertions(+), 32 deletions(-)
diff --git a/llvm/lib/Object/COFFImportFile.cpp b/llvm/lib/Object/COFFImportFile.cpp
index b60e32f498eb5a..60556c149bf735 100644
--- a/llvm/lib/Object/COFFImportFile.cpp
+++ b/llvm/lib/Object/COFFImportFile.cpp
@@ -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;
@@ -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()) {}
@@ -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
@@ -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)) +
@@ -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);
@@ -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);
@@ -336,7 +340,7 @@ 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)) +
@@ -344,7 +348,7 @@ ObjectFactory::createNullImportDescriptor(std::vector<uint8_t> &Buffer) {
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);
@@ -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)) +
@@ -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);
@@ -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'},
@@ -436,8 +439,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)},
};
@@ -445,12 +447,12 @@ NewArchiveMember ObjectFactory::createNullThunk(std::vector<uint8_t> &Buffer) {
// .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
@@ -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);
@@ -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;
@@ -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));
@@ -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,
diff --git a/llvm/test/tools/llvm-lib/arm64ec-implib.test b/llvm/test/tools/llvm-lib/arm64ec-implib.test
index 3c74b4bf660765..1071f8ca877838 100644
--- a/llvm/test/tools/llvm-lib/arm64ec-implib.test
+++ b/llvm/test/tools/llvm-lib/arm64ec-implib.test
@@ -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:
@@ -38,7 +40,7 @@ READOBJ-NEXT: Symbol: __imp_funcexp
READOBJ-NEXT: Symbol: funcexp
READOBJ-EMPTY:
READOBJ-NEXT: File: test.dll
-READOBJ-NEXT: Format: COFF-import-file-ARM64EC
+READOBJ-NEXT: Format: COFF-import-file-ARM64
READOBJ-NEXT: Type: data
READOBJ-NEXT: Name type: name
READOBJ-NEXT: Symbol: __imp_dataexp
>From 763ad5d437707d9d7289e8215c688a64b1557082 Mon Sep 17 00:00:00 2001
From: Jacek Caban <jacek at codeweavers.com>
Date: Thu, 18 Jan 2024 04:03:45 +0100
Subject: [PATCH 2/2] Make tests more strict
---
llvm/test/tools/llvm-lib/arm64ec-implib.test | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/llvm/test/tools/llvm-lib/arm64ec-implib.test b/llvm/test/tools/llvm-lib/arm64ec-implib.test
index 1071f8ca877838..2672f8d38b7f70 100644
--- a/llvm/test/tools/llvm-lib/arm64ec-implib.test
+++ b/llvm/test/tools/llvm-lib/arm64ec-implib.test
@@ -18,17 +18,17 @@ ARMAP-NEXT: funcexp in test.dll
RUN: llvm-readobj test.lib | FileCheck -check-prefix=READOBJ %s
READOBJ: File: test.lib(test.dll)
-READOBJ-NEXT: Format: COFF-ARM64
+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-ARM64
+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-ARM64
+READOBJ-NEXT: Format: COFF-ARM64{{$}}
READOBJ-NEXT: Arch: aarch64
READOBJ-NEXT: AddressSize: 64bit
READOBJ-EMPTY:
@@ -40,7 +40,7 @@ READOBJ-NEXT: Symbol: __imp_funcexp
READOBJ-NEXT: Symbol: funcexp
READOBJ-EMPTY:
READOBJ-NEXT: File: test.dll
-READOBJ-NEXT: Format: COFF-import-file-ARM64
+READOBJ-NEXT: Format: COFF-import-file-ARM64EC
READOBJ-NEXT: Type: data
READOBJ-NEXT: Name type: name
READOBJ-NEXT: Symbol: __imp_dataexp
More information about the llvm-commits
mailing list