gcc can target wrong instruction set when building JDK native code
David Holmes
david.holmes at oracle.com
Tue Apr 8 05:48:07 UTC 2014
I just filed this as:
https://bugs.openjdk.java.net/browse/JDK-8039426
Our JDK build does not specify -march/-mtune (whereas hotspot specifies
-march=i586) so JDK gets gcc's default behaviour. The default is
-mtune=generic and 'generic', at least back to 4.2, means i686 - this
means that the generated code will not run on devices that only support
the Pentium (i586) instructions.
We only observed this behaviour when doing 32-bit builds on certain
64-bit hosts. This is somewhat ironic as the docs for -m32 state:
"The 32-bit environment sets int, long and pointer to 32 bits and
generates code that runs on any i386 system. "
So if anything a 32-bit build on a 64-bit system should always work on
any i386 device, whereas 32-bit on 32-bit should be i686 by default. But
we observe the opposite. The reason seems to be that the gcc we are
using has itself been built with specific default behaviour that
conflicts with the documented defaults. If we look at gcc on a 64-bit
Ubuntu host for example we see:
> gcc -m32 -v -E -
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro
4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs
--enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr
--program-suffix=-4.6 --enable-shared --enable-linker-build-id
--with-system-zlib --libexecdir=/usr/lib --without-included-gettext
--enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6
--libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu
--enable-libstdcxx-debug --enable-libstdcxx-time=yes
--enable-gnu-unique-object --enable-plugin --enable-objc-gc
--disable-werror --with-arch-32=i686 --with-tune=generic
--enable-checking=release --build=x86_64-linux-gnu
--host=x86_64-linux-gnu --target=x86_64-linux-gnu
Note the --with-arch-32=i686 - hence why our 32-bit builds are wrong.
In contrast on an older 32-bit Ubuntu we see:
> gcc -m32 -v -E -
Using built-in specs.
Target: i486-linux-gnu
So the default target is i486, hence okay for i586.
The Fedora 9 "official" 32-bit build machines are configured for i386.
So gcc's behaviour seems at odds with its documentation. But regardless
we should not be relying on whatever default is used but should set
-mtune/-march explicitly as is done by hotspot.
David
More information about the build-dev
mailing list