[lld] r301391 - [ELF] - Implemented --defsym option.

Sean Silva via llvm-commits llvm-commits at lists.llvm.org
Thu May 4 16:38:26 PDT 2017


On Wed, Apr 26, 2017 at 3:40 AM, George Rimar via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Author: grimar
> Date: Wed Apr 26 05:40:02 2017
> New Revision: 301391
>
> URL: http://llvm.org/viewvc/llvm-project?rev=301391&view=rev
> Log:
> [ELF] - Implemented --defsym option.
>
> gnu ld description of option is:
>
> --defsym=symbol=expression
> Create a global symbol in the output file, containing the absolute address
> given
> by expression. You may use this option as many times as necessary to
> define multiple
> symbols in the command line. A limited form of arithmetic is supported for
> the
> expression in this context: you may give a hexadecimal constant or the
> name of an
> existing symbol, or use "+" and "-" to add or subtract hexadecimal
> constants or
> symbols. If you need more elaborate expressions, consider using the linker
> command
> language from a script. Note: there should be no white space between
> symbol,
> the equals sign ("="), and expression.
>
> In compare with D32082, this patch does not support math expressions and
> absolute
> symbols. It implemented via code similar to --wrap. That covers 1 of 3
> possible
> --defsym cases.
>
> Differential revision: https://reviews.llvm.org/D32171
>
> Added:
>     lld/trunk/test/ELF/defsym.s
> Modified:
>     lld/trunk/ELF/Driver.cpp
>     lld/trunk/ELF/Options.td
>     lld/trunk/ELF/SymbolTable.cpp
>     lld/trunk/ELF/SymbolTable.h
>
> Modified: lld/trunk/ELF/Driver.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.
> cpp?rev=301391&r1=301390&r2=301391&view=diff
> ============================================================
> ==================
> --- lld/trunk/ELF/Driver.cpp (original)
> +++ lld/trunk/ELF/Driver.cpp Wed Apr 26 05:40:02 2017
> @@ -880,6 +880,21 @@ static uint64_t getImageBase(opt::InputA
>    return V;
>  }
>
> +// Parses --defsym=alias option.
> +static std::vector<std::pair<StringRef, StringRef>>
> +getDefsym(opt::InputArgList &Args) {
> +  std::vector<std::pair<StringRef, StringRef>> Ret;
> +  for (auto *Arg : Args.filtered(OPT_defsym)) {
> +    StringRef From;
> +    StringRef To;
> +    std::tie(From, To) = StringRef(Arg->getValue()).split('=');
> +    if (!isValidCIdentifier(To))
> +      error("--defsym: symbol name expected, but got " + To);
> +    Ret.push_back({From, To});
> +  }
> +  return Ret;
> +}
> +
>  // Do actual linking. Note that when this function is called,
>  // all linker scripts have already been parsed.
>  template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
> @@ -945,6 +960,10 @@ template <class ELFT> void LinkerDriver:
>    for (auto *Arg : Args.filtered(OPT_wrap))
>      Symtab.wrap(Arg->getValue());
>
> +  // Handle --defsym=sym=alias option.
> +  for (std::pair<StringRef, StringRef> &Def : getDefsym(Args))
> +    Symtab.alias(Def.first, Def.second);
> +
>    // 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.
>
> Modified: lld/trunk/ELF/Options.td
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.
> td?rev=301391&r1=301390&r2=301391&view=diff
> ============================================================
> ==================
> --- lld/trunk/ELF/Options.td (original)
> +++ lld/trunk/ELF/Options.td Wed Apr 26 05:40:02 2017
> @@ -25,6 +25,8 @@ def build_id_eq: J<"build-id=">, HelpTex
>  def compress_debug_sections : J<"compress-debug-sections=">,
>    HelpText<"Compress DWARF debug sections">;
>
> +def defsym: J<"defsym=">, HelpText<"Define a symbol alias">;
> +
>

This option is also accepted as `--defsym foo=0x1000`, not just
`--defsym=foo=0x1000`.

-- Sean Silva


