Skip to content

Commit dcc45fa

Browse files
committed
[ELF] PROVIDE: fix spurious "symbol not found"
When archive member extraction involving ENTRY happens after `addScriptReferencedSymbolsToSymTable`, `addScriptReferencedSymbolsToSymTable` may fail to define some PROVIDE symbols used by ENTRY. This is an edge case that regressed after llvm#84512. (The interaction with PROVIDE and ENTRY-in-archive was not considered before). While here, also ensure that --undefined-glob extracted object files are parsed before `addScriptReferencedSymbolsToSymTable`. Fixes: ebb326a Pull Request: llvm#87530
1 parent 9e3b64b commit dcc45fa

File tree

2 files changed

+35
-7
lines changed

2 files changed

+35
-7
lines changed

lld/ELF/Driver.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2767,13 +2767,6 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
27672767
// Create dynamic sections for dynamic linking and static PIE.
27682768
config->hasDynSymTab = !ctx.sharedFiles.empty() || config->isPic;
27692769

2770-
script->addScriptReferencedSymbolsToSymTable();
2771-
2772-
// Prevent LTO from removing any definition referenced by -u.
2773-
for (StringRef name : config->undefined)
2774-
if (Defined *sym = dyn_cast_or_null<Defined>(symtab.find(name)))
2775-
sym->isUsedInRegularObj = true;
2776-
27772770
// If an entry symbol is in a static archive, pull out that file now.
27782771
if (Symbol *sym = symtab.find(config->entry))
27792772
handleUndefined(sym, "--entry");
@@ -2782,6 +2775,16 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
27822775
for (StringRef pat : args::getStrings(args, OPT_undefined_glob))
27832776
handleUndefinedGlob(pat);
27842777

2778+
// After potential archive member extraction involving ENTRY and
2779+
// -u/--undefined-glob, check whether PROVIDE symbols should be defined (the
2780+
// RHS may refer to definitions in just extracted object files).
2781+
script->addScriptReferencedSymbolsToSymTable();
2782+
2783+
// Prevent LTO from removing any definition referenced by -u.
2784+
for (StringRef name : config->undefined)
2785+
if (Defined *sym = dyn_cast_or_null<Defined>(symtab.find(name)))
2786+
sym->isUsedInRegularObj = true;
2787+
27852788
// Mark -init and -fini symbols so that the LTO doesn't eliminate them.
27862789
if (Symbol *sym = dyn_cast_or_null<Defined>(symtab.find(config->init)))
27872790
sym->isUsedInRegularObj = true;

lld/test/ELF/linkerscript/symbolreferenced.s

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,21 @@
5050
# RUN: not ld.lld -T chain2.t a.o 2>&1 | FileCheck %s --check-prefix=ERR --implicit-check-not=error:
5151
# ERR-COUNT-3: error: chain2.t:1: symbol not found: undef
5252

53+
## _start in a lazy object file references PROVIDE symbols. We extract _start
54+
## earlier to avoid spurious "symbol not found" errors.
55+
# RUN: llvm-mc -filetype=obj -triple=x86_64 undef.s -o undef.o
56+
# RUN: llvm-mc -filetype=obj -triple=x86_64 start.s -o start.o
57+
# RUN: ld.lld -T chain2.t undef.o --start-lib start.o --end-lib -o lazy
58+
# RUN: llvm-nm lazy | FileCheck %s --check-prefix=LAZY
59+
# RUN: ld.lld -e 0 -T chain2.t --undefined-glob '_start*' undef.o --start-lib start.o --end-lib -o lazy
60+
# RUN: llvm-nm lazy | FileCheck %s --check-prefix=LAZY
61+
62+
# LAZY: T _start
63+
# LAZY-NEXT: t f1
64+
# LAZY-NEXT: T f2
65+
# LAZY-NEXT: T newsym
66+
# LAZY-NEXT: T unde
67+
5368
#--- a.s
5469
.global _start
5570
_start:
@@ -89,3 +104,13 @@ PROVIDE(newsym = f1);
89104
PROVIDE(f2 = undef);
90105
PROVIDE_HIDDEN(f1 = f2);
91106
PROVIDE(newsym = f1);
107+
108+
#--- undef.s
109+
.globl undef
110+
undef: ret
111+
112+
#--- start.s
113+
.globl _start
114+
_start: ret
115+
.data
116+
.quad newsym

0 commit comments

Comments
 (0)