[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