[PATCH] D41438: [ELF] - Do not handle --defsym as regular linkerscript assignment.

Rafael Avila de Espindola via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 24 12:06:56 PST 2017


I quite like the fact that defsym symbols have the same semantics as a
mini linker script.

It looks like it is important for linker scripts to allow a symbol to
be redefined (see D27276).

Why is it important for defsym to error?

Thanks,
Rafael

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

> grimar updated this revision to Diff 128096.
> grimar added a comment.
>
> - Rebased, updated.
>
>
> https://reviews.llvm.org/D41438
>
> Files:
>   ELF/LinkerScript.cpp
>   ELF/LinkerScript.h
>   ELF/ScriptParser.cpp
>   test/ELF/linkerscript/symbol-multiple-defs.s
>
>
> Index: test/ELF/linkerscript/symbol-multiple-defs.s
> ===================================================================
> --- test/ELF/linkerscript/symbol-multiple-defs.s
> +++ test/ELF/linkerscript/symbol-multiple-defs.s
> @@ -0,0 +1,14 @@
> +# REQUIRES: x86
> +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
> +
> +# RUN: echo "foo = 0x3;" > %t.script
> +# RUN: ld.lld -o %t1 --script %t.script %t
> +# RUN: llvm-objdump -t %t1 | FileCheck %s --check-prefix=SCRIPT
> +# SCRIPT: 0000000000000003 *ABS* 00000000 foo
> +
> +# RUN: not ld.lld --defsym=foo=0x3 -o %t2 %t 2>&1 \
> +# RUN:  | FileCheck %s --check-prefix=ERR
> +# ERR: duplicate symbol: foo
> +
> +.global foo
> +foo:
> Index: ELF/ScriptParser.cpp
> ===================================================================
> --- ELF/ScriptParser.cpp
> +++ ELF/ScriptParser.cpp
> @@ -277,6 +277,7 @@
>    if (!atEOF())
>      setError("EOF expected, but got " + next());
>    SymbolAssignment *Cmd = make<SymbolAssignment>(Name, E, getCurrentLocation());
> +  Cmd->IsDefsym = true;
>    Script->SectionCommands.push_back(Cmd);
>  }
>  
> Index: ELF/LinkerScript.h
> ===================================================================
> --- ELF/LinkerScript.h
> +++ ELF/LinkerScript.h
> @@ -104,6 +104,9 @@
>    bool Provide = false;
>    bool Hidden = false;
>  
> +  // Flag shows if this command is -defsym assignment.
> +  bool IsDefsym = false;
> +
>    // Holds file name and line number for error reporting.
>    std::string Location;
>  };
> Index: ELF/LinkerScript.cpp
> ===================================================================
> --- ELF/LinkerScript.cpp
> +++ ELF/LinkerScript.cpp
> @@ -129,9 +129,6 @@
>    // Define a symbol.
>    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);
>    ExprValue Value = Cmd->Expression();
>    SectionBase *Sec = Value.isAbsolute() ? nullptr : Value.Sec;
>  
> @@ -148,8 +145,21 @@
>    // write expressions like this: `alignment = 16; . = ALIGN(., alignment)`.
>    uint64_t SymValue = Value.Sec ? 0 : Value.getValue();
>  
> -  replaceSymbol<Defined>(Sym, nullptr, Cmd->Name, STB_GLOBAL, Visibility,
> -                         STT_NOTYPE, SymValue, 0, Sec);
> +  // Regular linker script assignment may be used to update existent symbol
> +  // value, but --defsym assignment should always create new symbol and report
> +  // duplicate symbol definition error if symbol already exists.
> +  if (Cmd->IsDefsym) {
> +    Sym = Symtab->addRegular(Cmd->Name, Visibility, STT_NOTYPE, SymValue,
> +                             /*Size=*/0, STB_GLOBAL, Sec,
> +                             /*File=*/nullptr);
> +  } else {
> +    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, SymValue, 0, Sec);
> +  }
>    Cmd->Sym = cast<Defined>(Sym);
>  }
>  
>
>
> Index: test/ELF/linkerscript/symbol-multiple-defs.s
> ===================================================================
> --- test/ELF/linkerscript/symbol-multiple-defs.s
> +++ test/ELF/linkerscript/symbol-multiple-defs.s
> @@ -0,0 +1,14 @@
> +# REQUIRES: x86
> +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
> +
> +# RUN: echo "foo = 0x3;" > %t.script
> +# RUN: ld.lld -o %t1 --script %t.script %t
> +# RUN: llvm-objdump -t %t1 | FileCheck %s --check-prefix=SCRIPT
> +# SCRIPT: 0000000000000003 *ABS* 00000000 foo
> +
> +# RUN: not ld.lld --defsym=foo=0x3 -o %t2 %t 2>&1 \
> +# RUN:  | FileCheck %s --check-prefix=ERR
> +# ERR: duplicate symbol: foo
> +
> +.global foo
> +foo:
> Index: ELF/ScriptParser.cpp
> ===================================================================
> --- ELF/ScriptParser.cpp
> +++ ELF/ScriptParser.cpp
> @@ -277,6 +277,7 @@
>    if (!atEOF())
>      setError("EOF expected, but got " + next());
>    SymbolAssignment *Cmd = make<SymbolAssignment>(Name, E, getCurrentLocation());
> +  Cmd->IsDefsym = true;
>    Script->SectionCommands.push_back(Cmd);
>  }
>  
> Index: ELF/LinkerScript.h
> ===================================================================
> --- ELF/LinkerScript.h
> +++ ELF/LinkerScript.h
> @@ -104,6 +104,9 @@
>    bool Provide = false;
>    bool Hidden = false;
>  
> +  // Flag shows if this command is -defsym assignment.
> +  bool IsDefsym = false;
> +
>    // Holds file name and line number for error reporting.
>    std::string Location;
>  };
> Index: ELF/LinkerScript.cpp
> ===================================================================
> --- ELF/LinkerScript.cpp
> +++ ELF/LinkerScript.cpp
> @@ -129,9 +129,6 @@
>    // Define a symbol.
>    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);
>    ExprValue Value = Cmd->Expression();
>    SectionBase *Sec = Value.isAbsolute() ? nullptr : Value.Sec;
>  
> @@ -148,8 +145,21 @@
>    // write expressions like this: `alignment = 16; . = ALIGN(., alignment)`.
>    uint64_t SymValue = Value.Sec ? 0 : Value.getValue();
>  
> -  replaceSymbol<Defined>(Sym, nullptr, Cmd->Name, STB_GLOBAL, Visibility,
> -                         STT_NOTYPE, SymValue, 0, Sec);
> +  // Regular linker script assignment may be used to update existent symbol
> +  // value, but --defsym assignment should always create new symbol and report
> +  // duplicate symbol definition error if symbol already exists.
> +  if (Cmd->IsDefsym) {
> +    Sym = Symtab->addRegular(Cmd->Name, Visibility, STT_NOTYPE, SymValue,
> +                             /*Size=*/0, STB_GLOBAL, Sec,
> +                             /*File=*/nullptr);
> +  } else {
> +    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, SymValue, 0, Sec);
> +  }
>    Cmd->Sym = cast<Defined>(Sym);
>  }
>  


More information about the llvm-commits mailing list