summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFangrui Song <i@maskray.me>2024-10-10 20:47:12 -0700
committerFangrui Song <i@maskray.me>2024-10-10 20:47:12 -0700
commita89670cc3fdb8ec3e181fb8c374161c4ade25995 (patch)
tree090d1c43f7e364fb72b218fe415dfff906e67db3
parent51e9430a0c767243411d4b81c284700f89719277 (diff)
Created using spr 1.3.5-bogner
-rw-r--r--lld/ELF/LinkerScript.cpp7
-rw-r--r--lld/test/ELF/linkerscript/provide-defined.s33
2 files changed, 39 insertions, 1 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index f3f95ec589bd..2247d592c8bc 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -1811,6 +1811,11 @@ void LinkerScript::addScriptReferencedSymbolsToSymTable() {
}
bool LinkerScript::shouldAddProvideSym(StringRef symName) {
+ // A Defined may be demoted to Undefined but the return value must stay the
+ // same. Use isUsedInRegularObj to ensure this. The exportDynamic condition,
+ // while not so accurate, allows PROVIDE to define a symbol referenced by a
+ // DSO.
Symbol *sym = elf::ctx.symtab->find(symName);
- return sym && !sym->isDefined() && !sym->isCommon();
+ return sym && !sym->isDefined() && !sym->isCommon() &&
+ (sym->isUsedInRegularObj || sym->exportDynamic);
}
diff --git a/lld/test/ELF/linkerscript/provide-defined.s b/lld/test/ELF/linkerscript/provide-defined.s
new file mode 100644
index 000000000000..6ebfd706c16e
--- /dev/null
+++ b/lld/test/ELF/linkerscript/provide-defined.s
@@ -0,0 +1,33 @@
+# REQUIRES: x86
+## Test the GC behavior when the PROVIDE symbol is defined by a relocatable file.
+
+# RUN: rm -rf %t && split-file %s %t && cd %t
+# RUN: llvm-mc -filetype=obj -triple=x86_64 a.s -o a.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64 b.s -o b.o
+# RUN: ld.lld -T a.t --gc-sections a.o b.o -o a
+# RUN: llvm-readelf -s a | FileCheck %s
+
+# CHECK: 1: {{.*}} 0 NOTYPE GLOBAL DEFAULT 1 _start
+# CHECK-NEXT:2: {{.*}} 0 NOTYPE GLOBAL DEFAULT 2 f3
+# CHECK-NOT: {{.}}
+
+#--- a.s
+.global _start, f1, f2, f3, bar
+_start:
+ call f3
+
+.section .text.f1,"ax"; f1:
+.section .text.f2,"ax"; f2:
+.section .text.f3,"ax"; f3:
+.section .text.bar,"ax"; bar:
+
+#--- b.s
+ call f2
+
+#--- a.t
+SECTIONS {
+ . = . + SIZEOF_HEADERS;
+ PROVIDE(f1 = bar+1);
+ PROVIDE(f2 = bar+2);
+ PROVIDE(f3 = bar+3);
+}