Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -878,6 +878,8 @@ if (ErrorCount) return; + Script::X->addUndefined(); + for (auto *Arg : Args.filtered(OPT_wrap)) Symtab.wrap(Arg->getValue()); Index: ELF/LinkerScript.h =================================================================== --- ELF/LinkerScript.h +++ ELF/LinkerScript.h @@ -217,6 +217,8 @@ // A map from memory region name to a memory region descriptor. llvm::DenseMap MemoryRegions; + + std::vector Undefined; }; extern ScriptConfiguration *ScriptConfig; @@ -297,6 +299,8 @@ void addSymbol(SymbolAssignment *Cmd); void processCommands(OutputSectionFactory &Factory); + void addUndefined(); + ExprValue getSymbolValue(const Twine &Loc, StringRef S) override; bool isDefined(StringRef S) override; }; Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -392,6 +392,13 @@ } template +void LinkerScript::addUndefined() { + for (const llvm::StringRef &Name : Opt.Undefined) { + Symtab::X->addUndefined(Name); + } +} + +template void LinkerScript::processCommands(OutputSectionFactory &Factory) { // A symbol can be assigned before any section is mentioned in the linker // script. In an DSO, the symbol values are addresses, so the only important @@ -998,8 +1005,8 @@ if (SymbolBody *B = Symtab::X->find(S)) { if (auto *D = dyn_cast(B)) return {D->Section, D->Value}; - auto *C = cast(B); - return {In::Common, C->Offset}; + if (auto *C = dyn_cast(B)) + return {In::Common, C->Offset}; } error(Loc + ": symbol not found: " + S); return 0; @@ -1871,8 +1878,11 @@ return [=] { return V; }; // Tok is a symbol name. - if (Tok != "." && !isValidCIdentifier(Tok)) - setError("malformed number: " + Tok); + if (Tok != ".") { + if (!isValidCIdentifier(Tok)) + setError("malformed number: " + Tok); + Opt.Undefined.push_back(Tok); + } return [=] { return ScriptBase->getSymbolValue(Location, Tok); }; } Index: test/ELF/linkerscript/symbol-reserved.s =================================================================== --- /dev/null +++ test/ELF/linkerscript/symbol-reserved.s @@ -0,0 +1,16 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "PROVIDE_HIDDEN(newsym = __ehdr_start + 5);" > %t.script +# RUN: ld.lld -o %t1 %t.script %t +# RUN: llvm-objdump -t %t1 | FileCheck %s + +# CHECK: 0000000000200005 .text 00000000 .hidden newsym + +# RUN: ld.lld -o %t1.so %t.script %t -shared +# RUN: llvm-objdump -t %t1.so | FileCheck --check-prefix=SHARED %s + +# SHARED: 0000000000000005 .dynsym 00000000 .hidden newsym + +.global _start +_start: + lea newsym(%rip),%rax