diff options
| author | Fangrui Song <i@maskray.me> | 2024-10-10 20:48:53 -0700 |
|---|---|---|
| committer | Fangrui Song <i@maskray.me> | 2024-10-10 20:48:53 -0700 |
| commit | def2bf44c89df039b5a49b1ab8f4d783e84914c2 (patch) | |
| tree | 090d1c43f7e364fb72b218fe415dfff906e67db3 | |
| parent | 51e9430a0c767243411d4b81c284700f89719277 (diff) | |
[𝘀𝗽𝗿] initial versionusers/MaskRay/spr/elf-make-shouldaddprovidesym-values-consistent-when-demoted-to-undefined-1
Created using spr 1.3.5-bogner
| -rw-r--r-- | lld/ELF/LinkerScript.cpp | 7 | ||||
| -rw-r--r-- | lld/test/ELF/linkerscript/provide-defined.s | 33 |
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); +} |
