[lld] 56077e5 - [LLD][COFF] Add support for locally imported EC symbols (#114985)

via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 6 03:09:25 PST 2024


Author: Jacek Caban
Date: 2024-11-06T12:09:22+01:00
New Revision: 56077e5ac09eb2d6b7ca818abce2bbbcf179f529

URL: https://github.com/llvm/llvm-project/commit/56077e5ac09eb2d6b7ca818abce2bbbcf179f529
DIFF: https://github.com/llvm/llvm-project/commit/56077e5ac09eb2d6b7ca818abce2bbbcf179f529.diff

LOG: [LLD][COFF] Add support for locally imported EC symbols (#114985)

Allow imported symbols to be recognized in both mangled and demangled
forms. Support __imp_aux_ symbols in addition to __imp_ symbols.

Added: 
    lld/test/COFF/locally-imported-arm64ec.test

Modified: 
    lld/COFF/SymbolTable.cpp

Removed: 
    


################################################################################
diff  --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp
index aeeebbb4e332ab..35d54d4945f7f4 100644
--- a/lld/COFF/SymbolTable.cpp
+++ b/lld/COFF/SymbolTable.cpp
@@ -501,13 +501,30 @@ bool SymbolTable::resolveRemainingUndefines() {
     // If we can resolve a symbol by removing __imp_ prefix, do that.
     // This odd rule is for compatibility with MSVC linker.
     if (name.starts_with("__imp_")) {
-      Symbol *imp = find(name.substr(strlen("__imp_")));
-      if (imp) {
-        // The unprefixed symbol might come later in symMap, so handle it now
-        // so that the condition below can be appropriately applied.
-        auto *undef = dyn_cast<Undefined>(imp);
-        if (undef) {
-          undef->resolveWeakAlias();
+      auto findLocalSym = [&](StringRef n) {
+        Symbol *sym = find(n);
+        if (auto undef = dyn_cast_or_null<Undefined>(sym)) {
+          // The unprefixed symbol might come later in symMap, so handle it now
+          // if needed.
+          if (!undef->resolveWeakAlias())
+            sym = nullptr;
+        }
+        return sym;
+      };
+
+      StringRef impName = name.substr(strlen("__imp_"));
+      Symbol *imp = findLocalSym(impName);
+      if (!imp && isArm64EC(ctx.config.machine)) {
+        // Try to use the mangled symbol on ARM64EC.
+        std::optional<std::string> mangledName =
+            getArm64ECMangledFunctionName(impName);
+        if (mangledName)
+          imp = findLocalSym(*mangledName);
+        if (!imp && impName.consume_front("aux_")) {
+          // If it's a __imp_aux_ symbol, try skipping the aux_ prefix.
+          imp = findLocalSym(impName);
+          if (!imp && (mangledName = getArm64ECMangledFunctionName(impName)))
+            imp = findLocalSym(*mangledName);
         }
       }
       if (imp && imp->isLazy()) {

diff  --git a/lld/test/COFF/locally-imported-arm64ec.test b/lld/test/COFF/locally-imported-arm64ec.test
new file mode 100644
index 00000000000000..9ec55c2dceaefc
--- /dev/null
+++ b/lld/test/COFF/locally-imported-arm64ec.test
@@ -0,0 +1,68 @@
+REQUIRES: aarch64
+RUN: split-file %s %t.dir && cd %t.dir
+
+RUN: llvm-mc -filetype=obj -triple=arm64ec-windows funcs.s -o funcs.obj
+RUN: llvm-mc -filetype=obj -triple=arm64ec-windows func-mangled.s -o func-mangled.obj
+RUN: llvm-mc -filetype=obj -triple=arm64ec-windows impsym.s -o impsym.obj
+RUN: llvm-mc -filetype=obj -triple=arm64ec-windows impauxsym.s -o impauxsym.obj
+
+Ensure that when both mangled and demangled symbols are present, the __imp_ symbol
+resolves to the demangled symbol.
+
+RUN: lld-link -machine:arm64ec -dll -noentry funcs.obj impsym.obj -out:impsym.dll
+
+RUN: llvm-readobj --coff-basereloc impsym.dll | FileCheck --check-prefix=RELOCS %s
+RELOCS:       Entry {
+RELOCS-NEXT:    Type: DIR64
+RELOCS-NEXT:    Address: 0x2000
+RELOCS-NEXT:  }
+
+RUN: llvm-readobj --hex-dump=.test impsym.dll | FileCheck --check-prefix=TEST %s
+TEST: 0x180003000 00200000
+
+RUN: llvm-readobj --hex-dump=.rdata impsym.dll | FileCheck --check-prefix=RDATA-DEMANGLED %s
+RDATA-MANGLED:   0x180002000 00100080 01000000
+RDATA-DEMANGLED: 0x180002000 04100080 01000000
+
+
+Ensure that when both mangled and demangled symbols are present, the __imp_aux_ symbol
+resolves to the demangled symbol.
+
+RUN: lld-link -machine:arm64ec -dll -noentry funcs.obj impauxsym.obj -out:impauxsym.dll
+RUN: llvm-readobj --hex-dump=.test impauxsym.dll | FileCheck --check-prefix=TEST %s
+RUN: llvm-readobj --hex-dump=.rdata impauxsym.dll | FileCheck --check-prefix=RDATA-DEMANGLED %s
+
+Ensure that if only the mangled symbol is present, the __imp_ symbol resolves to it.
+
+RUN: lld-link -machine:arm64ec -dll -noentry func-mangled.obj impsym.obj -out:impsym-mangled.dll
+RUN: llvm-readobj --coff-basereloc impsym-mangled.dll | FileCheck --check-prefix=RELOCS %s
+RUN: llvm-readobj --hex-dump=.test impsym-mangled.dll | FileCheck --check-prefix=TEST %s
+RUN: llvm-readobj --hex-dump=.rdata impsym-mangled.dll | FileCheck --check-prefix=RDATA-MANGLED %s
+
+Ensure that if only the mangled symbol is present, the __imp_aux_ symbol resolves to it.
+
+RUN: lld-link -machine:arm64ec -dll -noentry func-mangled.obj impauxsym.obj -out:impauxsym-mangled.dll
+RUN: llvm-readobj --hex-dump=.test impauxsym-mangled.dll | FileCheck --check-prefix=TEST %s
+RUN: llvm-readobj --hex-dump=.rdata impauxsym-mangled.dll | FileCheck --check-prefix=RDATA-MANGLED %s
+
+#--- funcs.s
+    .globl "#myfunc"
+"#myfunc":
+    ret
+    .text
+    .globl myfunc
+myfunc:
+    ret
+
+#--- func-mangled.s
+    .globl "#myfunc"
+"#myfunc":
+    ret
+
+#--- impsym.s
+    .section .test, "r"
+    .rva __imp_myfunc
+
+#--- impauxsym.s
+    .section .test, "r"
+    .rva __imp_aux_myfunc


        


More information about the llvm-commits mailing list