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