1
votes

I have two trivial source files

obj1.cc:

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

obj2.cc:

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

I am using Sourcery codebench lite 2013.11:

$ arm-none-eabi-g++ --version
  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 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
  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
  Tag_ABI_enum_size: small

If I run the link step with -v, I can see this when gcc gets to the lto 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 any way to accomplish this goal without rebuilding gcc from source?

Update: I just confirmed the exact same behavior in Ubuntu 14.04 with the arm-none-eabi-gcc 4.8.2-14ubuntu1+6toolchain (http://packages.ubuntu.com/trusty/devel/gcc-arm-none-eabi)

1

1 Answers

0
votes

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:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=61123

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

https://bugs.launchpad.net/gcc-arm-embedded/+bug/1315810