Search code examples
c++c++11armtoolchainlinaro

Linaro toolchain fails to create ARMv5 binary


I am trying to upgrade my compiler to support C++11, the kernel of my target machine is 2.6.33.20.

For this purpose I am attempting to use the prebuilt binaries at https://releases.linaro.org/components/toolchain/binaries/, namely the version 5.5.0.

The trivial testing program

//#include <functional>
#include <stdio.h>

int main(void)
{
//  auto lambda = [](int value) { printf("Wert: %d\n", value); };
//  lambda(20);
    printf("My output\n");
    return 0;
}

compiles fine with the command arm-linux-gnueabi-g++ -o test -static-libstdc++ -std=gnu++11 main.cpp.

When I execute file on the executable, it outputs, test: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, for GNU/Linux 2.6.32, BuildID[sha1]=2d49dc2492f7fb2ee5992f7614604aac370e42f7, with debug_info, not stripped.

The file command run over the same source but compiled with the old (Pre-C++11) compiler yields: test: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, for GNU/Linux 2.6.14, not stripped

The output of readelf -A yields for the old (working) compiler:

Attribute Section: aeabi
File Attributes
  Tag_CPU_name: "ARM10TDMI"
  Tag_CPU_arch: v5T
  Tag_ARM_ISA_use: Yes
  Tag_THUMB_ISA_use: Thumb-1
  Tag_ABI_PCS_wchar_t: 4
  Tag_ABI_FP_denormal: Needed
  Tag_ABI_FP_exceptions: Needed
  Tag_ABI_FP_number_model: IEEE 754
  Tag_ABI_align_needed: 8-Byte
  Tag_ABI_enum_size: int

whereas the new compiler produced by the new compiler yields:

Attribute Section: aeabi
File Attributes
  Tag_CPU_name: "7-A"
  Tag_CPU_arch: v7
  Tag_CPU_arch_profile: Anwendung
  Tag_ARM_ISA_use: Yes
  Tag_THUMB_ISA_use: Thumb-2
  Tag_ABI_PCS_wchar_t: 4
  Tag_ABI_FP_rounding: Needed
  Tag_ABI_FP_denormal: Needed
  Tag_ABI_FP_exceptions: Needed
  Tag_ABI_FP_number_model: IEEE 754
  Tag_ABI_align_needed: 8-Byte
  Tag_ABI_align_preserved: 8-byte, except leaf SP
  Tag_ABI_enum_size: int
  Tag_CPU_unaligned_access: v6

Following this, I've added the flag -mcpu=arm10tdmi to the above command (resulting in arm-linux-gnueabi-g++ -mcpu=arm10tdmi -o test main.cpp), however the output of readelf still remains the same. Using the ARM flags -march=arm5vt and -mtune=arm10tdmi lead to the exact same result.

This suggests, that the compiler ignores the architecture flags (or maybe does not support building for ARM5) and insists on building for ARM7.

I've also tried the toolchain 4.9, but with the same results.

As a side note: The arm-linux-gnueabi-g++ shipped with Ubuntu 14.04 is known to work (with C++11 support), however I can't seem to find a way to pack the thing into a folder to be used as a transferable toolchain.

Edit: Following old_timer's input, I've redirected the compilation to an object file (main.o) with the command arm-linux-gnueabi-g++ -mcpu=arm10tdmi main.cpp -c

Running readelf -A on the resulting object file yields this output:

Attribute Section: aeabi
File Attributes
  Tag_CPU_name: "ARM10TDMI"
  Tag_CPU_arch: v5T
  Tag_ARM_ISA_use: Yes
  Tag_THUMB_ISA_use: Thumb-1
  Tag_ABI_PCS_wchar_t: 4
  Tag_ABI_FP_denormal: Needed
  Tag_ABI_FP_exceptions: Needed
  Tag_ABI_FP_number_model: IEEE 754
  Tag_ABI_align_needed: 8-Byte
  Tag_ABI_align_preserved: 8-byte, except leaf SP
  Tag_ABI_enum_size: int
  Tag_ABI_optimization_goals: Aggressive Debug

However, when I try to create an actual executable from this using arm-linux-gnueabi-g++ -mcpu=arm10tdmi main.o -o test, the readelf output returns to the ARMv7 output I posted above.

This suggests, that the compiler itself understands and uses the -mcpu switch, but the linker then proceeds and turns it into a ARMv7 binary.


Solution

  • Kudos for this answer to go old_timer, who gave me an invaluable hint on where to go.

    All I ended up having to do was mosey over to https://crosstool-ng.github.io, download the package, rummage through the dependencies and then let the thing do it's magic.

    I chose the minimal configuration, compiler version 5.5.0 and, despite my worries that Kernel version 2.6.33.20 was not available, the binary simply worked after adding the target architecture to the command line call.