I have two trivial source files:
int x(int y)
{
return y - 10;
}
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.
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: