xmon: setjmp / longjmp implementation problems
Hi,
I was hunting an ugly problem in the NuBus PowerMac port of Linux [1] for a while now (that platform isn't included in mainline kernel and still is based on 2.4 kernel series).
Linux was successfully built using gcc-3.3.5/binutils-2.15 so far.
Later toolchain versions (e.g. gcc-3.4.5/binutils-2.15) turned out to break things during hardware detection on the NuBus. Looking at the relevant code sections shows that the register probing code is based on the setjmp/longjmp implementation [2] found in xmon. Regarding the "ppc" platform that code almost matches at least up to mainline kernel 2.6.20.1 [3].
On the "powerpc" platform the code did dramatically change [4].
I was extracting both implementations to a simple userspace application to be able to easily try different compiler versions and optimization levels.
Eventually I found out that the temporary solution is to build the ppc-implementation using -O1 for gcc versions >3.3.5.
Since I found a comment by Paul in arch/ppc/xmon/setjmp.c: "NB this file must be compiled with -O2.", I was wondering which toolchain versions are/were used to compile xmon-enabled kernels for the ppc and powerpc platform.
Since -O2 seems to be the default for 2.6 kernels as well, I am wondering what gcc version is known to build a kernel with xmon support. Are there are any known gcc versions, which are causing trouble with xmon (actually its setjmp/longjmp implementation)?
Some details of toolchain tests follow:
"ppc" implementation:
When -O2 is used gcc-3.4.5 inlines static functions by default, which turned out to be the first problem. Even when "static" is removed the resulting program flow reflects an infinite loop (when longjumped function returns).
I found out that -O1 with gcc-3.4.5 generates code, which resembles the functionality of gcc-3.3.5 with -O2. I.e. a working version of setjmp/longjmp. A segmentation fault occurs when no optimization level is used.
With gcc-4.1.0 no successful working build was possible.
"powerpc" implementation:
The binary works with no optimization level, -O0 and -O1 with gcc-3.4.5. Using -O2 turns the resulting code into an infinite loop again. With gcc-4.1.0/binutils-2.16.1 only -O0 generated a useful binary.
Thanks for any suggestions!
Florian
[1] http://nubus-pmac.sf.net
[2]
http://nubus-pmac.cvs.sourceforge.net/nubus-pmac/linuxppc-2.4-nubus/arch/ppc/platforms/nbpmac_setup.c
Lines 162-194
[3] http://lxr.linux.no/source/arch/ppc/xmon/setjmp.c?a=ppc
[4] http://lxr.linux.no/source/arch/powerpc/xmon/setjmp.S?a=ppc
Just for the record:
I made a mistake in my userspace test environment regarding the setjmp/longjmp implementation.
I defined setjmp/longjmp functions as static ones, which triggered recent compilers to inline. Inlining breaks setjmp/longjmp of course.
Further I realized that the NuBus-specific setjmp/longjmp was also defined as static functions. For xmon this was never the case (even defined in a separate file).
Thanks to David Gibson and Sergei Shtylyov for answering my questions on #mklinux.
Cheers,
Florian