gcclinkerarmeabilto

GCC (Sourcery CodeBench 2013.11) link-time optimization, ignoring -fno-short-enums


I have two trivial source files:

File bj1.cc

int x(int y)
{
    return y - 10;
}

File obj2.cc

int foo(int bar)
{
    return bar*10;
}

I am using Sourcery CodeBench lite 2013.11:

arm-none-eabi-g++ --version

Output:

arm-none-eabi-g++.exe (Sourcery CodeBench Lite 2013.11-24) 4.8.1

I compile each source file using

arm-none-eabi-g++.exe -fno-short-enums -mcpu=arm946e-s -c obj1.cc -o obj1.o  -Os -flto
arm-none-eabi-g++.exe -fno-short-enums -mcpu=arm946e-s -c obj2.cc -o obj2.o  -Os -flto

If I link them without -flto, link-time optimization (LTO) is not invoked, and I get an object file marked as having int-sized enums:

arm-none-eabi-g++.exe -fno-short-enums -mcpu=arm946e-s obj1.cc obj2.cc -Wl,-Ur -o partial_link_result.o -nostdlib -Os
arm-none-eabi-readelf.exe -a partial_link_result.o | grep enum

Output:

Tag_ABI_enum_size: int

But if I simply add -flto to the linker invocation, the output claims that it has small enums:

arm-none-eabi-g++.exe -fno-short-enums -mcpu=arm946e-s obj1.cc obj2.cc -Wl,-Ur -o partial_link_result.o -nostdlib -Os -flto
arm-none-eabi-readelf.exe -a partial_link_result.o | grep enum

Output:

Tag_ABI_enum_size: small

If I run the link step with -v, I can see this when GCC gets to the link-time optimization stage:

gcc version 4.8.1 (Sourcery CodeBench Lite 2013.11-24)
COLLECT_GCC_OPTIONS='-c' '-fexceptions' '-mcpu=arm946e-s' '-mcpu=arm946e-s' '-nostdlib' '-Os' '-v' '-D' '__CS_SOURCERYGXX_MAJ__=2013' '-D' '__CS_SOURCERYGXX_MIN__=11' '-D' '__CS_SOURCERYGXX_REV__=24' '-dumpdir' './' '-dumpbase' 'partial_link_result.o.wpa' '-fltrans-output-list=C:\Users\BOBBY_~1\AppData\Local\Temp\ccrOoESe.ltrans.out' '-fwpa' '-fresolution=C:\Users\BOBBY_~1\AppData\Local\Temp\cccj0syW.res' '-D' '__CS_SOURCERYGXX_MAJ__=2013' '-D' '__CS_SOURCERYGXX_MIN__=11'
 '-D' '__CS_SOURCERYGXX_REV__=24'
 c:/program files (x86)/sourcery/lib/gcc/../../libexec/gcc/arm-none-eabi/4.8.1/lto1.exe -quiet -dumpdir ./ -dumpbase partial_link_result.o.wpa -mcpu=arm946e-s -mcpu=arm946e-s -auxbase ccQXQ7aT -Os -version -fexceptions -fltrans-output-list=C:\Users\BOBBY_~1\AppData\Local\Temp\ccrOoESe.ltrans.out -fwpa -fresolution=C:\Users\BOBBY_~1\AppData\Local\Temp\cccj0syW.res @C:\Users\BOBBY_~1\AppData\Local\Temp\ccDElvyi

It sure looks to me like something removed -fno-short-enums from COLLECT_GCC_OPTIONS during the LTO step. I suspect this might be a general GCC problem, and not restricted to the Sourcery build.

Is this a GCC bug? I need GCC to generate object files without short enums in order to link against certain libraries built with 32-bit enums. Is there a way to accomplish this goal without rebuilding GCC from source?

I confirmed the exact same behavior in Ubuntu 14.04 (Trusty Tahr) with the arm-none-eabi-gcc 4.8.2-14ubuntu1+6toolchain version.


Solution

  • This has been confirmed as a bug in GCC. Certain options are filtered by LTO that could change the binary output.

    It is being tracked in GCC's Bugzilla instance:

    It's being tracked in the bare-metal ARM launchpad project as well: