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