Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -531,6 +531,26 @@ DefinedSynthetic::SectionEnd); } +template +static void defineStandartSymbols(SymbolTable &Symtab) { + auto Define = [&](StringRef S, DefinedRegular *&Sym1, + DefinedRegular *&Sym2) { + Sym1 = Symtab.addIgnored(S, STV_DEFAULT); + + // The name without the underscore is not a reserved name, + // so it is defined only when there is a reference against it. + assert(S.startswith("_")); + S = S.substr(1); + if (SymbolBody *B = Symtab.find(S)) + if (B->isUndefined()) + Sym2 = Symtab.addAbsolute(S, STV_DEFAULT); + }; + + Define("_end", ElfSym::End, ElfSym::End2); + Define("_etext", ElfSym::Etext, ElfSym::Etext2); + Define("_edata", ElfSym::Edata, ElfSym::Edata2); +} + // The linker is expected to define some symbols depending on // the linking result. This function defines such symbols. template void Writer::addReservedSymbols() { @@ -578,22 +598,8 @@ if (!isOutputDynamic()) Symtab.addIgnored("__tls_get_addr"); - auto Define = [this](StringRef S, DefinedRegular *&Sym1, - DefinedRegular *&Sym2) { - Sym1 = Symtab.addIgnored(S, STV_DEFAULT); - - // The name without the underscore is not a reserved name, - // so it is defined only when there is a reference against it. - assert(S.startswith("_")); - S = S.substr(1); - if (SymbolBody *B = Symtab.find(S)) - if (B->isUndefined()) - Sym2 = Symtab.addAbsolute(S, STV_DEFAULT); - }; - - Define("_end", ElfSym::End, ElfSym::End2); - Define("_etext", ElfSym::Etext, ElfSym::Etext2); - Define("_edata", ElfSym::Edata, ElfSym::Edata2); + if (!ScriptConfig->HasContents) + defineStandartSymbols(Symtab); } // Sort input sections by section name suffixes for Index: test/ELF/end.s =================================================================== --- test/ELF/end.s +++ test/ELF/end.s @@ -23,52 +23,6 @@ // DEFAULT-NEXT: Value: 0x12008 // DEFAULT: ] -// If there is no .bss section, "_end" should point to the end of the .data section. -// RUN: echo "SECTIONS { \ -// RUN: /DISCARD/ : { *(.bss) } }" > %t.script -// RUN: ld.lld %t.o --script %t.script -o %t -// RUN: llvm-readobj -sections -symbols %t | FileCheck %s --check-prefix=NOBSS - -// NOBSS: Sections [ -// NOBSS: Name: .data -// NOBSS-NEXT: Type: -// NOBSS-NEXT: Flags [ -// NOBSS-NEXT: SHF_ALLOC -// NOBSS-NEXT: SHF_WRITE -// NOBSS-NEXT: ] -// NOBSS-NEXT: Address: 0x159 -// NOBSS-NEXT: Offset: -// NOBSS-NEXT: Size: 2 -// NOBSS: ] -// NOBSS: Symbols [ -// NOBSS: Name: _end -// NOBSS-NEXT: Value: 0x15B -// NOBSS: ] - -// If the layout of the sections is changed, "_end" should point to the end of allocated address space. -// RUN: echo "SECTIONS { \ -// RUN: .bss : { *(.bss) } \ -// RUN: .data : { *(.data) } \ -// RUN: .text : { *(.text) } }" > %t.script -// RUN: ld.lld %t.o --script %t.script -o %t -// RUN: llvm-readobj -sections -symbols %t | FileCheck %s --check-prefix=TEXTATEND - -// TEXTATEND: Sections [ -// TEXTATEND: Name: .text -// TEXTATEND-NEXT: Type: -// TEXTATEND-NEXT: Flags [ -// TEXTATEND-NEXT: SHF_ALLOC -// TEXTATEND-NEXT: SHF_EXECINSTR -// TEXTATEND-NEXT: ] -// TEXTATEND-NEXT: Address: 0x160 -// TEXTATEND-NEXT: Offset: -// TEXTATEND-NEXT: Size: 1 -// TEXTATEND: ] -// TEXTATEND: Symbols [ -// TEXTATEND: Name: _end -// TEXTATEND-NEXT: Value: 0x161 -// TEXTATEND: ] - .global _start,_end .text _start: Index: test/ELF/linkerscript/linkerscript-edata-etext.s =================================================================== --- test/ELF/linkerscript/linkerscript-edata-etext.s +++ test/ELF/linkerscript/linkerscript-edata-etext.s @@ -0,0 +1,20 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-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: _edata +# CHECK: undefined symbol: _end +# CHECK: undefined symbol: _etext + +.global _start,_end,_etext,_edata +.text +_start: + .quad _edata + 0x1 + .quad _etext + 0x1 + .quad _end + 0x1 + +.data + .word 1 +.bss + .align 4 + .space 6