0

Many questions in this forum start with "why does my code not run..." For a change, this one is "why does my code run..."

I develop on Ubuntu 18.04 running as a VM machine on a laptop (windows x86). The following program compiled and linked with gcc runs fine and displays a 64 bit address.

char *s = "Hello\n"; printf ("Hello at address: %p\n", s);

My assumption is that arm-none-eabi targets a system bare metal. Of course I am not trying to run the above program on a bare metal. But I am trying to understand how cross compilation works.

The same program compiled and linked with arm-none-eabi-gcc (installed from Ubuntu) indicates a lot of missing references (_exit ...etc.) - normal. The code created is ARM assembly language, I verified with arm-none-eabi-objdump.

Adding the option --specs=nosys.specs at load time solves the missing references - as expected. When I run it on Ubuntu, QEMU is automatically called and has a segmentation fault. I am not surprised about the segmentation fault but the automatic launch of QEMU was unexpected.

Changing the option to --spec=rdimon.specs also solves the missing references - as expected. But despite the assembly code created is arm, it runs on Ubuntu (x86). The address displayed is 32 bits.

I know that rdimon.specs relates to semi-hosting, but I thought this was only activated when the program runs on the target (arm processor) and communicates with the host running gdb. Apparently I am wrong.

Sorry about this long preamble...simple question: how is it that my arm code runs on x86?

user1238760
  • 61
  • 2
  • 6

1 Answers1

0

This is a result of the binfmt mechanism. When qemu is installed, it registers itself to run non-native executables, and is transparently invoked when a non-native ELF is executed. When semihosting is enabled using rdimon specs, it links a suitable set of libc stubs which cooperate with the host environment.

nanofarad
  • 40,330
  • 4
  • 86
  • 117