[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 ac31d64a64e8a648f6834f4cf9de10c56c8d1083)
This commit is contained in:
parent
f1bca175af
commit
bbc8346e6b
@ -1364,7 +1364,19 @@ void SymbolTable::resolveAlternateNames() {
|
||||
!isArm64ECMangledFunctionName(u->getName()))
|
||||
continue;
|
||||
}
|
||||
u->setWeakAlias(addUndefined(to));
|
||||
|
||||
// Check if the destination symbol is defined. If not, skip it.
|
||||
// It may still be resolved later if more input files are added.
|
||||
// Also skip anti-dependency targets, as they can't be chained anyway.
|
||||
Symbol *toSym = find(to);
|
||||
if (!toSym)
|
||||
continue;
|
||||
auto toUndef = dyn_cast<Undefined>(toSym);
|
||||
if (toUndef && (!toUndef->weakAlias || toUndef->isAntiDep))
|
||||
continue;
|
||||
if (toSym->isLazy())
|
||||
forceLazy(toSym);
|
||||
u->setWeakAlias(toSym);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
15
lld/test/COFF/alternatename-alias.s
Normal file
15
lld/test/COFF/alternatename-alias.s
Normal file
@ -0,0 +1,15 @@
|
||||
// REQUIRES: x86
|
||||
|
||||
// Check that a weak alias can be used as an alternate name target.
|
||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-windows %s -o %t.obj
|
||||
// RUN: lld-link -dll -noentry %t.obj -alternatename:sym=altsym
|
||||
|
||||
.data
|
||||
.rva sym
|
||||
|
||||
.weak altsym
|
||||
.set altsym,a
|
||||
|
||||
.globl a
|
||||
a:
|
||||
.word 1
|
||||
16
lld/test/COFF/alternatename-antidep.s
Normal file
16
lld/test/COFF/alternatename-antidep.s
Normal file
@ -0,0 +1,16 @@
|
||||
// REQUIRES: x86
|
||||
|
||||
// Check that an anti-dependency alias can't be used as an alternate name target.
|
||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-windows %s -o %t.obj
|
||||
// RUN: not lld-link -dll -noentry %t.obj -alternatename:sym=altsym 2>&1 | FileCheck %s
|
||||
// CHECK: error: undefined symbol: sym
|
||||
|
||||
.data
|
||||
.rva sym
|
||||
|
||||
.weak_anti_dep altsym
|
||||
.set altsym,a
|
||||
|
||||
.globl a
|
||||
a:
|
||||
.word 1
|
||||
43
lld/test/COFF/alternatename-lib.s
Normal file
43
lld/test/COFF/alternatename-lib.s
Normal file
@ -0,0 +1,43 @@
|
||||
// REQUIRES: x86
|
||||
// RUN: split-file %s %t.dir && cd %t.dir
|
||||
|
||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-windows refab.s -o refab.obj
|
||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-windows aa.s -o aa.obj
|
||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-windows b.s -o b.obj
|
||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-windows antidep.s -o antidep.obj
|
||||
// RUN: llvm-lib -out:aa.lib aa.obj
|
||||
// RUN: llvm-lib -out:b.lib b.obj
|
||||
|
||||
// Check that -alternatename with an undefined target does not prevent the symbol from being resolved to a library,
|
||||
// once another alternate name is resolved and pulls in the source symbol.
|
||||
// RUN: lld-link -out:out.dll -dll -noentry -machine:amd64 refab.obj aa.lib -alternatename:a=aa -alternatename:b=undef
|
||||
|
||||
// Check that -alternatename with an anti-dependency target does not prevent the symbol from being resolved to a library,
|
||||
// after another alternate name is resolved and pulls in the source symbol.
|
||||
// RUN: lld-link -out:out2.dll -dll -noentry -machine:amd64 antidep.obj refab.obj aa.lib -alternatename:a=aa -alternatename:b=u
|
||||
|
||||
#--- refab.s
|
||||
.data
|
||||
.rva a
|
||||
.rva b
|
||||
|
||||
#--- aa.s
|
||||
.globl aa
|
||||
aa:
|
||||
.word 1
|
||||
|
||||
.section .drectve, "yn"
|
||||
.ascii "/defaultlib:b.lib"
|
||||
|
||||
#--- b.s
|
||||
.globl b
|
||||
b:
|
||||
.word 2
|
||||
|
||||
#--- antidep.s
|
||||
.weak_anti_dep u
|
||||
.set u,d
|
||||
|
||||
.globl d
|
||||
d:
|
||||
.word 3
|
||||
@ -2,6 +2,7 @@ REQUIRES: aarch64
|
||||
RUN: split-file %s %t.dir && cd %t.dir
|
||||
|
||||
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows ext.s -o ext.obj
|
||||
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows ext-mangled.s -o ext-mangled.obj
|
||||
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows impl.s -o impl.obj
|
||||
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows impl-cpp.s -o impl-cpp.obj
|
||||
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
|
||||
RUN: llvm-objdump -d out4.dll | FileCheck --check-prefix=DISASM %s
|
||||
RUN: llvm-readobj --hex-dump=.test out4.dll | FileCheck --check-prefix=TESTSEC %s
|
||||
|
||||
# Check that when both mangled and demangled alternate names are used,
|
||||
# only the one whose target is defined is used (the mangled one in this case).
|
||||
|
||||
RUN: lld-link -machine:arm64ec -dll -noentry -out:out5.dll ext-mangled.obj loadconfig.obj "-alternatename:#func=#altsym" -alternatename:func=altsym
|
||||
RUN: llvm-objdump -d out5.dll | FileCheck --check-prefix=DISASM %s
|
||||
RUN: llvm-readobj --hex-dump=.test out5.dll | FileCheck --check-prefix=TESTSEC %s
|
||||
|
||||
# Check that when both mangled and demangled alternate names are used,
|
||||
# only the one whose target is defined is used (the demangled one in this case).
|
||||
|
||||
RUN: lld-link -machine:arm64ec -dll -noentry -out:out6.dll ext.obj loadconfig.obj "-alternatename:#func=#altsym" -alternatename:func=altsym
|
||||
RUN: llvm-objdump -d out6.dll | FileCheck --check-prefix=DISASM2 %s
|
||||
RUN: llvm-readobj --hex-dump=.test out6.dll | FileCheck --check-prefix=TESTSEC2 %s
|
||||
|
||||
#--- ext.s
|
||||
.weak_anti_dep func
|
||||
.set func, "#func"
|
||||
@ -70,6 +85,30 @@ altsym:
|
||||
mov w0, #1
|
||||
ret
|
||||
|
||||
#--- ext-mangled.s
|
||||
.weak_anti_dep func
|
||||
.set func, "#func"
|
||||
.weak_anti_dep "#func"
|
||||
.set "#func", thunksym
|
||||
|
||||
.section .test, "r"
|
||||
.rva func
|
||||
.rva "#func"
|
||||
|
||||
.section .thnk,"xr",discard,thunksym
|
||||
thunksym:
|
||||
mov w0, #2
|
||||
ret
|
||||
|
||||
.section .text,"xr",discard,"#altsym"
|
||||
.globl "#altsym"
|
||||
"#altsym":
|
||||
mov w0, #1
|
||||
ret
|
||||
|
||||
.weak_anti_dep altsym
|
||||
.set altsym,"#altsym"
|
||||
|
||||
#--- impl.s
|
||||
.weak_anti_dep func
|
||||
.set func, "#func"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user