Skip to content

Commit 6bb6922

Browse files
authored
[LLD][COFF] Allow overriding EC alias symbols with alternate names (#113456)
1 parent b91ce7b commit 6bb6922

File tree

3 files changed

+128
-3
lines changed

3 files changed

+128
-3
lines changed

lld/COFF/Driver.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2518,9 +2518,19 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
25182518
Symbol *sym = ctx.symtab.find(from);
25192519
if (!sym)
25202520
continue;
2521-
if (auto *u = dyn_cast<Undefined>(sym))
2522-
if (!u->weakAlias)
2523-
u->setWeakAlias(ctx.symtab.addUndefined(to));
2521+
if (auto *u = dyn_cast<Undefined>(sym)) {
2522+
if (u->weakAlias) {
2523+
// On ARM64EC, anti-dependency aliases are treated as undefined
2524+
// symbols unless a demangled symbol aliases a defined one, which is
2525+
// part of the implementation.
2526+
if (!isArm64EC(ctx.config.machine) || !u->isAntiDep)
2527+
continue;
2528+
if (!isa<Undefined>(u->weakAlias) &&
2529+
!isArm64ECMangledFunctionName(u->getName()))
2530+
continue;
2531+
}
2532+
u->setWeakAlias(ctx.symtab.addUndefined(to));
2533+
}
25242534
}
25252535

25262536
// If any inputs are bitcode files, the LTO code generator may create

lld/test/COFF/arm64ec-altnames.s

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
REQUIRES: aarch64
2+
RUN: split-file %s %t.dir && cd %t.dir
3+
4+
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows ext.s -o ext.obj
5+
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows impl.s -o impl.obj
6+
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows impl-cpp.s -o impl-cpp.obj
7+
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows %S/Inputs/loadconfig-arm64ec.s -o loadconfig.obj
8+
9+
# Ensure -alternatename can change a mangled function symbol aliasing a defined symbol (typically a guest exit thunk).
10+
11+
RUN: lld-link -machine:arm64ec -dll -noentry -out:out1.dll ext.obj loadconfig.obj "-alternatename:#func=altsym"
12+
13+
RUN: llvm-objdump -d out1.dll | FileCheck --check-prefix=DISASM %s
14+
DISASM: 0000000180001000 <.text>:
15+
DISASM-NEXT: 180001000: 52800020 mov w0, #0x1 // =1
16+
DISASM-NEXT: 180001004: d65f03c0 ret
17+
DISASM-NOT: .thnk
18+
19+
RUN: llvm-readobj --hex-dump=.test out1.dll | FileCheck --check-prefix=TESTSEC %s
20+
TESTSEC: 0x180004000 00100000 00100000
21+
22+
# Ensure -alternatename can change a demangled function symbol aliasing an anti-dependency symbol.
23+
24+
RUN: lld-link -machine:arm64ec -dll -noentry -out:out2.dll ext.obj loadconfig.obj -alternatename:func=altsym
25+
26+
RUN: llvm-objdump -d out2.dll | FileCheck --check-prefix=DISASM2 %s
27+
DISASM2: Disassembly of section .text:
28+
DISASM2-EMPTY:
29+
DISASM2-NEXT: 0000000180001000 <.text>:
30+
DISASM2-NEXT: 180001000: 52800020 mov w0, #0x1 // =1
31+
DISASM2-NEXT: 180001004: d65f03c0 ret
32+
DISASM2-EMPTY:
33+
DISASM2-NEXT: Disassembly of section .thnk:
34+
DISASM2-EMPTY:
35+
DISASM2-NEXT: 0000000180005000 <.thnk>:
36+
DISASM2-NEXT: 180005000: 52800040 mov w0, #0x2 // =2
37+
DISASM2-NEXT: 180005004: d65f03c0 ret
38+
39+
RUN: llvm-readobj --hex-dump=.test out2.dll | FileCheck --check-prefix=TESTSEC2 %s
40+
TESTSEC2: 0x180004000 00100000 00500000
41+
42+
# Ensure -alternatename cannot modify a demangled function symbol aliasing a defined symbol.
43+
44+
RUN: lld-link -machine:arm64ec -dll -noentry -out:out3.dll impl.obj loadconfig.obj -alternatename:func=altsym
45+
RUN: llvm-objdump -d out3.dll | FileCheck --check-prefix=DISASM %s
46+
RUN: llvm-readobj --hex-dump=.test out3.dll | FileCheck --check-prefix=TESTSEC %s
47+
48+
RUN: lld-link -machine:arm64ec -dll -noentry -out:out4.dll impl-cpp.obj loadconfig.obj -alternatename:func=altsym
49+
RUN: llvm-objdump -d out4.dll | FileCheck --check-prefix=DISASM %s
50+
RUN: llvm-readobj --hex-dump=.test out4.dll | FileCheck --check-prefix=TESTSEC %s
51+
52+
#--- ext.s
53+
.weak_anti_dep func
54+
.set func, "#func"
55+
.weak_anti_dep "#func"
56+
.set "#func", thunksym
57+
58+
.section .test, "r"
59+
.rva func
60+
.rva "#func"
61+
62+
.section .thnk,"xr",discard,thunksym
63+
thunksym:
64+
mov w0, #2
65+
ret
66+
67+
.section .text,"xr",discard,altsym
68+
.globl altsym
69+
altsym:
70+
mov w0, #1
71+
ret
72+
73+
#--- impl.s
74+
.weak_anti_dep func
75+
.set func, "#func"
76+
77+
.section .test, "r"
78+
.rva func
79+
.rva "#func"
80+
81+
.section .text,"xr",discard,"#func"
82+
"#func":
83+
mov w0, #1
84+
ret
85+
86+
.section .text,"xr",discard,altsym
87+
.globl altsym
88+
altsym:
89+
mov w0, #2
90+
ret
91+
92+
#--- impl-cpp.s
93+
.weak_anti_dep func
94+
.set func, "?func@@$$hYAXXZ"
95+
96+
.section .test, "r"
97+
.rva func
98+
.rva "?func@@$$hYAXXZ"
99+
100+
.section .text,"xr",discard,"?func@@$$hYAXXZ"
101+
"?func@@$$hYAXXZ":
102+
mov w0, #1
103+
ret
104+
105+
.section .text,"xr",discard,altsym
106+
.globl altsym
107+
altsym:
108+
mov w0, #2
109+
ret

llvm/include/llvm/IR/Mangler.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ std::optional<std::string> getArm64ECMangledFunctionName(StringRef Name);
6161
/// mangled.
6262
std::optional<std::string> getArm64ECDemangledFunctionName(StringRef Name);
6363

64+
/// Check if an ARM64EC function name is mangled.
65+
bool inline isArm64ECMangledFunctionName(StringRef Name) {
66+
return Name[0] == '#' ||
67+
(Name[0] == '?' && Name.find("$$h") != StringRef::npos);
68+
}
69+
6470
} // End llvm namespace
6571

6672
#endif

0 commit comments

Comments
 (0)