Skip to content

[LLD][COFF] Avoid resolving symbols with -alternatename if the target is undefined #149496

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion lld/COFF/SymbolTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
Expand Down
15 changes: 15 additions & 0 deletions lld/test/COFF/alternatename-alias.s
Original file line number Diff line number Diff line change
@@ -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 changes: 16 additions & 0 deletions lld/test/COFF/alternatename-antidep.s
Original file line number Diff line number Diff line change
@@ -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 changes: 43 additions & 0 deletions lld/test/COFF/alternatename-lib.s
Original file line number Diff line number Diff line change
@@ -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
39 changes: 39 additions & 0 deletions lld/test/COFF/arm64ec-altnames.s
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"
Expand All @@ -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"
Expand Down