Skip to content

Commit c706382

Browse files
cjacekllvmbot
authored andcommitted
[LLD][COFF] Avoid resolving symbols with -alternatename if the target is undefined (#149496)
This change fixes an issue with the use of `-alternatename` in the MSVC CRT on ARM64EC, where both mangled and demangled symbol names are specified. Without this patch, the demangled name could be resolved to an anti-dependency alias of the target. Since chaining anti-dependency aliases is not allowed, this results in an undefined symbol. The root cause isn't specific to ARM64EC, it can affect other targets as well, even when anti-dependency aliases aren't involved. The accompanying test case demonstrates a scenario where the symbol could be resolved from an archive. However, because the archive member is pulled in after the first pass of alternate name resolution, and archive members don't override weak aliases, eager resolution would incorrectly skip it. (cherry picked from commit ac31d64)
1 parent f83c249 commit c706382

File tree

5 files changed

+126
-1
lines changed

5 files changed

+126
-1
lines changed

lld/COFF/SymbolTable.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1364,7 +1364,19 @@ void SymbolTable::resolveAlternateNames() {
13641364
!isArm64ECMangledFunctionName(u->getName()))
13651365
continue;
13661366
}
1367-
u->setWeakAlias(addUndefined(to));
1367+
1368+
// Check if the destination symbol is defined. If not, skip it.
1369+
// It may still be resolved later if more input files are added.
1370+
// Also skip anti-dependency targets, as they can't be chained anyway.
1371+
Symbol *toSym = find(to);
1372+
if (!toSym)
1373+
continue;
1374+
auto toUndef = dyn_cast<Undefined>(toSym);
1375+
if (toUndef && (!toUndef->weakAlias || toUndef->isAntiDep))
1376+
continue;
1377+
if (toSym->isLazy())
1378+
forceLazy(toSym);
1379+
u->setWeakAlias(toSym);
13681380
}
13691381
}
13701382
}

lld/test/COFF/alternatename-alias.s

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// REQUIRES: x86
2+
3+
// Check that a weak alias can be used as an alternate name target.
4+
// RUN: llvm-mc -filetype=obj -triple=x86_64-windows %s -o %t.obj
5+
// RUN: lld-link -dll -noentry %t.obj -alternatename:sym=altsym
6+
7+
.data
8+
.rva sym
9+
10+
.weak altsym
11+
.set altsym,a
12+
13+
.globl a
14+
a:
15+
.word 1

lld/test/COFF/alternatename-antidep.s

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// REQUIRES: x86
2+
3+
// Check that an anti-dependency alias can't be used as an alternate name target.
4+
// RUN: llvm-mc -filetype=obj -triple=x86_64-windows %s -o %t.obj
5+
// RUN: not lld-link -dll -noentry %t.obj -alternatename:sym=altsym 2>&1 | FileCheck %s
6+
// CHECK: error: undefined symbol: sym
7+
8+
.data
9+
.rva sym
10+
11+
.weak_anti_dep altsym
12+
.set altsym,a
13+
14+
.globl a
15+
a:
16+
.word 1

