[lld] r323729 - [ELF] - Define linkerscript symbols early.
George Rimar via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 30 01:04:27 PST 2018
Author: grimar
Date: Tue Jan 30 01:04:27 2018
New Revision: 323729
URL: http://llvm.org/viewvc/llvm-project?rev=323729&view=rev
Log:
[ELF] - Define linkerscript symbols early.
Currently symbols assigned or created by linkerscript are not processed early
enough. As a result it is not possible to version them or assign any other flags/properties.
Patch creates Defined symbols for -defsym and linkerscript symbols early,
so that issue from above can be addressed.
It is based on Rafael Espindola's version of D38239 patch.
Fixes PR34121.
Differential revision: https://reviews.llvm.org/D41987
Added:
lld/trunk/test/ELF/linkerscript/version-script.s
Modified:
lld/trunk/ELF/Driver.cpp
lld/trunk/ELF/LTO.cpp
lld/trunk/ELF/LinkerScript.cpp
lld/trunk/ELF/LinkerScript.h
lld/trunk/test/ELF/linkerscript/symbols-synthetic.s
lld/trunk/test/ELF/lto/defsym.ll
lld/trunk/test/ELF/lto/linker-script-symbols-assign.ll
lld/trunk/test/ELF/lto/linker-script-symbols-ipo.ll
Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=323729&r1=323728&r2=323729&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Tue Jan 30 01:04:27 2018
@@ -1063,6 +1063,10 @@ template <class ELFT> void LinkerDriver:
if (!Config->Relocatable)
addReservedSymbols();
+ // We want to declare linker script's symbols early,
+ // so that we can version them.
+ Script->declareSymbols();
+
// Apply version scripts.
Symtab->scanVersionScript();
Modified: lld/trunk/ELF/LTO.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LTO.cpp?rev=323729&r1=323728&r2=323729&view=diff
==============================================================================
--- lld/trunk/ELF/LTO.cpp (original)
+++ lld/trunk/ELF/LTO.cpp Tue Jan 30 01:04:27 2018
@@ -129,11 +129,6 @@ void BitcodeCompiler::add(BitcodeFile &F
std::vector<Symbol *> Syms = F.getSymbols();
std::vector<lto::SymbolResolution> Resols(Syms.size());
- DenseSet<StringRef> ScriptSymbols;
- for (BaseCommand *Base : Script->SectionCommands)
- if (auto *Cmd = dyn_cast<SymbolAssignment>(Base))
- ScriptSymbols.insert(Cmd->Name);
-
bool IsExecutable = !Config->Shared && !Config->Relocatable;
// Provide a resolution to the LTO API for each symbol.
@@ -164,12 +159,10 @@ void BitcodeCompiler::add(BitcodeFile &F
if (R.Prevailing)
undefine(Sym);
- // We tell LTO to not apply interprocedural optimization for following
- // symbols because otherwise LTO would inline them while their values are
- // still not final:
- // 1) Aliased (with --defsym) or wrapped (with --wrap) symbols.
- // 2) Symbols redefined in linker script.
- R.LinkerRedefined = !Sym->CanInline || ScriptSymbols.count(Sym->getName());
+ // We tell LTO to not apply interprocedural optimization for wrapped
+ // (with --wrap) symbols because otherwise LTO would inline them while
+ // their values are still not final.
+ R.LinkerRedefined = !Sym->CanInline;
}
checkError(LTOObj->add(std::move(F.Obj), Resols));
}
Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=323729&r1=323728&r2=323729&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Tue Jan 30 01:04:27 2018
@@ -114,16 +114,28 @@ void LinkerScript::setDot(Expr E, const
Ctx->OutSec->Size = Dot - Ctx->OutSec->Addr;
}
-// This function is called from processSectionCommands,
-// while we are fixing the output section layout.
-void LinkerScript::addSymbol(SymbolAssignment *Cmd) {
+// Used for handling linker symbol assignments, for both finalizing
+// their values and doing early declarations. Returns true if symbol
+// should be defined from linker script.
+static bool shouldDefineSym(SymbolAssignment *Cmd) {
if (Cmd->Name == ".")
- return;
+ return false;
+
+ if (!Cmd->Provide)
+ return true;
- // If a symbol was in PROVIDE(), we need to define it only when
- // it is a referenced undefined symbol.
+ // If a symbol was in PROVIDE(), we need to define it only
+ // when it is a referenced undefined symbol.
Symbol *B = Symtab->find(Cmd->Name);
- if (Cmd->Provide && (!B || B->isDefined()))
+ if (!B || B->isDefined())
+ return false;
+ return true;
+}
+
+// This function is called from processSectionCommands,
+// while we are fixing the output section layout.
+void LinkerScript::addSymbol(SymbolAssignment *Cmd) {
+ if (!shouldDefineSym(Cmd))
return;
// Define a symbol.
@@ -153,6 +165,30 @@ void LinkerScript::addSymbol(SymbolAssig
Cmd->Sym = cast<Defined>(Sym);
}
+// Symbols defined in script should not be inlined by LTO. At the same time
+// we don't know their final values until late stages of link. Here we scan
+// over symbol assignment commands and create placeholder symbols if needed.
+void LinkerScript::declareSymbols() {
+ assert(!Ctx);
+ for (BaseCommand *Base : SectionCommands) {
+ auto *Cmd = dyn_cast<SymbolAssignment>(Base);
+ if (!Cmd || !shouldDefineSym(Cmd))
+ continue;
+
+ // We can't calculate final value right now.
+ Symbol *Sym;
+ uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
+ std::tie(Sym, std::ignore) =
+ Symtab->insert(Cmd->Name, /*Type*/ 0, Visibility,
+ /*CanOmitFromDynSym*/ false,
+ /*File*/ nullptr);
+ replaceSymbol<Defined>(Sym, nullptr, Cmd->Name, STB_GLOBAL, Visibility,
+ STT_NOTYPE, 0, 0, nullptr);
+ Cmd->Sym = cast<Defined>(Sym);
+ Cmd->Provide = false;
+ }
+}
+
// This function is called from assignAddresses, while we are
// fixing the output section addresses. This function is supposed
// to set the final value for a given symbol assignment.
Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=323729&r1=323728&r2=323729&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Tue Jan 30 01:04:27 2018
@@ -265,12 +265,13 @@ public:
bool needsInterpSection();
bool shouldKeep(InputSectionBase *S);
- void assignAddresses();
- void allocateHeaders(std::vector<PhdrEntry *> &Phdrs);
- void processSectionCommands();
-
- // SECTIONS command list.
- std::vector<BaseCommand *> SectionCommands;
+ void assignAddresses();
+ void allocateHeaders(std::vector<PhdrEntry *> &Phdrs);
+ void processSectionCommands();
+ void declareSymbols();
+
+ // SECTIONS command list.
+ std::vector<BaseCommand *> SectionCommands;
// PHDRS command list.
std::vector<PhdrsCommand> PhdrsCommands;
Modified: lld/trunk/test/ELF/linkerscript/symbols-synthetic.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/symbols-synthetic.s?rev=323729&r1=323728&r2=323729&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/symbols-synthetic.s (original)
+++ lld/trunk/test/ELF/linkerscript/symbols-synthetic.s Tue Jan 30 01:04:27 2018
@@ -58,20 +58,20 @@
# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=IN-SEC %s
# SIMPLE: 0000000000000128 .foo 00000000 .hidden _end_sec
-# SIMPLE-NEXT: 0000000000000120 .foo 00000000 _begin_sec
-# SIMPLE-NEXT: 0000000000000128 *ABS* 00000000 _end_sec_abs
-# SIMPLE-NEXT: 0000000000001048 .text 00000000 _start
-# SIMPLE-NEXT: 0000000000000120 .foo 00000000 begin_foo
-# SIMPLE-NEXT: 0000000000000128 .foo 00000000 end_foo
-# SIMPLE-NEXT: 0000000000000008 *ABS* 00000000 size_foo_1
+# SIMPLE-NEXT: 0000000000000120 .foo 00000000 _begin_sec
+# SIMPLE-NEXT: 0000000000000128 *ABS* 00000000 _end_sec_abs
+# SIMPLE-NEXT: 0000000000001048 .text 00000000 _start
+# SIMPLE-NEXT: 0000000000000ee4 *ABS* 00000000 size_foo_3
+# SIMPLE-NEXT: 0000000000000120 .foo 00000000 begin_foo
+# SIMPLE-NEXT: 0000000000000128 .foo 00000000 end_foo
+# SIMPLE-NEXT: 0000000000000008 *ABS* 00000000 size_foo_1
# SIMPLE-NEXT: 0000000000000008 *ABS* 00000000 size_foo_1_abs
-# SIMPLE-NEXT: 0000000000001000 .foo 00000000 begin_bar
-# SIMPLE-NEXT: 0000000000001004 .foo 00000000 end_bar
-# SIMPLE-NEXT: 0000000000000ee4 *ABS* 00000000 size_foo_2
-# SIMPLE-NEXT: 0000000000000ee4 *ABS* 00000000 size_foo_3
-# SIMPLE-NEXT: 0000000000001004 .eh_frame_hdr 00000000 __eh_frame_hdr_start
-# SIMPLE-NEXT: 0000000000001010 *ABS* 00000000 __eh_frame_hdr_start2
-# SIMPLE-NEXT: 0000000000001018 .eh_frame_hdr 00000000 __eh_frame_hdr_end
+# SIMPLE-NEXT: 0000000000001000 .foo 00000000 begin_bar
+# SIMPLE-NEXT: 0000000000001004 .foo 00000000 end_bar
+# SIMPLE-NEXT: 0000000000000ee4 *ABS* 00000000 size_foo_2
+# SIMPLE-NEXT: 0000000000001004 .eh_frame_hdr 00000000 __eh_frame_hdr_start
+# SIMPLE-NEXT: 0000000000001010 *ABS* 00000000 __eh_frame_hdr_start2
+# SIMPLE-NEXT: 0000000000001018 .eh_frame_hdr 00000000 __eh_frame_hdr_end
# SIMPLE-NEXT: 0000000000001020 *ABS* 00000000 __eh_frame_hdr_end2
# NO-SEC: 0000000000201000 .text 00000000 .hidden _begin_sec
Added: lld/trunk/test/ELF/linkerscript/version-script.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/version-script.s?rev=323729&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/version-script.s (added)
+++ lld/trunk/test/ELF/linkerscript/version-script.s Tue Jan 30 01:04:27 2018
@@ -0,0 +1,52 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+
+# RUN: echo "bar = foo; VERSION { V { global: foo; bar; local: *; }; }" > %t.script
+# RUN: ld.lld -T %t.script -shared --no-undefined-version %t.o -o %t.so
+# RUN: llvm-readobj -V %t.so | FileCheck %s
+
+## Check that we are able to version symbols defined in script.
+# CHECK: Symbols [
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Version: 0
+# CHECK-NEXT: Name: @
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Version: 0
+# CHECK-NEXT: Name: und@
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Version: 2
+# CHECK-NEXT: Name: foo@@V
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Version: 2
+# CHECK-NEXT: Name: bar@@V
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+# RUN: echo "bar = und; VERSION { V { global: foo; bar; local: *; }; }" > %t.script
+# RUN: not ld.lld -T %t.script -shared --no-undefined-version %t.o -o %t.so \
+# RUN: 2>&1 | FileCheck --check-prefix=ERR %s
+# ERR: symbol not found: und
+
+# RUN: echo "und = 0x1; VERSION { V { global: und; local: *; }; }" > %t.script
+# RUN: ld.lld -T %t.script -shared --no-undefined-version %t.o -o %t.so
+# RUN: llvm-readobj -V %t.so | FileCheck %s --check-prefix=UNDEF
+# UNDEF: Symbols [
+# UNDEF-NEXT: Symbol {
+# UNDEF-NEXT: Version: 0
+# UNDEF-NEXT: Name: @
+# UNDEF-NEXT: }
+# UNDEF-NEXT: Symbol {
+# UNDEF-NEXT: Version: 2
+# UNDEF-NEXT: Name: und@@V
+# UNDEF-NEXT: }
+# UNDEF-NEXT: ]
+
+.global und
+
+.text
+.globl foo
+.type foo, at function
+foo:
Modified: lld/trunk/test/ELF/lto/defsym.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/lto/defsym.ll?rev=323729&r1=323728&r2=323729&view=diff
==============================================================================
--- lld/trunk/test/ELF/lto/defsym.ll (original)
+++ lld/trunk/test/ELF/lto/defsym.ll Tue Jan 30 01:04:27 2018
@@ -1,18 +1,22 @@
; REQUIRES: x86
-; LTO
-; RUN: llvm-as %s -o %t.o
-; RUN: llvm-as %S/Inputs/defsym-bar.ll -o %t1.o
-; RUN: ld.lld %t.o %t1.o -shared -o %t.so -defsym=bar2=bar3
-; RUN: llvm-objdump -d %t.so | FileCheck %s
-
-; ThinLTO
-; RUN: opt -module-summary %s -o %t.o
-; RUN: opt -module-summary %S/Inputs/defsym-bar.ll -o %t1.o
-; RUN: ld.lld %t.o %t1.o -shared -o %t.so -defsym=bar2=bar3
-; RUN: llvm-objdump -d %t.so | FileCheck %s --check-prefix=THIN
-
-; Call to bar2() should not be inlined and should be routed to bar3()
-; Symbol bar3 should not be eliminated
+; LTO
+; RUN: llvm-as %s -o %t.o
+; RUN: llvm-as %S/Inputs/defsym-bar.ll -o %t1.o
+; RUN: ld.lld %t.o %t1.o -shared -o %t.so -defsym=bar2=bar3 -save-temps
+; RUN: llvm-readelf -t %t.so.lto.o | FileCheck --check-prefix=OBJ %s
+; RUN: llvm-objdump -d %t.so | FileCheck %s
+
+; ThinLTO
+; RUN: opt -module-summary %s -o %t.o
+; RUN: opt -module-summary %S/Inputs/defsym-bar.ll -o %t1.o
+; RUN: ld.lld %t.o %t1.o -shared -o %t2.so -defsym=bar2=bar3 -save-temps
+; RUN: llvm-readelf -t %t2.so1.lto.o | FileCheck --check-prefix=OBJ %s
+; RUN: llvm-objdump -d %t2.so | FileCheck %s --check-prefix=THIN
+
+; OBJ: UND bar2
+
+; Call to bar2() should not be inlined and should be routed to bar3()
+; Symbol bar3 should not be eliminated
; CHECK: foo:
; CHECK-NEXT: pushq %rax
Modified: lld/trunk/test/ELF/lto/linker-script-symbols-assign.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/lto/linker-script-symbols-assign.ll?rev=323729&r1=323728&r2=323729&view=diff
==============================================================================
--- lld/trunk/test/ELF/lto/linker-script-symbols-assign.ll (original)
+++ lld/trunk/test/ELF/lto/linker-script-symbols-assign.ll Tue Jan 30 01:04:27 2018
@@ -3,22 +3,13 @@
; RUN: echo "foo = 1;" > %t.script
; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 --script %t.script -save-temps
-; RUN: llvm-readobj -symbols %t2.lto.o | FileCheck %s
-
-; CHECK-NOT: bar
-; CHECK: Symbol {
-; CHECK: Name: foo
-; CHECK-NEXT: Value: 0x0
-; CHECK-NEXT: Size: 4
-; CHECK-NEXT: Binding: Weak
-; CHECK-NEXT: Type: Object
-; CHECK-NEXT: Other: 0
-; CHECK-NEXT: Section: .bss.foo
-; CHECK-NEXT: }
-; CHECK-NEXT:]
-
-; RUN: llvm-readobj -symbols %t2 | FileCheck %s --check-prefix=VAL
-; VAL: Symbol {
+; RUN: llvm-readobj -symbols %t2.lto.o | FileCheck %s
+
+; CHECK-NOT: bar
+; CHECK-NOT: foo
+
+; RUN: llvm-readobj -symbols %t2 | FileCheck %s --check-prefix=VAL
+; VAL: Symbol {
; VAL: Name: foo
; VAL-NEXT: Value: 0x1
; VAL-NEXT: Size:
Modified: lld/trunk/test/ELF/lto/linker-script-symbols-ipo.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/lto/linker-script-symbols-ipo.ll?rev=323729&r1=323728&r2=323729&view=diff
==============================================================================
--- lld/trunk/test/ELF/lto/linker-script-symbols-ipo.ll (original)
+++ lld/trunk/test/ELF/lto/linker-script-symbols-ipo.ll Tue Jan 30 01:04:27 2018
@@ -13,15 +13,15 @@
;; Check that LTO does not do IPO for symbols assigned by script.
; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t4 --script %t.script -save-temps
-; RUN: llvm-objdump -d %t4 | FileCheck %s --check-prefix=NOIPO
-; NOIPO: Disassembly of section .text:
-; NOIPO: foo:
-; NOIPO-NEXT: 201010: {{.*}} movl $2, %eax
-; NOIPO: _start:
-; NOIPO-NEXT: 201020: {{.*}} jmp -21 <foo>
-
-target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-target triple = "x86_64-unknown-linux-gnu"
+; RUN: llvm-objdump -d %t4 | FileCheck %s --check-prefix=NOIPO
+; NOIPO: Disassembly of section .text:
+; NOIPO: foo:
+; NOIPO-NEXT: {{.*}} movl $2, %eax
+; NOIPO: _start:
+; NOIPO-NEXT: {{.*}} jmp -21 <foo>
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
define i32 @bar() {
ret i32 1
More information about the llvm-commits
mailing list