0

I am trying to build Cortex-M0 (ARMv6, thumb) firmware with clang 13.0. Everything seems fine except for builtin functions like __udivsi3, __udivmoddi4 that are in ARM mode. Of course the CPU only supports thumb and delivers a fault when trying to execute them. I know that these functions are wrong because the CPU faults, the debugger displays them as ARM mode and their addresses in the .elf have Lsb cleared. I am linking to newlib provided by gcc (v6 flavor of libc_nano.a) and the libc functions are correct (ie. thumb mode). Functions from my .c files are also correctly built in thumb mode and the firmware runs just fine until it encounters integer division.

My compile options:

clang -o some_file.o -c -MD --target=armv6m-none-eabi -nostdlib 
--sysroot="/path/to/newlib/arm-none-eabi" -fshort-enums -mcpu=cortex-m0
-mthumb -mfloat-abi=soft -g3 -I ../some/includes -Oz -std=gnu11
-Wall -pipe -ffunction-sections -fdata-sections some_file.c

My linking options:

clang -o my_project.elf --target=armv6m-none-eabi -nostdlib
-L"/path/to/newlib/arm-none-eabi/lib/." "/path/to/newlib/lib/gcc/arm-none-eabi/9.2.1/libgcc.a"
"/path/to/newlib/arm-none-eabi/lib/thumb/v6-m/nofp/libc_nano.a"
-mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -Wl,--gc-sections
-T my_linker_script.ld object_file1.o object_file2.o object_file3.o -lm

The same happens when I try --target=arm-none-eabi or -mtune=cortex-m0. I am using clang 13.0.0 (official binaries from github). I tried building on both Windows and Linux machines. Clang lists cortex-m0 as available for target arm-none-eabi. llc lists thumb in the list of targets (and all my own functions are correctly built in thumb mode).

What am I doing wrong?

Thanks for help

filo
  • 223
  • 3
  • 14
  • are you able to compile a simple c file to object (without any other libraries, etc) to the target armv6-m device. the last one or two major versions of clang I am not able to do this with the generically built tool. (--target=) The only way I could get clang to work in the recent version(s) is to build it specifically for the architecture (armv6-m) and that worked great. are you running into this issue or are you dealing only with telling the tool which library to link? – old_timer Nov 23 '21 at 00:36
  • clang/llvm has changed how you specify a target over time, I stopped around 7.x.x with clang because i could no longer maintain a set of makefiles that worked across different major versions. now that I build the binaries for the target, I am able to use the clang/llvm tools again. YMMV – old_timer Nov 23 '21 at 00:37

1 Answers1

0

I traced it down to the wrong libgcc.a being linked. I did not provide the correct architecture/thumb flags when executing arm-none-eabi-gcc -print-libgcc-file-name and it supplied the default version of that library build in ARM mode.

filo
  • 223
  • 3
  • 14