[Bug target/63373] New: ELF symbol sizes for variable-length objects are too small
srk31 at srcf dot ucam.org
gcc-bugzilla@gcc.gnu.org
Thu Sep 25 17:26:00 GMT 2014
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63373
Bug ID: 63373
Summary: ELF symbol sizes for variable-length objects are too
small
Product: gcc
Version: 4.9.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: srk31 at srcf dot ucam.org
Created attachment 33569
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=33569&action=edit
Source files used in the bug description
Suppose I have an object file containing a data object of some variable-length
type.
$ cat section-size-test.c
struct blah
{
float foo;
int i[];
};
struct blah b = { 42.0, { 1, 2, 3, 4, 0 } };
$ cc -c -o section-size-test.o section-size-test.c
Now I have an object of size 24 bytes. From ELF's point of view, we have a
section of size 24 but a symbol of size only 4.
$ readelf -Ss section-size-test.o
There are 9 section headers, starting at offset 0xc8:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .text PROGBITS 0000000000000000 00000040
0000000000000000 0000000000000000 AX 0 0 1
[ 2] .data PROGBITS 0000000000000000 00000040
0000000000000018 0000000000000000 WA 0 0 4
[ 3] .bss NOBITS 0000000000000000 00000058
0000000000000000 0000000000000000 WA 0 0 1
[ 4] .comment PROGBITS 0000000000000000 00000058
0000000000000024 0000000000000001 MS 0 0 1
[ 5] .note.GNU-stack PROGBITS 0000000000000000 0000007c
0000000000000000 0000000000000000 0 0 1
[ 6] .shstrtab STRTAB 0000000000000000 0000007c
0000000000000045 0000000000000000 0 0 1
[ 7] .symtab SYMTAB 0000000000000000 00000308
00000000000000c0 0000000000000018 8 7 8
[ 8] .strtab STRTAB 0000000000000000 000003c8
0000000000000017 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
Symbol table '.symtab' contains 8 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS section-size-test.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
3: 0000000000000000 0 SECTION LOCAL DEFAULT 2
4: 0000000000000000 0 SECTION LOCAL DEFAULT 3
5: 0000000000000000 0 SECTION LOCAL DEFAULT 5
6: 0000000000000000 0 SECTION LOCAL DEFAULT 4
7: 0000000000000000 4 OBJECT GLOBAL DEFAULT 2 b
The bug is that when copy relocations are used, the variable-length part of the
object will get thrown away. I think the symbol size should also be 24 (hence
filing a gcc bug not a binutils bug).
Continuing: I create a shared library out of this object file, and an
executable that depends on my object.
$ cat exe.c
struct blah
{
float foo;
int i[];
};
extern struct blah b;
int main(void)
{
return (unsigned long long) &b % 32;
}
$ cc -shared -o section-size-test.so section-size-test.o
$ cc -o exe exe.c section-size-test.so
Now the executable is using a copy reloc to address my variable-length object.
$ objdump -RT exe
exe: file format elf64-x86-64
DYNAMIC SYMBOL TABLE:
0000000000000000 w D *UND* 0000000000000000
_ITM_deregisterTMCloneTable
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __libc_start_main
0000000000000000 w D *UND* 0000000000000000 __gmon_start__
0000000000000000 w D *UND* 0000000000000000
_Jv_RegisterClasses
0000000000000000 w D *UND* 0000000000000000
_ITM_registerTMCloneTable
0000000000601038 g D .data 0000000000000000 Base _edata
0000000000601040 g D .bss 0000000000000000 Base _end
0000000000601038 g D .bss 0000000000000000 Base __bss_start
0000000000400550 g DF .init 0000000000000000 Base _init
0000000000601038 g DO .bss 0000000000000004 b
0000000000400724 g DF .fini 0000000000000000 Base _fini
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
0000000000600ff8 R_X86_64_GLOB_DAT __gmon_start__
0000000000601038 R_X86_64_COPY b
0000000000601018 R_X86_64_JUMP_SLOT __libc_start_main
0000000000601020 R_X86_64_JUMP_SLOT __gmon_start__
We can see that b has size 4, and the object has been truncated, since _end is
at b+8. The variable-length part of the object has not been copy-relocated.
I would guess that the right behaviour is to emit the symbol as having the
"full" size of the object, which is clearly known at compile time. Then the
linker will (I hope?) create a big enough copy reloc.
More information about the Gcc-bugs
mailing list