bug(?): anonymous initialisers go in the .data section, not .rodata
Austin Donnelly
Austin.Donnelly@cl.cam.ac.uk
Fri Nov 2 14:04:00 GMT 2001
In older versions of gcc, eg 2.95.2, anonymous array or structure
initialisers would go into the .rodata section. Some of our software
relied on this behaviour.
In newer gcc:
hornet$ gcc -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.96/specs
gcc version 2.96 20000731 (Red Hat Linux 7.1 2.96-85)
these same initialisers go in the .data section, ie they are not
sharable.
To reproduce:
cat >anon-init.c
void foo (void)
{
const char * const A[] = {"one", "two", 0};
}
^D
oldgcc$ gcc -v
Reading specs from /usr/opt/gcc-lib/i586-pc-linux-gnu/2.95.2/specs
gcc version 2.95.2 19991024 (release)
oldgcc$ gcc -c anon-init.c -o anon-init
oldgcc$ objdump -h anon-init
anon-init: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000022 00000000 00000000 00000034 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data 00000000 00000000 00000000 00000058 2**2
^^ note: nothing in the .data section
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 00000058 2**2
ALLOC
3 .note 00000014 00000000 00000000 00000058 2**0
CONTENTS, READONLY
4 .rodata 00000008 00000000 00000000 0000006c 2**0
^^ note: because it went here
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .comment 00000026 00000000 00000000 00000074 2**0
CONTENTS, READONLY
oldgcc$ objdump --version
GNU objdump 2.9.5
But, with newer gcc:
newgcc$ gcc -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.96/specs
gcc version 2.96 20000731 (Red Hat Linux 7.1 2.96-85)
newgcc$ gcc -c anon-init.c -o anon-init
newgcc$ objdump -h anon-init
anon-init: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000028 00000000 00000000 00000034 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data 0000000c 00000000 00000000 0000005c 2**2
^^ note: went in .data section
CONTENTS, ALLOC, LOAD, RELOC, DATA
2 .bss 00000000 00000000 00000000 00000068 2**2
ALLOC
3 .note 00000014 00000000 00000000 00000068 2**0
CONTENTS, READONLY
4 .rodata 00000008 00000000 00000000 0000007c 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .comment 00000036 00000000 00000000 00000084 2**0
CONTENTS, READONLY
newgcc$ objdump --version
GNU objdump 2.10.91
Looking at the produced assembly, the strings are put in the .rodata
section correctly, but the array initialiser isn't:
.section .rodata
.LC0:
.string "one"
.LC1:
.string "two"
.data ; this
.align 4 ; is
.LC2: ; the
.long .LC0 ; stuff
.long .LC1 ; I'm
.long 0 ; talking about
.text
.align 4
.globl foo
.type foo,@function
foo:
etc etc...
Doesn't "const char * const A[]" mean A is an array of constant
pointers to constant strings - ie the programmer promises not to
modify the array, hence it too can go in the .rodata section.
If the initialiser is placed at file scope, rather than inside a
function, then both versions of gcc put all the data in the .rodata
section as expected:
static const char * const A_init[] = { "one", "two", 0 };
void foo (void)
{
const char * const * A = A_init;
}
This is the work-around I'm using for the moment.
Austin
More information about the Gcc
mailing list