>  def L: JoinedOrSeparate<["-"], "L">, MetaVarName<"<dir>">,
>    HelpText<"Add a directory to the library search path">;
>
>
> Modified: lld/trunk/ELF/SymbolTable.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/
> SymbolTable.cpp?rev=301391&r1=301390&r2=301391&view=diff
> ============================================================
> ==================
> --- lld/trunk/ELF/SymbolTable.cpp (original)
> +++ lld/trunk/ELF/SymbolTable.cpp Wed Apr 26 05:40:02 2017
> @@ -168,6 +168,19 @@ template <class ELFT> void SymbolTable<E
>    memcpy(Sym->Body.buffer, Wrap->Body.buffer, sizeof(Wrap->Body));
>  }
>
> +// Creates alias for symbol. Used to implement --defsym=ALIAS=SYM.
> +template <class ELFT>
> +void SymbolTable<ELFT>::alias(StringRef Alias, StringRef Name) {
> +  SymbolBody *B = find(Name);
> +  if (!B) {
> +    error("-defsym: undefined symbol: " + Name);
> +    return;
> +  }
> +  Symbol *Sym = B->symbol();
> +  Symbol *AliasSym = addUndefined(Alias);
> +  memcpy(AliasSym->Body.buffer, Sym->Body.buffer, sizeof(AliasSym->Body));
> +}
> +
>  static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {
>    if (VA == STV_DEFAULT)
>      return VB;
>
> Modified: lld/trunk/ELF/SymbolTable.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/
> SymbolTable.h?rev=301391&r1=301390&r2=301391&view=diff
> ============================================================
> ==================
> --- lld/trunk/ELF/SymbolTable.h (original)
> +++ lld/trunk/ELF/SymbolTable.h Wed Apr 26 05:40:02 2017
> @@ -86,6 +86,7 @@ public:
>
>    void trace(StringRef Name);
>    void wrap(StringRef Name);
> +  void alias(StringRef Alias, StringRef Name);
>
>  private:
>    std::vector<SymbolBody *> findByVersion(SymbolVersion Ver);
>
> Added: lld/trunk/test/ELF/defsym.s
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/
> defsym.s?rev=301391&view=auto
> ============================================================
> ==================
> --- lld/trunk/test/ELF/defsym.s (added)
> +++ lld/trunk/test/ELF/defsym.s Wed Apr 26 05:40:02 2017
> @@ -0,0 +1,44 @@
> +# REQUIRES: x86
> +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
> +# RUN: ld.lld -o %t %t.o --defsym=foo2=foo1
> +# RUN: llvm-readobj -t -s %t | FileCheck %s
> +# RUN: llvm-objdump -d -print-imm-hex %t | FileCheck %s --check-prefix=USE
> +
> +## In compare with GNU linkers, symbol defined with --defsym does
> +## not get aliased name in symbol table:
> +# CHECK:      Symbol {
> +# CHECK:        Name: foo1
> +# CHECK-NEXT:   Value: 0x123
> +# CHECK-NEXT:   Size:
> +# CHECK-NEXT:   Binding: Global
> +# CHECK-NEXT:   Type:
> +# CHECK-NEXT:   Other:
> +# CHECK-NEXT:   Section: Absolute
> +# CHECK-NEXT: }
> +# CHECK-NEXT: Symbol {
> +# CHECK-NEXT:   Name: foo1
> +# CHECK-NEXT:   Value: 0x123
> +# CHECK-NEXT:   Size:
> +# CHECK-NEXT:   Binding: Global
> +# CHECK-NEXT:   Type:
> +# CHECK-NEXT:   Other:
> +# CHECK-NEXT:   Section: Absolute
> +# CHECK-NEXT: }
> +
> +## Check we can use foo2 and it that it is an alias for foo1.
> +# USE:       Disassembly of section .text:
> +# USE-NEXT:  _start:
> +# USE-NEXT:    movl $0x123, %edx
> +
> +# RUN: not ld.lld -o %t %t.o --defsym=foo2=1 2>&1 | FileCheck %s
> -check-prefix=ERR1
> +# ERR1: error: --defsym: symbol name expected, but got 1
> +
> +# RUN: not ld.lld -o %t %t.o --defsym=foo2=und 2>&1 | FileCheck %s
> -check-prefix=ERR2
> +# ERR2: error: -defsym: undefined symbol: und
> +
> +.globl foo1
> + foo1 = 0x123
> +
> +.global _start
> +_start:
> +  movl $foo2, %edx
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170504/f9a79aa9/attachment.html>


More information about the llvm-commits mailing list