Index: ELF/Symbols.h =================================================================== --- ELF/Symbols.h +++ ELF/Symbols.h @@ -366,6 +366,9 @@ // Some linker-generated symbols need to be created as // DefinedRegular symbols. template struct ElfSym { + // The content for __ehdr_start symbol. + static DefinedRegular *EhdrStart; + // The content for _etext and etext symbols. static DefinedRegular *Etext; static DefinedRegular *Etext2; @@ -382,6 +385,7 @@ static SymbolBody *MipsGpDisp; }; +template DefinedRegular *ElfSym::EhdrStart; template DefinedRegular *ElfSym::Etext; template DefinedRegular *ElfSym::Etext2; template DefinedRegular *ElfSym::Edata; Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -596,6 +596,8 @@ if (ScriptConfig->HasContents) return; + ElfSym::EhdrStart = Symtab::X->addIgnored("__ehdr_start"); + auto Define = [this](StringRef S, DefinedRegular *&Sym1, DefinedRegular *&Sym2) { Sym1 = Symtab::X->addIgnored(S, STV_DEFAULT); @@ -1177,6 +1179,10 @@ // to each section. This function fixes some predefined absolute // symbol values that depend on section address and size. template void Writer::fixAbsoluteSymbols() { + // __ehdr_start is the location of program headers. + if (ElfSym::EhdrStart) + ElfSym::EhdrStart->Value = Out::ProgramHeaders->getVA(); + auto Set = [](DefinedRegular *S1, DefinedRegular *S2, uintX_t V) { if (S1) S1->Value = V; Index: test/ELF/ehdr_start.s =================================================================== --- /dev/null +++ test/ELF/ehdr_start.s @@ -0,0 +1,11 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: ld.lld %t.o -o %t +# RUN: llvm-objdump -t %t | FileCheck %s +# CHECK: 0000000000010040 *ABS* 00000000 .hidden __ehdr_start + +.text +.global _start, __ehdr_start +_start: + .quad __ehdr_start Index: test/ELF/linkerscript/linkerscript-ehdr_start.s =================================================================== --- /dev/null +++ test/ELF/linkerscript/linkerscript-ehdr_start.s @@ -0,0 +1,11 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "SECTIONS { }" > %t.script +# RUN: not ld.lld %t.o -script %t.script -o %t 2>&1 | FileCheck %s +# CHECK: undefined symbol: __ehdr_start + +.text +.global _start, __ehdr_start +_start: + .quad __ehdr_start