2

Good evening everyone,

I am trying to compile a simple program in Ada for Arm-based microcontroller. I installed gnat-5-arm-linux-gnueabi package on Linux subsystem for Windows.

Now, compiling with arm-linux-gnueabi-gcc-5 -mcpu=cortex-m4 -mthumb program.adb works fine, however linking with arm-linux-gnueabi-ld -T flash.ld -o program.elf program.o results in an error:

program.o:(.ARM.exidx+0x0): undefined reference to `__aeabi_unwind_cpp_pr0'

I have looked through existing solutions, however none of them worked for me. I have tried installing gcc-arm-none-eabi package and using its linker (the same error), as well as using ld (does not recognise arm target).

One of my theories is that I might be using wrong GNAT package or binary, either for compiling or linking. Therefore, if someone knows where to find some descriptions of those, it might also help me :-) (there are quite a few GNAT packages, but only 2 with "arm" in their name)

EDIT: There is a file libgcc_eh.a under /usr/lib/gcc-cross/arm-linux-gnueabi/5/, which contains symbol "unwind"; adding this file to the linker input seems to solve this error, but makes a few new "undefined references" appear:

Incl/libgcc_eh.a(unwind-arm.o): In function 'get_eit_entry':
(.text+0x238): undefined reference to '__exidx_start'
Incl/libgcc_eh.a(unwind-arm.o): In function 'get_eit_entry':
(.text+0x23c): undefined reference to '__exidx_end'
Incl/libgcc_eh.a(unwind-arm.o): In function 'unwind_phase2':
(.text+0x334): undefined reference to 'abort'
Incl/libgcc_eh.a(unwind-arm.o): In function 'unwind_phase2_forced':
(.text+0x424): undefined reference to 'memcpy'
Incl/libgcc_eh.a(unwind-arm.o): In function 'unwind_phase2_forced':
(.text+0x478): undefined reference to 'memcpy'
Incl/libgcc_eh.a(unwind-arm.o): In function '__gnu_Unwind_Resume':
(.text+0x5b8): undefined reference to 'abort'
Incl/libgcc_eh.a(unwind-arm.o): In function '__gnu_Unwind_Resume':
(.text+0x5f4): undefined reference to 'abort'
Incl/libgcc_eh.a(pr-support.o): In function '_Unwind_GetTextRelBase':
(.text+0x4f0): undefined reference to 'abort'
micmys
  • 48
  • 6
  • 1
    One thing to check is whether you are using the right style of exceptions - look for pragmas or compiler options for SJLJ versus ZCX (Setjump/Longjump vs Zero Cost Exceptions) as your runtime may not support both (and "unwind" suggests exception handling code is involved) –  Feb 10 '18 at 00:44
  • It looks like this package uses ZCX, and there is different one for SJLJ: `gnat-5-sjlj-arm-linux-gnueabi`, so this is probably not an issue – micmys Feb 10 '18 at 03:29
  • Which ARM-based MCU? and, do you need to build in the Linux subsystem, or would a Windows toolset be OK? – Simon Wright Feb 10 '18 at 10:48
  • @BrianDrummond I tried to do that, but whatever combination I use there are always multiple undefined references – micmys Feb 10 '18 at 17:27
  • @SimonWright STM32, but at this stage it shouldn't matter I guess. The Ada program is just an empty loop, without any MCU-specific instructions. As for Windows toolset - I have tried it on native Linux computer with identical effect, so it's not a problem with WSL – micmys Feb 10 '18 at 17:27
  • Sorry, my bad. I added those to the question now. – micmys Feb 10 '18 at 18:17
  • Related : including links to some useful ARM resources ... https://stackoverflow.com/questions/34721811/does-ada-real-time-need-an-underlying-operating-system/34722070#34722070 –  Feb 11 '18 at 13:30

1 Answers1

3

When you compile program.adb, the resulting object code will contain references to the runtime system (for, e.g., exception support, text i/o).

The gnat-5-arm-linux-gnueabi package will by default compile for a Linux-based RTS, hence the undefined references.

You could probably get by with this package by specifying an appropriate RTS for your board (--RTS=/where/ever) - if you had one!

I think your best bet for getting started is to download one of the compiler suites from AdaCore]1. This’ll take you to a download page for a host version compatible with your OS; click on the "More packages, platforms, versions and sources" link at the bottom right, and select your platform: either "ARM ELF (hosted on linux)" or "ARM ELF (hosted on windows)".

On Linux, there’s an installation README: (a) you’ll probably need to install as root, (b) the relevant examples are in <installation root>/share/examples/gnat-cross. As I remember, the led-flasher-stm32f4 example is actually for an STM32F429I, which has different and fewer pin assignments for the on-board LEDs! see src/lights.ads.

You should find documentation in <installation root>/share/doc. See gps for the AdaCore IDE, gnat for various components including the Ada Reference Manual (confusingly known as "ARM"), gnat-cross for cross-compilation issues.

Simon Wright
  • 25,108
  • 2
  • 35
  • 62
  • Thanks for this suggestion! I installed "ARM ELF (hosted on windows)" version from Adacore's website. Unfortunately, when I try to run `arm-eabi-gcc -mcpu=cortex-m4 -mthumb program.adb` , I get an error: `fatal error, run-time library not installed correctly cannot locate file system.ads compilation abandoned` – micmys Feb 11 '18 at 03:01
  • Ok, the lights example compiles and flashes onto the board. So I will just assume that the command previously mentioned is incorrect, but the configuration works otherwise. Thank you again for your help :-) – micmys Feb 11 '18 at 03:32
  • ah, sounds like you are bare metal programming, or at least, your unspecified "ARM based microcontroller" works somewhere below the Linux OS level. Without a full Ada RTS, you don't have access to full Ada, and that places restrictions on e.g. how you can handle exceptions. Solutions are either to restrict your Ada usage (this can be expressed with pragmas like "No_Exception_Propagation", sometimes found in system.ads) or to extend the RTS. You'll soon find Simon's own ARM RTS work. (Adding the EH code as per edit is tantamount to extending the RTS, but you don't want to do that ad-hoc) –  Feb 11 '18 at 13:24
  • Yeah, I was trying to do bare metal programming. I tried to follow this tutorial: [link](http://www.inspirel.com/articles/Ada_On_Cortex_First_Program.html), where the author uses native tools, but mentions that cross-compilation can be used in the same way, just with different commands; apparently it's not that simple. – micmys Feb 11 '18 at 14:07
  • If you go down to the _Cross Compilation_ section of [Chapter 2 of the Inspirel tutorial](http://www.inspirel.com/articles/Ada_On_Cortex_Documentation_And_Tools.html) you’ll see that when Maciej says `gcc` he means `arm-eabi-gcc`; i.e. _not_ the host tools. Unless you’re on a Pi. – Simon Wright Feb 11 '18 at 14:35
  • Well, if he uses cross-compilation as well, then I was following his tutorial precisely, and I have no idea why he did not encounter the same problems. – micmys Feb 11 '18 at 14:56
  • Hmm. I think he must have been running on an ARM-based Linux machine, e.g. a Pi, so the compiler saw the host `system.ads`. Will see if I can find a simple workround & report back ... oh, try putting system.ads in the current directory, `package System is\nend System;` (`\n` => newline, must have that newline in there!) – Simon Wright Feb 11 '18 at 17:21
  • Thanks, that worked! Also, what helped then for original problem was adding `pragma Restrictions (No_Exception_Propagation);` to system.ads. So I think my problem is solved completely (or at least it seems to be). In any case, thank you both for all the help! – micmys Feb 12 '18 at 00:21