Watch out for function reordering in GCC 4.6
Colin Watson
cjwatson at ubuntu.com
Mon Sep 26 09:13:37 UTC 2011
I ran across https://bugs.launchpad.net/bugs/837815 last night. In
short, GCC 4.6 has a new optimisation pass which tries to detect
functions which are unlikely to be executed and cooperates with the
linker to group them all together at the start of the .text section in
the resulting binary, in an effort to improve performance with large
executables. In particular, such functions will be emitted before the
entry point by default. Generally I have no quarrel with this
behaviour, but, in specialised binaries such as boot loaders that rely
on the entry point being at a precise location, this can cause havoc.
I've checked GRUB 2 and SYSLINUX, and found both of those clean. GRUB 2
is currently built with GCC 4.5, but escapes this even with GCC 4.6 by
good fortune: the optimiser does not find any unlikely symbols in the
GRUB kernel. SYSLINUX generally seems to use explicit linker scripts
which don't treat .text.unlikely sections specially. However,
developers with an interest in other such specialised binaries may wish
to check them out to ensure they haven't been broken. (Fortunately very
few binaries have this kind of specialised requirement.)
In a built tree, you can look for object files where the compiler found
unlikely-to-be-executed functions like this:
for x in $(find -name \*.o); do
objdump -x "$x" | fgrep -q .text.unlikely && echo "$x"
done
You can check whether the linked binary has come out correctly by using
'nm -n binary.elf' (whatever the file name is before it's converted to
its final form using 'objcopy -O binary' or similar; with any luck your
build system keeps this temporary file around for inspection) and
checking that the position of the entry point symbol (usually _start)
matches its expected location.
The simplest fix I know of, and the one I'm going to use in GRUB Legacy,
is to compile any object files linked into such binaries with
-fno-reorder-functions. This option is available back to GCC 3.3.
--
Colin Watson [cjwatson at ubuntu.com]
More information about the ubuntu-devel
mailing list