lld/test/COFF/alternatename-lib.s

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// REQUIRES: x86
2+
// RUN: split-file %s %t.dir && cd %t.dir
3+
4+
// RUN: llvm-mc -filetype=obj -triple=x86_64-windows refab.s -o refab.obj
5+
// RUN: llvm-mc -filetype=obj -triple=x86_64-windows aa.s -o aa.obj
6+
// RUN: llvm-mc -filetype=obj -triple=x86_64-windows b.s -o b.obj
7+
// RUN: llvm-mc -filetype=obj -triple=x86_64-windows antidep.s -o antidep.obj
8+
// RUN: llvm-lib -out:aa.lib aa.obj
9+
// RUN: llvm-lib -out:b.lib b.obj
10+
11+
// Check that -alternatename with an undefined target does not prevent the symbol from being resolved to a library,
12+
// once another alternate name is resolved and pulls in the source symbol.
13+
// RUN: lld-link -out:out.dll -dll -noentry -machine:amd64 refab.obj aa.lib -alternatename:a=aa -alternatename:b=undef
14+
15+
// Check that -alternatename with an anti-dependency target does not prevent the symbol from being resolved to a library,
16+
// after another alternate name is resolved and pulls in the source symbol.
17+
// RUN: lld-link -out:out2.dll -dll -noentry -machine:amd64 antidep.obj refab.obj aa.lib -alternatename:a=aa -alternatename:b=u
18+
19+
#--- refab.s
20+
.data
21+
.rva a
22+
.rva b
23+
24+
#--- aa.s
25+
.globl aa
26+
aa:
27+
.word 1
28+
29+
.section .drectve, "yn"
30+
.ascii "/defaultlib:b.lib"
31+
32+
#--- b.s
33+
.globl b
34+
b:
35+
.word 2
36+
37+
#--- antidep.s
38+
.weak_anti_dep u
39+
.set u,d
40+
41+
.globl d
42+
d:
43+
.word 3

lld/test/COFF/arm64ec-altnames.s

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ REQUIRES: aarch64
22
RUN: split-file %s %t.dir && cd %t.dir
33

44
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows ext.s -o ext.obj
5+
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows ext-mangled.s -o ext-mangled.obj
56
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows impl.s -o impl.obj
67
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows impl-cpp.s -o impl-cpp.obj
78
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows %S/Inputs/loadconfig-arm64ec.s -o loadconfig.obj
@@ -49,6 +50,20 @@ RUN: lld-link -machine:arm64ec -dll -noentry -out:out4.dll impl-cpp.obj loadconf
4950
RUN: llvm-objdump -d out4.dll | FileCheck --check-prefix=DISASM %s
5051
RUN: llvm-readobj --hex-dump=.test out4.dll | FileCheck --check-prefix=TESTSEC %s
5152

53+
# Check that when both mangled and demangled alternate names are used,
54+
# only the one whose target is defined is used (the mangled one in this case).
55+
56+
RUN: lld-link -machine:arm64ec -dll -noentry -out:out5.dll ext-mangled.obj loadconfig.obj "-alternatename:#func=#altsym" -alternatename:func=altsym
57+
RUN: llvm-objdump -d out5.dll | FileCheck --check-prefix=DISASM %s
58+
RUN: llvm-readobj --hex-dump=.test out5.dll | FileCheck --check-prefix=TESTSEC %s
59+
60+
# Check that when both mangled and demangled alternate names are used,
61+
# only the one whose target is defined is used (the demangled one in this case).
62+
63+
RUN: lld-link -machine:arm64ec -dll -noentry -out:out6.dll ext.obj loadconfig.obj "-alternatename:#func=#altsym" -alternatename:func=altsym
64+
RUN: llvm-objdump -d out6.dll | FileCheck --check-prefix=DISASM2 %s
65+
RUN: llvm-readobj --hex-dump=.test out6.dll | FileCheck --check-prefix=TESTSEC2 %s
66+
5267
#--- ext.s
5368
.weak_anti_dep func
5469
.set func, "#func"
@@ -70,6 +85,30 @@ altsym:
7085
mov w0, #1
7186
ret
7287

88+
#--- ext-mangled.s
89+
.weak_anti_dep func
90+
.set func, "#func"
91+
.weak_anti_dep "#func"
92+
.set "#func", thunksym
93+
94+
.section .test, "r"
95+
.rva func
96+
.rva "#func"
97+
98+
.section .thnk,"xr",discard,thunksym
99+
thunksym:
100+
mov w0, #2
101+
ret
102+
103+
.section .text,"xr",discard,"#altsym"
104+
.globl "#altsym"
105+
"#altsym":
106+
mov w0, #1
107+
ret
108+
109+
.weak_anti_dep altsym
110+
.set altsym,"#altsym"
111+
73112
#--- impl.s
74113
.weak_anti_dep func
75114
.set func, "#func"

0 commit comments

Comments
 (0)