Index: ELF/LTO.cpp =================================================================== --- ELF/LTO.cpp +++ ELF/LTO.cpp @@ -10,6 +10,7 @@ #include "LTO.h" #include "Config.h" #include "Error.h" +#include "LinkerScript.h" #include "InputFiles.h" #include "SymbolTable.h" #include "Symbols.h" @@ -150,9 +151,11 @@ // 2) Symbols that are used in regular objects. // 3) C named sections if we have corresponding __start_/__stop_ symbol. // 4) Symbols that are defined in bitcode files and used for dynamic linking. + // 5) Symbols assigned from linkerscript. R.VisibleToRegularObj = Config->Relocatable || Sym->IsUsedInRegularObj || (R.Prevailing && Sym->includeInDynsym()) || - UsedStartStop.count(ObjSym.getSectionName()); + UsedStartStop.count(ObjSym.getSectionName()) || + Script->Opt.AssignedSymbols.count(B->getName()); if (R.Prevailing) undefine(Sym); R.LinkerRedefined = Config->RenamedSymbols.count(Sym); Index: ELF/LinkerScript.h =================================================================== --- ELF/LinkerScript.h +++ ELF/LinkerScript.h @@ -191,6 +191,9 @@ // A list of symbols referenced by the script. std::vector ReferencedSymbols; + + // A list of symbols assigned by the script. + llvm::DenseSet AssignedSymbols; }; class LinkerScript final { Index: ELF/ScriptParser.cpp =================================================================== --- ELF/ScriptParser.cpp +++ ELF/ScriptParser.cpp @@ -712,6 +712,7 @@ } SymbolAssignment *ScriptParser::readAssignment(StringRef Name) { + Script->Opt.AssignedSymbols.insert(Name); StringRef Op = next(); assert(Op == "=" || Op == "+="); Expr E = readExpr(); Index: test/ELF/lto/linker-script-symbols2.ll =================================================================== --- test/ELF/lto/linker-script-symbols2.ll +++ test/ELF/lto/linker-script-symbols2.ll @@ -0,0 +1,48 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o + +; 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: Global +; 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 { +; VAL: Name: foo +; VAL-NEXT: Value: 0x1 +; VAL-NEXT: Size: +; VAL-NEXT: Binding: Global +; VAL-NEXT: Type: None +; VAL-NEXT: Other: +; VAL-NEXT: Section: Absolute +; VAL-NEXT: } + +; RUN: echo "zed = 1;" > %t2.script +; RUN: ld.lld -m elf_x86_64 %t.o -o %t3 --script %t2.script +; RUN: llvm-readobj -symbols %t3 | FileCheck %s --check-prefix=ABS +; ABS: Symbol { +; ABS: Name: zed +; ABS-NEXT: Value: 0x1 +; ABS-NEXT: Size: 0 +; ABS-NEXT: Binding: Global +; ABS-NEXT: Type: None +; ABS-NEXT: Other: 0 +; ABS-NEXT: Section: Absolute +; ABS-NEXT: } + +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +@foo = global i32 0 +@bar = global i32 0