[lld] [LLD][COFF] Write both native and EC export symbols to the import library on ARM64X (PR #124833)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 28 12:43:49 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-platform-windows
@llvm/pr-subscribers-lld
Author: Jacek Caban (cjacek)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/124833.diff
2 Files Affected:
- (modified) lld/COFF/Driver.cpp (+32-19)
- (modified) lld/test/COFF/arm64x-export.test (+41)
``````````diff
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index ac3ac57bd17f44..b848e0d81dfa76 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -954,20 +954,31 @@ std::string LinkerDriver::getImportName(bool asLib) {
void LinkerDriver::createImportLibrary(bool asLib) {
llvm::TimeTraceScope timeScope("Create import library");
- std::vector<COFFShortExport> exports;
- for (Export &e1 : ctx.symtab.exports) {
- COFFShortExport e2;
- e2.Name = std::string(e1.name);
- e2.SymbolName = std::string(e1.symbolName);
- e2.ExtName = std::string(e1.extName);
- e2.ExportAs = std::string(e1.exportAs);
- e2.ImportName = std::string(e1.importName);
- e2.Ordinal = e1.ordinal;
- e2.Noname = e1.noname;
- e2.Data = e1.data;
- e2.Private = e1.isPrivate;
- e2.Constant = e1.constant;
- exports.push_back(e2);
+ std::vector<COFFShortExport> exports, nativeExports;
+
+ auto getExports = [](SymbolTable &symtab,
+ std::vector<COFFShortExport> &exports) {
+ for (Export &e1 : symtab.exports) {
+ COFFShortExport e2;
+ e2.Name = std::string(e1.name);
+ e2.SymbolName = std::string(e1.symbolName);
+ e2.ExtName = std::string(e1.extName);
+ e2.ExportAs = std::string(e1.exportAs);
+ e2.ImportName = std::string(e1.importName);
+ e2.Ordinal = e1.ordinal;
+ e2.Noname = e1.noname;
+ e2.Data = e1.data;
+ e2.Private = e1.isPrivate;
+ e2.Constant = e1.constant;
+ exports.push_back(e2);
+ }
+ };
+
+ if (ctx.hybridSymtab) {
+ getExports(ctx.symtab, nativeExports);
+ getExports(*ctx.hybridSymtab, exports);
+ } else {
+ getExports(ctx.symtab, exports);
}
std::string libName = getImportName(asLib);
@@ -975,7 +986,7 @@ void LinkerDriver::createImportLibrary(bool asLib) {
if (!ctx.config.incremental) {
checkError(writeImportLibrary(libName, path, exports, ctx.config.machine,
- ctx.config.mingw));
+ ctx.config.mingw, nativeExports));
return;
}
@@ -985,7 +996,7 @@ void LinkerDriver::createImportLibrary(bool asLib) {
path, /*IsText=*/false, /*RequiresNullTerminator=*/false);
if (!oldBuf) {
checkError(writeImportLibrary(libName, path, exports, ctx.config.machine,
- ctx.config.mingw));
+ ctx.config.mingw, nativeExports));
return;
}
@@ -995,8 +1006,9 @@ void LinkerDriver::createImportLibrary(bool asLib) {
Fatal(ctx) << "cannot create temporary file for import library " << path
<< ": " << ec.message();
- if (Error e = writeImportLibrary(libName, tmpName, exports,
- ctx.config.machine, ctx.config.mingw)) {
+ if (Error e =
+ writeImportLibrary(libName, tmpName, exports, ctx.config.machine,
+ ctx.config.mingw, nativeExports)) {
checkError(std::move(e));
return;
}
@@ -2668,7 +2680,8 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
// Windows specific -- when we are creating a .dll file, we also
// need to create a .lib file. In MinGW mode, we only do that when the
// -implib option is given explicitly, for compatibility with GNU ld.
- if (!ctx.symtab.exports.empty() || config->dll) {
+ if (config->dll || !ctx.symtab.exports.empty() ||
+ (ctx.hybridSymtab && !ctx.hybridSymtab->exports.empty())) {
llvm::TimeTraceScope timeScope("Create .lib exports");
ctx.forEachSymtab([](SymbolTable &symtab) { symtab.fixupExports(); });
if (!config->noimplib && (!config->mingw || !config->implib.empty()))
diff --git a/lld/test/COFF/arm64x-export.test b/lld/test/COFF/arm64x-export.test
index 3ae0725a67089f..bae40af4585ae1 100644
--- a/lld/test/COFF/arm64x-export.test
+++ b/lld/test/COFF/arm64x-export.test
@@ -48,12 +48,40 @@ EXPORTS-EC-NEXT: RVA: 0x2000
EXPORTS-EC-NEXT: }
EXPORTS-EC-NEXT: }
+RUN: llvm-readobj out-cmd.lib | FileCheck --check-prefixes=IMPLIB-HEADER,IMPLIB-EC %s
+IMPLIB-HEADER: File: out-{{.*}}.lib(out{{.*}}.dll)
+IMPLIB-HEADER-NEXT: Format: COFF-ARM64
+IMPLIB-HEADER-NEXT: Arch: aarch64
+IMPLIB-HEADER-NEXT: AddressSize: 64bit
+IMPLIB-HEADER-EMPTY:
+IMPLIB-HEADER-NEXT: File: out-{{.*}}.lib(out{{.*}}.dll)
+IMPLIB-HEADER-NEXT: Format: COFF-ARM64
+IMPLIB-HEADER-NEXT: Arch: aarch64
+IMPLIB-HEADER-NEXT: AddressSize: 64bit
+IMPLIB-HEADER-EMPTY:
+IMPLIB-HEADER-NEXT: File: out-{{.*}}.lib(out{{.*}}.dll)
+IMPLIB-HEADER-NEXT: Format: COFF-ARM64
+IMPLIB-HEADER-NEXT: Arch: aarch64
+IMPLIB-HEADER-NEXT: AddressSize: 64bit
+IMPLIB-HEADER-EMPTY:
+IMPLIB-EC: File: out{{.*}}.dll
+IMPLIB-EC-NEXT: Format: COFF-import-file-ARM64EC
+IMPLIB-EC-NEXT: Type: code
+IMPLIB-EC-NEXT: Name type: export as
+IMPLIB-EC-NEXT: Export name: func
+IMPLIB-EC-NEXT: Symbol: __imp_func
+IMPLIB-EC-NEXT: Symbol: func
+IMPLIB-EC-NEXT: Symbol: __imp_aux_func
+IMPLIB-EC-NEXT: Symbol: #func
+
+
# Export using the EC .drectve section.
RUN: lld-link -machine:arm64x -dll -out:out-drectve-ec.dll arm64ec-func.obj arm64-func.obj \
RUN: loadconfig-arm64.obj loadconfig-arm64ec.obj arm64ec-drectve.obj -noentry
RUN: llvm-objdump -d out-drectve-ec.dll | FileCheck --check-prefix=DISASM-EC %s
RUN: llvm-readobj --headers --coff-exports out-drectve-ec.dll | FileCheck --check-prefix=EXPORTS-EC %s
+RUN: llvm-readobj out-drectve-ec.lib | FileCheck --check-prefixes=IMPLIB-HEADER,IMPLIB-EC %s
# A command-line def file applies only to EC exports.
@@ -61,6 +89,7 @@ RUN: lld-link -machine:arm64x -dll -out:out-def-ec.dll arm64ec-func.obj arm64-fu
RUN: loadconfig-arm64.obj loadconfig-arm64ec.obj -def:func.def -noentry
RUN: llvm-objdump -d out-def-ec.dll | FileCheck --check-prefix=DISASM-EC %s
RUN: llvm-readobj --headers --coff-exports out-def-ec.dll | FileCheck --check-prefix=EXPORTS-EC %s
+RUN: llvm-readobj out-def-ec.lib | FileCheck --check-prefixes=IMPLIB-HEADER,IMPLIB-EC %s
# Export using the EC .edata section.
@@ -111,6 +140,15 @@ EXPORTS-NATIVE: ExportTableRVA: 0x0
EXPORTS-NATIVE-NEXT: ExportTableSize: 0x0
EXPORTS-NATIVE-NOT: Name: func
+RUN: llvm-readobj out-drectve-native.lib | FileCheck --check-prefixes=IMPLIB-HEADER,IMPLIB-NATIVE %s
+IMPLIB-NATIVE: File: out{{.*}}.dll
+IMPLIB-NATIVE-NEXT: Format: COFF-import-file-ARM64
+IMPLIB-NATIVE-NEXT: Type: code
+IMPLIB-NATIVE-NEXT: Name type: name
+IMPLIB-NATIVE-NEXT: Export name: func
+IMPLIB-NATIVE-NEXT: Symbol: __imp_func
+IMPLIB-NATIVE-NEXT: Symbol: func
+
# Export using the native .edata section.
RUN: lld-link -machine:arm64x -dll -out:out-edata.dll arm64ec-func.obj arm64-func.obj \
@@ -162,12 +200,15 @@ EXPORTS-BOTH-NEXT: RVA: 0x3000
EXPORTS-BOTH-NEXT: }
EXPORTS-BOTH-NEXT: }
+RUN: llvm-readobj out-both.lib | FileCheck --check-prefixes=IMPLIB-HEADER,IMPLIB-EC,IMPLIB-NATIVE %s
+
# Export using both the -def and -defarm64native arguments.
RUN: lld-link -machine:arm64x -dll -out:out-def-both.dll arm64ec-func.obj arm64-func.obj \
RUN: loadconfig-arm64.obj loadconfig-arm64ec.obj -def:func.def -defarm64native:func.def -noentry
RUN: llvm-objdump -d out-def-both.dll | FileCheck --check-prefix=DISASM-BOTH %s
RUN: llvm-readobj --headers --coff-exports out-def-both.dll | FileCheck --check-prefix=EXPORTS-BOTH %s
+RUN: llvm-readobj out-def-both.lib | FileCheck --check-prefixes=IMPLIB-HEADER,IMPLIB-EC,IMPLIB-NATIVE %s
# -defarm64native is ignored if -def is not specified.
``````````
</details>
https://github.com/llvm/llvm-project/pull/124833
More information about the llvm-commits
mailing list