ppc64 segmentation fault on function return that returns the value of another function. Segmentation fault occurs when application is compiled with "-O2", but not when compiled with "-O1". *.i files identical, so included is a small test program, rather than the .i file. Apply following as a patch. Test with "make test". diff -urpN null/libwrapped.c ppc-test/libwrapped.c --- null/libwrapped.c 1969-12-31 16:00:00.000000000 -0800 +++ ppc-test/libwrapped.c 2005-12-12 10:22:02.000000000 -0800 @@ -0,0 +1,11 @@ +#include "proto.h" + +unsigned long fn(void) +{ + return 0; +} + +unsigned long wrapped(void) +{ + return fn(); +} diff -urpN null/main.c ppc-test/main.c --- null/main.c 1969-12-31 16:00:00.000000000 -0800 +++ ppc-test/main.c 2005-12-12 12:11:37.000000000 -0800 @@ -0,0 +1,9 @@ +#include <stdio.h> +#include "proto.h" + +int main(int argc, char **argv) +{ + printf("unwrapped: %ld\n", fn()); + printf("wrapped: %ld\n", wrapped()); + return 0; +} diff -urpN null/Makefile ppc-test/Makefile --- null/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ ppc-test/Makefile 2005-12-12 12:27:25.000000000 -0800 @@ -0,0 +1,21 @@ +# -*- makefile -*- + +CFLAGS = -m64 -Wall -g -O2 + +main: main.o libwrapped.so + $(CC) $(CFLAGS) -o main main.o -L. -lwrapped + +libwrapped.o: libwrapped.c proto.h + $(CC) $(CFLAGS) -c -o libwrapped.o libwrapped.c + +libwrapped.so: libwrapped.o + ld -g -m elf64ppc -G -h libwrapped.so -o libwrapped.so libwrapped.o + +main.o: main.c proto.h + $(CC) $(CFLAGS) -c -o main.o main.c + +clean: + rm -f *.o *.so main + +test: main + LD_LIBRARY_PATH=. ./main diff -urpN null/proto.h ppc-test/proto.h --- null/proto.h 1969-12-31 16:00:00.000000000 -0800 +++ ppc-test/proto.h 2005-12-09 13:58:10.000000000 -0800 @@ -0,0 +1,3 @@ +extern unsigned long fn(void); +extern unsigned long wrapped(void); +
Forgot version data: First seen on 3.4.4 20050721 (Red Hat 3.4.4-2). Last tested: svn revision 108426. Still fails. Using built-in specs. Target: powerpc64-unknown-linux-gnu Configured with: ./configure Thread model: posix gcc version 4.2.0 20051212 (experimental)
The testcase is invalid, because you are compiling libwrapped.so without -fPIC. Now, powerpc64 code is always PIC, so you might think that -fPIC (or -fpic) is unnecessary on powerpc64 shared libraries. However, -fPIC/pic also tells gcc to compile assuming that the object might be for a shared library. One thing this affects is whether tail calls can be made to global functions. At -O2, sibling/tail call optimisation is done, so we get a tail call from "wrapped" to "fn" because -fPIC wasn't specified. This tail call inside the shared lib destroys r2, the TOC pointer, and an invalid TOC access is the reason for the segfault. It might possible to do something about this in the linker, but more complicated examples are not possible to fix. eg. where the function tail-called is overridden by a function of the same name in the main app.