Index: ELF/Symbols.h =================================================================== --- ELF/Symbols.h +++ ELF/Symbols.h @@ -302,6 +302,9 @@ // Some linker-generated symbols need to be created as // DefinedRegular symbols. struct ElfSym { + // The content for __bss_start symbol. + static DefinedRegular *BssStart; + // The content for _etext and etext symbols. static DefinedRegular *Etext; static DefinedRegular *Etext2; Index: ELF/Symbols.cpp =================================================================== --- ELF/Symbols.cpp +++ ELF/Symbols.cpp @@ -28,6 +28,7 @@ using namespace lld; using namespace lld::elf; +DefinedRegular *ElfSym::BssStart; DefinedRegular *ElfSym::Etext; DefinedRegular *ElfSym::Etext2; DefinedRegular *ElfSym::Edata; Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -846,6 +846,10 @@ // __ehdr_start is the location of ELF file headers. addOptionalRegular("__ehdr_start", Out::ElfHeader, 0, STV_HIDDEN); + // __bss_start is the location of .bss.* sections. + ElfSym::BssStart = + addOptionalRegular("__bss_start", Out::ElfHeader, 0, STV_DEFAULT); + auto Define = [](StringRef S, DefinedRegular *&Sym1, DefinedRegular *&Sym2) { Sym1 = addOptionalRegular(S, Out::ElfHeader, 0, STV_DEFAULT); assert(S.startswith("_")); @@ -1675,6 +1679,9 @@ if (LastRW) Set(ElfSym::Edata, ElfSym::Edata2, LastRW->First, LastRW->p_filesz); + if (OutputSection *Bss = findSection(".bss")) + Set(ElfSym::BssStart, nullptr, Bss, 0); + // Setup MIPS _gp_disp/__gnu_local_gp symbols which should // be equal to the _gp symbol's value. if (Config->EMachine == EM_MIPS) { Index: test/ELF/Inputs/bss-start.s =================================================================== --- test/ELF/Inputs/bss-start.s +++ test/ELF/Inputs/bss-start.s @@ -0,0 +1,13 @@ +.rodata +.globl a +.size a, 4 +.type a, @object +a: +.word 1 + +.section .data,"aw",%progbits +.globl b +.size b, 4 +.type b, @object +b: +.word 2 Index: test/ELF/bss-start.s =================================================================== --- test/ELF/bss-start.s +++ test/ELF/bss-start.s @@ -0,0 +1,21 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/bss-start.s -o %t2.o +# RUN: ld.lld -shared %t2.o -o %t.so +# RUN: ld.lld %t %t.so -o %t2 +# RUN: llvm-objdump -t -section-headers %t2 | FileCheck %s + +# CHECK: Sections: +# CHECK: Idx Name Size Address Type +# CHECK: 7 .bss.rel.ro 00000004 00000000002020b0 BSS +# CHECK: 8 .bss 00000008 0000000000203000 BSS +# CHECK: SYMBOL TABLE: +# CHECK: 0000000000203000 .bss 00000000 __bss_start + +.global __bss_start +.text +_start: +.comm sym1,4,4 + + movl $1, a + movl $1, b Index: test/ELF/bss-start2.s =================================================================== --- test/ELF/bss-start2.s +++ test/ELF/bss-start2.s @@ -0,0 +1,17 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/bss-start.s -o %t2.o +# RUN: ld.lld -shared %t2.o -o %t.so +# RUN: ld.lld %t %t.so -o %t2 +# RUN: llvm-objdump -t -section-headers %t2 | FileCheck %s + +# CHECK: Sections: +# CHECK: Idx Name Size Address Type +# CHECK: 7 .bss 00000004 0000000000203000 BSS +# CHECK: SYMBOL TABLE: +# CHECK: 0000000000203000 .bss 00000000 __bss_start + +.global __bss_start +.text +_start: + movl $1, b Index: test/ELF/bss-start3.s =================================================================== --- test/ELF/bss-start3.s +++ test/ELF/bss-start3.s @@ -0,0 +1,16 @@ + +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: ld.lld %t -o %t2 +# RUN: llvm-objdump -t -section-headers %t2 | FileCheck %s + +# CHECK: Sections: +# CHECK: Idx Name Size Address Type +# CHECK: 2 .bss 00000004 0000000000201000 BSS +# CHECK: SYMBOL TABLE: +# CHECK: 0000000000201000 .bss 00000000 __bss_start + +.global __bss_start +.text +_start: +.comm sym1,4,4