"John David Anglin" writes: > Andreas Jaeger wrote: >> GCC CVS mainline miscompiles glibc on i686-linux-gnu. The actual >> error I noticed is: >> CPP='/opt/gcc/3.3-devel/bin/gcc -E -x c-header' /builds/glibc/test-libc/elf/ld-linux.so.2 --library-path /builds/glibc/test-libc:/builds/glibc/test-libc/math:/builds/glibc/test-libc/elf:/builds/glibc/test-libc/dlfcn:/builds/glibc/test-libc/nss:/builds/glibc/test-libc/nis:/builds/glibc/test-libc/rt:/builds/glibc/test-libc/resolv:/builds/glibc/test-libc/crypt:/builds/glibc/test-libc/linuxthreads /builds/glibc/test-libc/sunrpc/rpcgen -Y ../scripts -c rpcsvc/bootparam_prot.x -o /builds/glibc/test-libc/sunrpc/xbootparam_prot.T >> make[2]: *** [/builds/glibc/test-libc/sunrpc/xbootparam_prot.stmp] Segmentation fault >> make[2]: Leaving directory `/cvs/libc/sunrpc' > > I hit what appears to be the same error trying to build glibc-2.3.1 on > hppa-linux. It's hard to debug because the segmentation fault occurs in > a shared library without any debug symbols. In my particular case, it > seemed as if the code was trying to call an undefined weak (indirect > call to function at address 0x0). I could reproduce this with a simple hello-world program and also with some smaller program, it is indeed a bug in handling of weak extern functions. Here's a small testcase that has the same behaviour: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ extern void weak_func (void *arg); asm (".weak weak_func"); void test (void *arg) { if (&weak_func != (void *)0) weak_func (arg); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Is compiled correctly with GCC 3.3 CVS but with GCC 3.4 the test for NULL is removed: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arthur:~/tmp:[0]$ /opt/gcc/3.3-devel/bin/gcc -O2 -c weak.c arthur:~/tmp:[0]$ objdump -Dr weak.o weak.o: file format elf32-i386 Disassembly of section .text: 00000000 : 0: 55 push %ebp 1: b8 00 00 00 00 mov $0x0,%eax 2: R_386_32 weak_func 6: 85 c0 test %eax,%eax 8: 89 e5 mov %esp,%ebp a: 74 06 je 12 c: 5d pop %ebp d: e9 fc ff ff ff jmp e e: R_386_PC32 weak_func 12: 5d pop %ebp 13: c3 ret Disassembly of section .data: arthur:~/tmp:[0]$ /opt/gcc/3.4-devel/bin/gcc -O2 -c weak.c arthur:~/tmp:[0]$ objdump -Dr weak.o weak.o: file format elf32-i386 Disassembly of section .text: 00000000 : 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 5d pop %ebp 4: e9 fc ff ff ff jmp 5 5: R_386_PC32 weak_func Disassembly of section .data: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If I change this line: asm (".weak weak_func"); to #pragma weak weak_func , GCC 3.4 compiles this correctly with the test for NULL. This one seems to be fine also: extern void weak_func (void *arg) __attribute ((weak)); GCC changed existing behaviour and miscompiles code that worked before for ages. So, how should this miscompilation get fixed? Is this a bug in glibc or an overoptimizing GCC? I've CC'ed the libc-alpha list, Andreas -- Andreas Jaeger SuSE Labs aj@suse.de private aj@arthur.inka.de http://www.suse.de/~aj