[PATCH] D30193: [ELF] - Scan lazy linkerscipt symbols early.

Rafael Avila de Espindola via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 21 09:10:51 PST 2017


Why is fetching the archive member the correct answer? If the linker
script defines a symbol, I don't see why we need to get a member that
defines it too.

Cheers,
Rafael

George Rimar via Phabricator <reviews at reviews.llvm.org> writes:

> grimar updated this revision to Diff 89214.
> grimar added a comment.
>
> - Simplified testcase.
>
>
> https://reviews.llvm.org/D30193
>
> Files:
>   ELF/Driver.cpp
>   ELF/LinkerScript.cpp
>   ELF/LinkerScript.h
>   test/ELF/linkerscript/Inputs/lazy-symbols.s
>   test/ELF/linkerscript/lazy-symbols.s
>
>
> Index: test/ELF/linkerscript/lazy-symbols.s
> ===================================================================
> --- test/ELF/linkerscript/lazy-symbols.s
> +++ test/ELF/linkerscript/lazy-symbols.s
> @@ -0,0 +1,10 @@
> +# REQUIRES: x86
> +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/lazy-symbols.s -o %t1
> +# RUN: llvm-ar rcs %tar %t1
> +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2
> +# RUN: echo "foo = 1;" > %t.script
> +# RUN: ld.lld %t2 %tar --script %t.script -o %tout
> +# RUN: llvm-readobj -symbols %tout | FileCheck %s
> +
> +# CHECK: Name: foo
> +# CHECK-NEXT: Value: 0x1
> Index: test/ELF/linkerscript/Inputs/lazy-symbols.s
> ===================================================================
> --- test/ELF/linkerscript/Inputs/lazy-symbols.s
> +++ test/ELF/linkerscript/Inputs/lazy-symbols.s
> @@ -0,0 +1,7 @@
> +.globl foo
> +foo:
> + .long .Linfo_string
> + 
> +.section .debug_str,"MS", at progbits,1
> +.Linfo_string:
> +  .asciz "foo"
> Index: ELF/LinkerScript.h
> ===================================================================
> --- ELF/LinkerScript.h
> +++ ELF/LinkerScript.h
> @@ -247,6 +247,7 @@
>    LinkerScript();
>    ~LinkerScript();
>  
> +  void fetchLazySymbols();
>    void processCommands(OutputSectionFactory<ELFT> &Factory);
>    void addOrphanSections(OutputSectionFactory<ELFT> &Factory);
>    void removeEmptyCommands();
> Index: ELF/LinkerScript.cpp
> ===================================================================
> --- ELF/LinkerScript.cpp
> +++ ELF/LinkerScript.cpp
> @@ -321,6 +321,17 @@
>    return Ret;
>  }
>  
> +// Script can contain assignments to lazy symbols. In that case
> +// we should scan such symbols early to fetch objects from archives
> +// and create input sections.
> +template <class ELFT> void LinkerScript<ELFT>::fetchLazySymbols() {
> +  for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands)
> +    if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get()))
> +      if (SymbolBody *Sym = Symtab<ELFT>::X->find(Cmd->Name))
> +        if (Sym->isLazy())
> +          addSymbol(Cmd);
> +}
> +
>  template <class ELFT>
>  void LinkerScript<ELFT>::processCommands(OutputSectionFactory<ELFT> &Factory) {
>    for (unsigned I = 0; I < Opt.Commands.size(); ++I) {
> Index: ELF/Driver.cpp
> ===================================================================
> --- ELF/Driver.cpp
> +++ ELF/Driver.cpp
> @@ -839,6 +839,8 @@
>    for (auto *Arg : Args.filtered(OPT_wrap))
>      Symtab.wrap(Arg->getValue());
>  
> +  Script<ELFT>::X->fetchLazySymbols();
> +
>    // Now that we have a complete list of input files.
>    // Beyond this point, no new files are added.
>    // Aggregate all input sections into one place.
>
>
> Index: test/ELF/linkerscript/lazy-symbols.s
> ===================================================================
> --- test/ELF/linkerscript/lazy-symbols.s
> +++ test/ELF/linkerscript/lazy-symbols.s
> @@ -0,0 +1,10 @@
> +# REQUIRES: x86
> +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/lazy-symbols.s -o %t1
> +# RUN: llvm-ar rcs %tar %t1
> +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2
> +# RUN: echo "foo = 1;" > %t.script
> +# RUN: ld.lld %t2 %tar --script %t.script -o %tout
> +# RUN: llvm-readobj -symbols %tout | FileCheck %s
> +
> +# CHECK: Name: foo
> +# CHECK-NEXT: Value: 0x1
> Index: test/ELF/linkerscript/Inputs/lazy-symbols.s
> ===================================================================
> --- test/ELF/linkerscript/Inputs/lazy-symbols.s
> +++ test/ELF/linkerscript/Inputs/lazy-symbols.s
> @@ -0,0 +1,7 @@
> +.globl foo
> +foo:
> + .long .Linfo_string
> + 
> +.section .debug_str,"MS", at progbits,1
> +.Linfo_string:
> +  .asciz "foo"
> Index: ELF/LinkerScript.h
> ===================================================================
> --- ELF/LinkerScript.h
> +++ ELF/LinkerScript.h
> @@ -247,6 +247,7 @@
>    LinkerScript();
>    ~LinkerScript();
>  
> +  void fetchLazySymbols();
>    void processCommands(OutputSectionFactory<ELFT> &Factory);
>    void addOrphanSections(OutputSectionFactory<ELFT> &Factory);
>    void removeEmptyCommands();
> Index: ELF/LinkerScript.cpp
> ===================================================================
> --- ELF/LinkerScript.cpp
> +++ ELF/LinkerScript.cpp
> @@ -321,6 +321,17 @@
>    return Ret;
>  }
>  
> +// Script can contain assignments to lazy symbols. In that case
> +// we should scan such symbols early to fetch objects from archives
> +// and create input sections.
> +template <class ELFT> void LinkerScript<ELFT>::fetchLazySymbols() {
> +  for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands)
> +    if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get()))
> +      if (SymbolBody *Sym = Symtab<ELFT>::X->find(Cmd->Name))
> +        if (Sym->isLazy())
> +          addSymbol(Cmd);
> +}
> +
>  template <class ELFT>
>  void LinkerScript<ELFT>::processCommands(OutputSectionFactory<ELFT> &Factory) {
>    for (unsigned I = 0; I < Opt.Commands.size(); ++I) {
> Index: ELF/Driver.cpp
> ===================================================================
> --- ELF/Driver.cpp
> +++ ELF/Driver.cpp
> @@ -839,6 +839,8 @@
>    for (auto *Arg : Args.filtered(OPT_wrap))
>      Symtab.wrap(Arg->getValue());
>  
> +  Script<ELFT>::X->fetchLazySymbols();
> +
>    // Now that we have a complete list of input files.
>    // Beyond this point, no new files are added.
>    // Aggregate all input sections into one place.


More information about the llvm-commits mailing list