https://sourceware.org/bugzilla/show_bug.cgi?id=33726
Bug ID: 33726
Summary: Output section with only symbol definitions is deleted
Product: binutils
Version: 2.45
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: ld
Assignee: unassigned at sourceware dot org
Reporter: davidegrayson at gmail dot com
Target Milestone: ---
If the linker script defines an output section that only has symbol
definitions,
with no matching input sections and no assignments to ., then the GNU linker
deletes the
section, and the linker script symbols in the resulting ELF file get assigned
to some other
unrelated section.
The LLD developers have documented this behavior:
When an output section has no input section, GNU ld will eliminate it if it
only contains
symbol assignments (e.g. .foo { symbol = 42; }).
Source: https://releases.llvm.org/18.1.7/tools/lld/docs/ELF/linker_script.html
This behavior has probably flown under the radar for a long time because the
assignment of symbols
to ELF sections does not really matter for executables. I'm only noticing it
because I'm
developing some system software and using LD to generate test cases, so I'm
looking very carefully
at the output of LD.
A workaround for the bug is to simply write ". = .;" inside the output section,
which somehow
convinces GNU LD to not delete it.
Here are the files I used to reproduce this. I'm using riscv64-unknown-elf-ld
from binutils 2.45
but you can probably observe this with any ELF target and any linker script by
simply adding a
section definition like my ".noinit" one.
==== test.ld
MEMORY
{
TLS (r): ORIGIN = 0, LENGTH = 64K
ROM (r): ORIGIN = 0x10000000, LENGTH = 64K
RAM : ORIGIN = 0x20000000, LENGTH = 64K
}
ENTRY(_start)
SECTIONS
{
.text : {
*(.text .text.*)
} > ROM
.data : {
__idata_start = .;
*(.data .data.*)
. = ALIGN(4);
__idata_end = .;
} >RAM
.bss (NOLOAD) : {
__bss_start = .;
*(.bss .bss.*)
. = ALIGN(4);
__bss_end = .;
} >RAM
.noinit (NOLOAD) : {
_noinit_start = .;
*(.noinit .noinit.*)
_noinit_end = .;
# Uncommenting this fixes the bug:
# . = .;
} >RAM
.tdata : {
*(.tdata .tdata.*)
. = ALIGN(4);
__tls_tdata_size = .;
} >TLS
}
==== bug.asm
.text
.global _start
.type _start, @function
_start:
ret
.size _start, . - _start
# Uncommenting this fixes the bug:
# .section .noinit
# .zero 4
==== build.sh
#!/usr/bin/env bash
set -uex
riscv64-unknown-elf-as -mabi=ilp32 -march=rv32i bug.asm -o bug.o
riscv64-unknown-elf-ld -melf32lriscv -Ttest.ld bug.o -o bug.elf
==== Output from riscv64-unknown-elf-objdump -xt bug.elf
bug.elf: file format elf32-littleriscv
bug.elf
architecture: riscv:rv32, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x10000000
Program Header:
0x70000003 off 0x00002000 vaddr 0x00000000 paddr 0x00000000 align 2**0
filesz 0x0000001a memsz 0x00000000 flags r--
LOAD off 0x00001000 vaddr 0x10000000 paddr 0x10000000 align 2**12
filesz 0x00000004 memsz 0x00000004 flags r-x
LOAD off 0x00002000 vaddr 0x20000000 paddr 0x20000000 align 2**12
filesz 0x00000000 memsz 0x00000000 flags rw-
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000004 10000000 10000000 00001000 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000000 20000000 20000000 00002000 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 20000000 20000000 00002000 2**0
ALLOC
3 .tdata 00000000 00000000 00000000 00002000 2**0
CONTENTS, ALLOC, LOAD, DATA, THREAD_LOCAL
4 .riscv.attributes 0000001a 00000000 00000000 00002000 2**0
CONTENTS, READONLY
SYMBOL TABLE:
10000000 l d .text 00000000 .text
20000000 l d .data 00000000 .data
20000000 l d .bss 00000000 .bss
00000000 l d .tdata 00000000 .tdata
00000000 l d .riscv.attributes 00000000 .riscv.attributes
00000000 l df *ABS* 00000000 bug.o
20000000 g .tdata 00000000 _noinit_start # <----- problem is here,
.tdata is invalid
20000000 g .data 00000000 __idata_end
20000000 g .bss 00000000 __bss_end
20000000 g .tdata 00000000 _noinit_end # <----- problem is here,
.tdata is invalid
10000000 g F .text 00000004 _start
20000000 g .bss 00000000 __bss_start
00000000 g .tdata 00000000 __tls_tdata_size
20000000 g .data 00000000 __idata_start
--
You are receiving this mail because:
You are on the CC list for the bug.