Skip to content

Commit 56077e5

Browse files
authored
[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.
1 parent ea6b8fa commit 56077e5

File tree

2 files changed

+92
-7
lines changed

2 files changed

+92
-7
lines changed

lld/COFF/SymbolTable.cpp

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -501,13 +501,30 @@ bool SymbolTable::resolveRemainingUndefines() {
501501
// If we can resolve a symbol by removing __imp_ prefix, do that.
502502
// This odd rule is for compatibility with MSVC linker.
503503
if (name.starts_with("__imp_")) {
504-
Symbol *imp = find(name.substr(strlen("__imp_")));
505-
if (imp) {
506-
// The unprefixed symbol might come later in symMap, so handle it now
507-
// so that the condition below can be appropriately applied.
508-
auto *undef = dyn_cast<Undefined>(imp);
509-
if (undef) {
510-
undef->resolveWeakAlias();
504+
auto findLocalSym = [&](StringRef n) {
505+
Symbol *sym = find(n);
506+
if (auto undef = dyn_cast_or_null<Undefined>(sym)) {
507+
// The unprefixed symbol might come later in symMap, so handle it now
508+
// if needed.
509+
if (!undef->resolveWeakAlias())
510+
sym = nullptr;
511+
}
512+
return sym;
513+
};
514+
515+
StringRef impName = name.substr(strlen("__imp_"));
516+
Symbol *imp = findLocalSym(impName);
517+
if (!imp && isArm64EC(ctx.config.machine)) {
518+
// Try to use the mangled symbol on ARM64EC.
519+
std::optional<std::string> mangledName =
520+
getArm64ECMangledFunctionName(impName);
521+
if (mangledName)
522+
imp = findLocalSym(*mangledName);
523+
if (!imp && impName.consume_front("aux_")) {
524+
// If it's a __imp_aux_ symbol, try skipping the aux_ prefix.
525+
imp = findLocalSym(impName);
526+
if (!imp && (mangledName = getArm64ECMangledFunctionName(impName)))
527+
imp = findLocalSym(*mangledName);
511528
}
512529
}
513530
if (imp && imp->isLazy()) {
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
REQUIRES: aarch64
2+
RUN: split-file %s %t.dir && cd %t.dir
3+
4+
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows funcs.s -o funcs.obj
5+
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows func-mangled.s -o func-mangled.obj
6+
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows impsym.s -o impsym.obj
7+
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows impauxsym.s -o impauxsym.obj
8+
9+
Ensure that when both mangled and demangled symbols are present, the __imp_ symbol
10+
resolves to the demangled symbol.
11+
12+
RUN: lld-link -machine:arm64ec -dll -noentry funcs.obj impsym.obj -out:impsym.dll
13+
14+
RUN: llvm-readobj --coff-basereloc impsym.dll | FileCheck --check-prefix=RELOCS %s
15+
RELOCS: Entry {
16+
RELOCS-NEXT: Type: DIR64
17+
RELOCS-NEXT: Address: 0x2000
18+
RELOCS-NEXT: }
19+
20+
RUN: llvm-readobj --hex-dump=.test impsym.dll | FileCheck --check-prefix=TEST %s
21+
TEST: 0x180003000 00200000
22+
23+
RUN: llvm-readobj --hex-dump=.rdata impsym.dll | FileCheck --check-prefix=RDATA-DEMANGLED %s
24+
RDATA-MANGLED: 0x180002000 00100080 01000000
25+
RDATA-DEMANGLED: 0x180002000 04100080 01000000
26+
27+
28+
Ensure that when both mangled and demangled symbols are present, the __imp_aux_ symbol
29+
resolves to the demangled symbol.
30+
31+
RUN: lld-link -machine:arm64ec -dll -noentry funcs.obj impauxsym.obj -out:impauxsym.dll
32+
RUN: llvm-readobj --hex-dump=.test impauxsym.dll | FileCheck --check-prefix=TEST %s
33+
RUN: llvm-readobj --hex-dump=.rdata impauxsym.dll | FileCheck --check-prefix=RDATA-DEMANGLED %s
34+
35+
Ensure that if only the mangled symbol is present, the __imp_ symbol resolves to it.
36+
37+
RUN: lld-link -machine:arm64ec -dll -noentry func-mangled.obj impsym.obj -out:impsym-mangled.dll
38+
RUN: llvm-readobj --coff-basereloc impsym-mangled.dll | FileCheck --check-prefix=RELOCS %s
39+
RUN: llvm-readobj --hex-dump=.test impsym-mangled.dll | FileCheck --check-prefix=TEST %s
40+
RUN: llvm-readobj --hex-dump=.rdata impsym-mangled.dll | FileCheck --check-prefix=RDATA-MANGLED %s
41+
42+
Ensure that if only the mangled symbol is present, the __imp_aux_ symbol resolves to it.
43+
44+
RUN: lld-link -machine:arm64ec -dll -noentry func-mangled.obj impauxsym.obj -out:impauxsym-mangled.dll
45+
RUN: llvm-readobj --hex-dump=.test impauxsym-mangled.dll | FileCheck --check-prefix=TEST %s
46+
RUN: llvm-readobj --hex-dump=.rdata impauxsym-mangled.dll | FileCheck --check-prefix=RDATA-MANGLED %s
47+
48+
#--- funcs.s
49+
.globl "#myfunc"
50+
"#myfunc":
51+
ret
52+
.text
53+
.globl myfunc
54+
myfunc:
55+
ret
56+
57+
#--- func-mangled.s
58+
.globl "#myfunc"
59+
"#myfunc":
60+
ret
61+
62+
#--- impsym.s
63+
.section .test, "r"
64+
.rva __imp_myfunc
65+
66+
#--- impauxsym.s
67+
.section .test, "r"
68+
.rva __imp_aux_myfunc

0 commit comments

Comments
 (0)