-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[llvm-lib] Add support for -defArm64Native argument. #81426
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-llvm-binary-utilities @llvm/pr-subscribers-lld-coff Author: Jacek Caban (cjacek) ChangesThis can be used to create import libraries that contain both ARM64EC and native exports. The implementation follows observed MSVC lib.exe behaviour. It's ignored on targets other than ARM64EC. Full diff: https://github.com/llvm/llvm-project/pull/81426.diff 7 Files Affected:
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 22ee2f133be98a..091aa0df207410 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -939,7 +939,7 @@ std::string LinkerDriver::getImportName(bool asLib) {
void LinkerDriver::createImportLibrary(bool asLib) {
llvm::TimeTraceScope timeScope("Create import library");
- std::vector<COFFShortExport> exports;
+ std::vector<COFFShortExport> exports, nativeExports;
for (Export &e1 : ctx.config.exports) {
COFFShortExport e2;
e2.Name = std::string(e1.name);
@@ -958,8 +958,8 @@ void LinkerDriver::createImportLibrary(bool asLib) {
std::string path = getImplibPath();
if (!ctx.config.incremental) {
- checkError(writeImportLibrary(libName, path, exports, ctx.config.machine,
- ctx.config.mingw));
+ checkError(writeImportLibrary(libName, path, exports, nativeExports,
+ ctx.config.machine, ctx.config.mingw));
return;
}
@@ -968,8 +968,8 @@ void LinkerDriver::createImportLibrary(bool asLib) {
ErrorOr<std::unique_ptr<MemoryBuffer>> oldBuf = MemoryBuffer::getFile(
path, /*IsText=*/false, /*RequiresNullTerminator=*/false);
if (!oldBuf) {
- checkError(writeImportLibrary(libName, path, exports, ctx.config.machine,
- ctx.config.mingw));
+ checkError(writeImportLibrary(libName, path, exports, nativeExports,
+ ctx.config.machine, ctx.config.mingw));
return;
}
@@ -979,7 +979,7 @@ void LinkerDriver::createImportLibrary(bool asLib) {
fatal("cannot create temporary file for import library " + path + ": " +
ec.message());
- if (Error e = writeImportLibrary(libName, tmpName, exports,
+ if (Error e = writeImportLibrary(libName, tmpName, exports, nativeExports,
ctx.config.machine, ctx.config.mingw)) {
checkError(std::move(e));
return;
diff --git a/llvm/include/llvm/Object/COFFImportFile.h b/llvm/include/llvm/Object/COFFImportFile.h
index 46a982ddb7eee6..23c3e6a1f0784a 100644
--- a/llvm/include/llvm/Object/COFFImportFile.h
+++ b/llvm/include/llvm/Object/COFFImportFile.h
@@ -137,6 +137,7 @@ struct COFFShortExport {
Error writeImportLibrary(StringRef ImportName, StringRef Path,
ArrayRef<COFFShortExport> Exports,
+ ArrayRef<COFFShortExport> NativeExports,
COFF::MachineTypes Machine, bool MinGW);
} // namespace object
diff --git a/llvm/lib/Object/COFFImportFile.cpp b/llvm/lib/Object/COFFImportFile.cpp
index a3e5e78952c16a..9175c3ee2a2c4b 100644
--- a/llvm/lib/Object/COFFImportFile.cpp
+++ b/llvm/lib/Object/COFFImportFile.cpp
@@ -625,6 +625,7 @@ NewArchiveMember ObjectFactory::createWeakExternal(StringRef Sym,
Error writeImportLibrary(StringRef ImportName, StringRef Path,
ArrayRef<COFFShortExport> Exports,
+ ArrayRef<COFFShortExport> NativeExports,
MachineTypes Machine, bool MinGW) {
MachineTypes NativeMachine =
@@ -642,66 +643,73 @@ Error writeImportLibrary(StringRef ImportName, StringRef Path,
std::vector<uint8_t> NullThunk;
Members.push_back(OF.createNullThunk(NullThunk));
- for (const COFFShortExport &E : Exports) {
- if (E.Private)
- continue;
-
- ImportType ImportType = IMPORT_CODE;
- if (E.Data)
- ImportType = IMPORT_DATA;
- if (E.Constant)
- ImportType = IMPORT_CONST;
-
- StringRef SymbolName = E.SymbolName.empty() ? E.Name : E.SymbolName;
- std::string Name;
-
- if (E.ExtName.empty()) {
- Name = std::string(SymbolName);
- } else {
- Expected<std::string> ReplacedName =
- replace(SymbolName, E.Name, E.ExtName);
- if (!ReplacedName)
- return ReplacedName.takeError();
- Name.swap(*ReplacedName);
- }
+ auto addExports = [&](ArrayRef<COFFShortExport> Exp,
+ MachineTypes M) -> Error {
+ for (const COFFShortExport &E : Exp) {
+ if (E.Private)
+ continue;
+
+ ImportType ImportType = IMPORT_CODE;
+ if (E.Data)
+ ImportType = IMPORT_DATA;
+ if (E.Constant)
+ ImportType = IMPORT_CONST;
+
+ StringRef SymbolName = E.SymbolName.empty() ? E.Name : E.SymbolName;
+ std::string Name;
+
+ if (E.ExtName.empty()) {
+ Name = std::string(SymbolName);
+ } else {
+ Expected<std::string> ReplacedName =
+ replace(SymbolName, E.Name, E.ExtName);
+ if (!ReplacedName)
+ return ReplacedName.takeError();
+ Name.swap(*ReplacedName);
+ }
- if (!E.AliasTarget.empty() && Name != E.AliasTarget) {
- Members.push_back(
- OF.createWeakExternal(E.AliasTarget, Name, false, Machine));
- Members.push_back(
- OF.createWeakExternal(E.AliasTarget, Name, true, Machine));
- continue;
- }
+ if (!E.AliasTarget.empty() && Name != E.AliasTarget) {
+ Members.push_back(OF.createWeakExternal(E.AliasTarget, Name, false, M));
+ Members.push_back(OF.createWeakExternal(E.AliasTarget, Name, true, M));
+ continue;
+ }
- ImportNameType NameType;
- std::string ExportName;
- if (E.Noname) {
- NameType = IMPORT_ORDINAL;
- } else if (!E.ExportAs.empty()) {
- NameType = IMPORT_NAME_EXPORTAS;
- ExportName = E.ExportAs;
- } else {
- NameType = getNameType(SymbolName, E.Name, Machine, MinGW);
- }
+ ImportNameType NameType;
+ std::string ExportName;
+ if (E.Noname) {
+ NameType = IMPORT_ORDINAL;
+ } else if (!E.ExportAs.empty()) {
+ NameType = IMPORT_NAME_EXPORTAS;
+ ExportName = E.ExportAs;
+ } else {
+ NameType = getNameType(SymbolName, E.Name, M, MinGW);
+ }
- // On ARM64EC, use EXPORTAS to import demangled name for mangled symbols.
- if (ImportType == IMPORT_CODE && isArm64EC(Machine)) {
- if (std::optional<std::string> MangledName =
- getArm64ECMangledFunctionName(Name)) {
- if (ExportName.empty()) {
+ // On ARM64EC, use EXPORTAS to import demangled name for mangled symbols.
+ if (ImportType == IMPORT_CODE && isArm64EC(M)) {
+ if (std::optional<std::string> MangledName =
+ getArm64ECMangledFunctionName(Name)) {
+ if (ExportName.empty()) {
+ NameType = IMPORT_NAME_EXPORTAS;
+ ExportName.swap(Name);
+ }
+ Name = std::move(*MangledName);
+ } else if (ExportName.empty()) {
NameType = IMPORT_NAME_EXPORTAS;
- ExportName.swap(Name);
+ ExportName = std::move(*getArm64ECDemangledFunctionName(Name));
}
- Name = std::move(*MangledName);
- } else if (ExportName.empty()) {
- NameType = IMPORT_NAME_EXPORTAS;
- ExportName = std::move(*getArm64ECDemangledFunctionName(Name));
}
+
+ Members.push_back(OF.createShortImport(Name, E.Ordinal, ImportType,
+ NameType, ExportName, M));
}
+ return Error::success();
+ };
- Members.push_back(OF.createShortImport(Name, E.Ordinal, ImportType,
- NameType, ExportName, Machine));
- }
+ if (Error e = addExports(Exports, Machine))
+ return e;
+ if (Error e = addExports(NativeExports, NativeMachine))
+ return e;
return writeArchive(Path, Members, SymtabWritingMode::NormalSymtab,
MinGW ? object::Archive::K_GNU : object::Archive::K_COFF,
diff --git a/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp b/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp
index 834903857a88eb..0749580c78a570 100644
--- a/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp
+++ b/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp
@@ -215,8 +215,9 @@ int llvm::dlltoolDriverMain(llvm::ArrayRef<const char *> ArgsArr) {
}
}
- if (!Path.empty() && writeImportLibrary(Def->OutputFile, Path, Def->Exports,
- Machine, /*MinGW=*/true))
+ if (!Path.empty() &&
+ writeImportLibrary(Def->OutputFile, Path, Def->Exports, std::nullopt,
+ Machine, /*MinGW=*/true))
return 1;
return 0;
}
diff --git a/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp b/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp
index 5d7ec0fb03098c..3baa0a08c73d1e 100644
--- a/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp
+++ b/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp
@@ -392,8 +392,34 @@ int llvm::libDriverMain(ArrayRef<const char *> ArgsArr) {
return 1;
}
- return writeImportLibrary(Def->OutputFile, OutputPath, Def->Exports,
- LibMachine,
+ std::vector<COFFShortExport> NativeExports;
+ std::string OutputFile = Def->OutputFile;
+
+ if (isArm64EC(LibMachine) && Args.hasArg(OPT_nativedeffile)) {
+ std::unique_ptr<MemoryBuffer> NativeMB =
+ openFile(Args.getLastArg(OPT_nativedeffile)->getValue());
+ if (!NativeMB)
+ return 1;
+
+ if (!NativeMB->getBufferSize()) {
+ llvm::errs() << "native definition file empty\n";
+ return 1;
+ }
+
+ Expected<COFFModuleDefinition> NativeDef =
+ parseCOFFModuleDefinition(*NativeMB, COFF::IMAGE_FILE_MACHINE_ARM64);
+
+ if (!NativeDef) {
+ llvm::errs() << "error parsing native definition\n"
+ << errorToErrorCode(NativeDef.takeError()).message();
+ return 1;
+ }
+ NativeExports = std::move(NativeDef->Exports);
+ OutputFile = std::move(NativeDef->OutputFile);
+ }
+
+ return writeImportLibrary(OutputFile, OutputPath, Def->Exports,
+ NativeExports, LibMachine,
/*MinGW=*/false)
? 1
: 0;
diff --git a/llvm/lib/ToolDrivers/llvm-lib/Options.td b/llvm/lib/ToolDrivers/llvm-lib/Options.td
index 22ac1fb842e4db..98da2497525b1b 100644
--- a/llvm/lib/ToolDrivers/llvm-lib/Options.td
+++ b/llvm/lib/ToolDrivers/llvm-lib/Options.td
@@ -23,6 +23,7 @@ def libpath: P<"libpath", "Object file search path">;
def lst : F<"list">, HelpText<"List contents of .lib file on stdout">;
def out : P<"out", "Path to file to write output">;
def deffile : P<"def", "def file to use to generate import library">;
+def nativedeffile : P<"defArm64Native", "def file to use to generate native ARM64 symbols in ARM64X import library">;
def llvmlibthin : F<"llvmlibthin">,
HelpText<"Make .lib point to .obj files instead of copying their contents">;
diff --git a/llvm/test/tools/llvm-lib/arm64ec-implib.test b/llvm/test/tools/llvm-lib/arm64ec-implib.test
index c583ef75b2b0aa..77bdc23589fd25 100644
--- a/llvm/test/tools/llvm-lib/arm64ec-implib.test
+++ b/llvm/test/tools/llvm-lib/arm64ec-implib.test
@@ -98,6 +98,208 @@ RUN: llvm-lib -machine:arm64ec test.lib -out:test2.lib
RUN: llvm-nm --print-armap test2.lib | FileCheck -check-prefix=ARMAP %s
+RUN: llvm-lib -machine:arm64ec -def:test.def -defArm64Native:test.def -out:testx.lib
+
+RUN: llvm-nm --print-armap testx.lib | FileCheck -check-prefix=ARMAPX %s
+
+ARMAPX: Archive map
+ARMAPX-NEXT: #mangledfunc in test.dll
+ARMAPX-NEXT: ?test_cpp_func@@YAHPEAX@Z in test.dll
+ARMAPX-NEXT: __IMPORT_DESCRIPTOR_test in test.dll
+ARMAPX-NEXT: __NULL_IMPORT_DESCRIPTOR in test.dll
+ARMAPX-NEXT: __imp_#mangledfunc in test.dll
+ARMAPX-NEXT: __imp_?test_cpp_func@@YAHPEAX@Z in test.dll
+ARMAPX-NEXT: __imp_dataexp in test.dll
+ARMAPX-NEXT: __imp_expname in test.dll
+ARMAPX-NEXT: __imp_funcexp in test.dll
+ARMAPX-NEXT: expname in test.dll
+ARMAPX-NEXT: funcexp in test.dll
+ARMAPX-NEXT: test_NULL_THUNK_DATA in test.dll
+ARMAPX-EMPTY:
+ARMAPX-NEXT: Archive EC map
+ARMAPX-NEXT: #expname in test.dll
+ARMAPX-NEXT: #funcexp in test.dll
+ARMAPX-NEXT: #mangledfunc in test.dll
+ARMAPX-NEXT: ?test_cpp_func@@$$hYAHPEAX@Z in test.dll
+ARMAPX-NEXT: ?test_cpp_func@@YAHPEAX@Z in test.dll
+ARMAPX-NEXT: __imp_?test_cpp_func@@YAHPEAX@Z in test.dll
+ARMAPX-NEXT: __imp_aux_?test_cpp_func@@YAHPEAX@Z in test.dll
+ARMAPX-NEXT: __imp_aux_expname in test.dll
+ARMAPX-NEXT: __imp_aux_funcexp in test.dll
+ARMAPX-NEXT: __imp_aux_mangledfunc in test.dll
+ARMAPX-NEXT: __imp_dataexp in test.dll
+ARMAPX-NEXT: __imp_expname in test.dll
+ARMAPX-NEXT: __imp_funcexp in test.dll
+ARMAPX-NEXT: __imp_mangledfunc in test.dll
+ARMAPX-NEXT: expname in test.dll
+ARMAPX-NEXT: funcexp in test.dll
+ARMAPX-NEXT: mangledfunc in test.dll
+
+RUN: llvm-readobj testx.lib | FileCheck -check-prefix=READOBJX %s
+
+READOBJX: File: testx.lib(test.dll)
+READOBJX-NEXT: Format: COFF-ARM64
+READOBJX-NEXT: Arch: aarch64
+READOBJX-NEXT: AddressSize: 64bit
+READOBJX-EMPTY:
+READOBJX-NEXT: File: testx.lib(test.dll)
+READOBJX-NEXT: Format: COFF-ARM64
+READOBJX-NEXT: Arch: aarch64
+READOBJX-NEXT: AddressSize: 64bit
+READOBJX-EMPTY:
+READOBJX-NEXT: File: testx.lib(test.dll)
+READOBJX-NEXT: Format: COFF-ARM64
+READOBJX-NEXT: Arch: aarch64
+READOBJX-NEXT: AddressSize: 64bit
+READOBJX-EMPTY:
+READOBJX-NEXT: File: test.dll
+READOBJX-NEXT: Format: COFF-import-file-ARM64EC
+READOBJX-NEXT: Type: code
+READOBJX-NEXT: Name type: export as
+READOBJX-NEXT: Export name: funcexp
+READOBJX-NEXT: Symbol: __imp_funcexp
+READOBJX-NEXT: Symbol: funcexp
+READOBJX-NEXT: Symbol: __imp_aux_funcexp
+READOBJX-NEXT: Symbol: #funcexp
+READOBJX-EMPTY:
+READOBJX-NEXT: File: test.dll
+READOBJX-NEXT: Format: COFF-import-file-ARM64EC
+READOBJX-NEXT: Type: code
+READOBJX-NEXT: Name type: export as
+READOBJX-NEXT: Export name: mangledfunc
+READOBJX-NEXT: Symbol: __imp_mangledfunc
+READOBJX-NEXT: Symbol: mangledfunc
+READOBJX-NEXT: Symbol: __imp_aux_mangledfunc
+READOBJX-NEXT: Symbol: #mangledfunc
+READOBJX-EMPTY:
+READOBJX-NEXT: File: test.dll
+READOBJX-NEXT: Format: COFF-import-file-ARM64EC
+READOBJX-NEXT: Type: code
+READOBJX-NEXT: Name type: export as
+READOBJX-NEXT: Export name: ?test_cpp_func@@YAHPEAX@Z
+READOBJX-NEXT: Symbol: __imp_?test_cpp_func@@YAHPEAX@Z
+READOBJX-NEXT: Symbol: ?test_cpp_func@@YAHPEAX@Z
+READOBJX-NEXT: Symbol: __imp_aux_?test_cpp_func@@YAHPEAX@Z
+READOBJX-NEXT: Symbol: ?test_cpp_func@@$$hYAHPEAX@Z
+READOBJX-EMPTY:
+READOBJX-NEXT: File: test.dll
+READOBJX-NEXT: Format: COFF-import-file-ARM64EC
+READOBJX-NEXT: Type: code
+READOBJX-NEXT: Name type: export as
+READOBJX-NEXT: Export name: expname
+READOBJX-NEXT: Symbol: __imp_expname
+READOBJX-NEXT: Symbol: expname
+READOBJX-NEXT: Symbol: __imp_aux_expname
+READOBJX-NEXT: Symbol: #expname
+READOBJX-EMPTY:
+READOBJX-NEXT: File: test.dll
+READOBJX-NEXT: Format: COFF-import-file-ARM64EC
+READOBJX-NEXT: Type: data
+READOBJX-NEXT: Name type: name
+READOBJX-NEXT: Export name: dataexp
+READOBJX-NEXT: Symbol: __imp_dataexp
+READOBJX-EMPTY:
+READOBJX-NEXT: File: test.dll
+READOBJX-NEXT: Format: COFF-import-file-ARM64
+READOBJX-NEXT: Type: code
+READOBJX-NEXT: Name type: name
+READOBJX-NEXT: Export name: funcexp
+READOBJX-NEXT: Symbol: __imp_funcexp
+READOBJX-NEXT: Symbol: funcexp
+READOBJX-EMPTY:
+READOBJX-NEXT: File: test.dll
+READOBJX-NEXT: Format: COFF-import-file-ARM64
+READOBJX-NEXT: Type: code
+READOBJX-NEXT: Name type: name
+READOBJX-NEXT: Export name: #mangledfunc
+READOBJX-NEXT: Symbol: __imp_#mangledfunc
+READOBJX-NEXT: Symbol: #mangledfunc
+READOBJX-EMPTY:
+READOBJX-NEXT: File: test.dll
+READOBJX-NEXT: Format: COFF-import-file-ARM64
+READOBJX-NEXT: Type: code
+READOBJX-NEXT: Name type: name
+READOBJX-NEXT: Export name: ?test_cpp_func@@YAHPEAX@Z
+READOBJX-NEXT: Symbol: __imp_?test_cpp_func@@YAHPEAX@Z
+READOBJX-NEXT: Symbol: ?test_cpp_func@@YAHPEAX@Z
+READOBJX-EMPTY:
+READOBJX-NEXT: File: test.dll
+READOBJX-NEXT: Format: COFF-import-file-ARM64
+READOBJX-NEXT: Type: code
+READOBJX-NEXT: Name type: name
+READOBJX-NEXT: Export name: expname
+READOBJX-NEXT: Symbol: __imp_expname
+READOBJX-NEXT: Symbol: expname
+READOBJX-EMPTY:
+READOBJX-NEXT: File: test.dll
+READOBJX-NEXT: Format: COFF-import-file-ARM64
+READOBJX-NEXT: Type: data
+READOBJX-NEXT: Name type: name
+READOBJX-NEXT: Export name: dataexp
+READOBJX-NEXT: Symbol: __imp_dataexp
+
+
+RUN: llvm-lib -machine:arm64ec -def:test.def -defArm64Native:test2.def -out:test2.lib
+RUN: llvm-nm --print-armap test2.lib | FileCheck -check-prefix=ARMAPX2 %s
+
+ARMAPX2: Archive map
+ARMAPX2-NEXT: __IMPORT_DESCRIPTOR_test2 in test2.dll
+ARMAPX2-NEXT: __NULL_IMPORT_DESCRIPTOR in test2.dll
+ARMAPX2-NEXT: __imp_otherfunc in test2.dll
+ARMAPX2-NEXT: otherfunc in test2.dll
+ARMAPX2-NEXT: test2_NULL_THUNK_DATA in test2.dll
+ARMAPX2-EMPTY:
+ARMAPX2-NEXT: Archive EC map
+ARMAPX2-NEXT: #expname in test2.dll
+ARMAPX2-NEXT: #funcexp in test2.dll
+ARMAPX2-NEXT: #mangledfunc in test2.dll
+ARMAPX2-NEXT: ?test_cpp_func@@$$hYAHPEAX@Z in test2.dll
+ARMAPX2-NEXT: ?test_cpp_func@@YAHPEAX@Z in test2.dll
+ARMAPX2-NEXT: __imp_?test_cpp_func@@YAHPEAX@Z in test2.dll
+ARMAPX2-NEXT: __imp_aux_?test_cpp_func@@YAHPEAX@Z in test2.dll
+ARMAPX2-NEXT: __imp_aux_expname in test2.dll
+ARMAPX2-NEXT: __imp_aux_funcexp in test2.dll
+ARMAPX2-NEXT: __imp_aux_mangledfunc in test2.dll
+ARMAPX2-NEXT: __imp_dataexp in test2.dll
+ARMAPX2-NEXT: __imp_expname in test2.dll
+ARMAPX2-NEXT: __imp_funcexp in test2.dll
+ARMAPX2-NEXT: __imp_mangledfunc in test2.dll
+ARMAPX2-NEXT: expname in test2.dll
+ARMAPX2-NEXT: funcexp in test2.dll
+ARMAPX2-NEXT: mangledfunc in test2.dll
+
+ARMAPX2: test2.dll:
+ARMAPX2: 00000000 T #funcexp
+ARMAPX2-NEXT: 00000000 T __imp_aux_funcexp
+ARMAPX2-NEXT: 00000000 T __imp_funcexp
+ARMAPX2-NEXT: 00000000 T funcexp
+ARMAPX2-EMPTY:
+ARMAPX2-NEXT: test2.dll:
+ARMAPX2-NEXT: 00000000 T #mangledfunc
+ARMAPX2-NEXT: 00000000 T __imp_aux_mangledfunc
+ARMAPX2-NEXT: 00000000 T __imp_mangledfunc
+ARMAPX2-NEXT: 00000000 T mangledfunc
+ARMAPX2-EMPTY:
+ARMAPX2-NEXT: test2.dll:
+ARMAPX2-NEXT: 00000000 T ?test_cpp_func@@$$hYAHPEAX@Z
+ARMAPX2-NEXT: 00000000 T ?test_cpp_func@@YAHPEAX@Z
+ARMAPX2-NEXT: 00000000 T __imp_?test_cpp_func@@YAHPEAX@Z
+ARMAPX2-NEXT: 00000000 T __imp_aux_?test_cpp_func@@YAHPEAX@Z
+ARMAPX2-EMPTY:
+ARMAPX2-NEXT: test2.dll:
+ARMAPX2-NEXT: 00000000 T #expname
+ARMAPX2-NEXT: 00000000 T __imp_aux_expname
+ARMAPX2-NEXT: 00000000 T __imp_expname
+ARMAPX2-NEXT: 00000000 T expname
+ARMAPX2-EMPTY:
+ARMAPX2-NEXT: test2.dll:
+ARMAPX2-NEXT: 00000000 D __imp_dataexp
+ARMAPX2-EMPTY:
+ARMAPX2-NEXT: test2.dll:
+ARMAPX2-NEXT: 00000000 T __imp_otherfunc
+ARMAPX2-NEXT: 00000000 T otherfunc
+
+
RUN: llvm-lib -machine:arm64ec -def:exportas.def -out:exportas.lib
RUN: llvm-nm --print-armap exportas.lib | FileCheck -check-prefix=EXPAS-ARMAP %s
RUN: llvm-readobj exportas.lib | FileCheck -check-prefix=EXPAS-READOBJ %s
@@ -186,6 +388,11 @@ EXPORTS
expname=impname
dataexp DATA
+#--- test2.def
+LIBRARY test2.dll
+EXPORTS
+ otherfunc
+
#--- exportas.def
LIBRARY test.dll
EXPORTS
|
@@ -23,6 +23,7 @@ def libpath: P<"libpath", "Object file search path">; | |||
def lst : F<"list">, HelpText<"List contents of .lib file on stdout">; | |||
def out : P<"out", "Path to file to write output">; | |||
def deffile : P<"def", "def file to use to generate import library">; | |||
def nativedeffile : P<"defArm64Native", "def file to use to generate native ARM64 symbols in ARM64X import library">; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ARM64X
or ARM64EC
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to underline the fact that such libraries can be used by both ARM64EC and pure ARM64 target. Thinking about it again, using ARM64X for static libraries may be misleading, it's not exactly an analogue of ARM64X PE images. I will change it, thanks.
This can be used to create import libraries that contain both ARM64EC and native exports. The implementation follows observed MSVC lib.exe behaviour. It's ignored on targets other than ARM64EC.
if (!Path.empty() && writeImportLibrary(Def->OutputFile, Path, Def->Exports, | ||
Machine, /*MinGW=*/true)) | ||
if (!Path.empty() && | ||
writeImportLibrary(Def->OutputFile, Path, Def->Exports, std::nullopt, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see that you're passing std::nullopt
here, while in lld/COFF, you pass a real initialized array (which isn't ever used other than passing into this function). Is this because you're planning on using the array in lld?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I plan on using it in both llvm-dlltool and lld. I plan to submit llvm-dlltool as soon as this PR settles, lld part will need general ARM64X support in lld, to it will take more time. There was no strong reason to differentiate them in this PR, I guess it was easy to extract the declaration in lld from my WIP tree, while llvm-dlltool will need a small bit of refactoring.
@@ -98,6 +98,208 @@ RUN: llvm-lib -machine:arm64ec test.lib -out:test2.lib | |||
RUN: llvm-nm --print-armap test2.lib | FileCheck -check-prefix=ARMAP %s | |||
|
|||
|
|||
RUN: llvm-lib -machine:arm64ec -def:test.def -defArm64Native:test.def -out:testx.lib | |||
|
|||
RUN: llvm-nm --print-armap testx.lib | FileCheck -check-prefix=ARMAPX %s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does ARMAPX
stand for here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ARMAP part was picked after --print-armap llvm-nm argument, I guess it's "archive map". The X suffix is just something different than other tests and matches picked file name suffix. The inspiration to pick X was ARM64X (although that may not be the best choice, as mentioned in the earlier comment).
@@ -137,6 +137,7 @@ struct COFFShortExport { | |||
|
|||
Error writeImportLibrary(StringRef ImportName, StringRef Path, | |||
ArrayRef<COFFShortExport> Exports, | |||
ArrayRef<COFFShortExport> NativeExports, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For users of this API, could you add a comment about the difference between Exports and NativeExports?
(Rust is pondering what to do here: rust-lang/rust#120996)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I created #81600 with a clarification.
This can be used to create import libraries that contain both ARM64EC and native exports. The implementation follows observed MSVC lib.exe behaviour. It's ignored on targets other than ARM64EC.