diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -2198,9 +2198,8 @@ else eSym->st_size = sym->getSize(); - // st_value is usually an address of a symbol, but that has a - // special meaning for uninstantiated common symbols (this can - // occur if -r is given). + // st_value is usually an address of a symbol, but that has a special + // meaning for uninstantiated common symbols (--no-define-common). if (BssSection *commonSec = getCommonSec(ent.sym)) eSym->st_value = commonSec->alignment; else if (isDefinedHere) diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -811,9 +811,12 @@ if (isa(isec) && !(isec->flags & SHF_MERGE)) continue; + // Set the symbol to be relative to the output section so that its st_value + // equals the output section address. Note, there may be a gap between the + // start of the output section and isec. auto *sym = make(isec->file, "", STB_LOCAL, /*stOther=*/0, STT_SECTION, - /*value=*/0, /*size=*/0, isec); + /*value=*/0, /*size=*/0, isec->getOutputSection()); in.symTab->addSymbol(sym); } } diff --git a/lld/test/ELF/section-symbol-gap.s b/lld/test/ELF/section-symbol-gap.s new file mode 100644 --- /dev/null +++ b/lld/test/ELF/section-symbol-gap.s @@ -0,0 +1,51 @@ +# REQUIRES: x86 +## Test st_value of the STT_SECTION symbol equals the output section address, +## instead of the first input section address. + +# RUN: split-file %s %t +# RUN: llvm-mc -filetype=obj -triple=x86_64 %t/asm -o %t.o + +# RUN: ld.lld --emit-relocs -T %t/lds %t.o -o %t.out +# RUN: llvm-readelf -S -r -s %t.out | FileCheck %s --check-prefix=EXE + +## In -r mode, section addresses are zeros, hence the st_value fields of +## STT_SECTION are zeros. +# RUN: ld.lld -r -T %t/lds %t.o -o %t.ro +# RUN: llvm-readelf -S -r -s %t.ro | FileCheck %s --check-prefix=RO + +# EXE: [Nr] Name Type Address +# EXE-NEXT: [ 0] +# EXE-NEXT: [ 1] .text PROGBITS 0000000000000000 +# EXE-NEXT: [ 2] .bss NOBITS 000000000000000a + +# EXE: R_X86_64_64 {{.*}} .bss + 1 + +# EXE: Symbol table '.symtab' contains 4 entries: +# EXE-NEXT: Num: Value Size Type Bind Vis Ndx Name +# EXE-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND +# EXE-NEXT: 1: 000000000000000a 0 SECTION LOCAL DEFAULT 2 .bss +# EXE-NEXT: 2: 0000000000000000 0 SECTION LOCAL DEFAULT 1 .text +# EXE-NEXT: 3: 0000000000000000 0 SECTION LOCAL DEFAULT 4 .comment + +# RO: [Nr] Name Type Address +# RO-NEXT: [ 0] +# RO-NEXT: [ 1] .bss NOBITS 0000000000000000 + +# RO: R_X86_64_64 {{.*}} .bss + 1 + +# RO: Symbol table '.symtab' contains 3 entries: +# RO-NEXT: Num: Value Size Type Bind Vis Ndx Name +# RO-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND +# RO-NEXT: 1: 0000000000000000 0 SECTION LOCAL DEFAULT 1 .bss +# RO-NEXT: 2: 0000000000000000 0 SECTION LOCAL DEFAULT 2 .text + +#--- asm +movabsq .bss, %rax + +.bss +.byte 0 + +#--- lds +SECTIONS { + .bss : { BYTE(0) *(.bss) } +}