[llvm-dev] Cross-compiling for ARM Cortex-M3 on x86

Peter Smith via llvm-dev
Mon, 12 Mar 2018 15:28:09 -0000

Hello Son,

Tim is right in that by default the linker is not selecting a
compatible C library. You'll also need a linker script to direct the
code and ro-data to flash and the rw-data, heap and stack to RAM. The
GNU R/M toolchain does have some sample programs that you should be
able to alter to get what you need. I believe they use newlib or
newlib-nano. I don't have a copy of the toolchain in front of me and I
can't remember precisely where the examples are, but if you look for a
directory called samples or Samples I think you'll find enough to get
started. You'll have more luck using gcc as the linker driver than
clang as the samples use gcc specs files to communicate options and
understands multilib for bare-metal systems.

Unfortunately cross-compiling for Arm embedded systems needs quite a
bit more manual work that is device specific.

Peter

On 12 March 2018 at 15:06, Son Tuan VU via llvm-dev
<llvm-dev at lists.llvm.org> wrote:
> Hi all,
>
> I am trying to cross-compile my application for ARM Cortex-M3. Here's
how
> I'm doing it:
>
> 1, Get a pre-built GNU toolchain for ARM Cortex-M processors from
> https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads
>
> 2, Create an object file for ARM:
> clang -c -target arm-none-eabi -mcpu=cortex-m3 -mthumb -O3 -g
> --sysroot=/home/gcc-arm-none-eabi-6-2017-q2-update/arm-none-eabi test.c -o
> test.o
>
> 3, Then link it with ld:
> arm-none-eabi-gcc -o test test.o
>
> Everything seems to work until now (actually I get this warning
> "arm-none-eabi/bin/ld: warning: test.o uses 32-bit enums yet the
output is
> to use variable-size enums; use of enum values across objects may
fail", but
> I guess it is not important): I get an ELF executable for ARM Cortex-M3 as
> expected.
>
> However, things get tricky if we look closer at the assembly file (obtained
> by arm-none-eabi-objdump): the user code (written by me) is in Thumb mode,
> for example:
>
> 1420 00008fd2 :
> 1421     8fd2:   b580        push    {r7, lr}
> 1422     8fd4:   466f        mov r7, sp
> 1423     8fd6:   f7ff fd83   bl 91d8 <srand>
> 1424     8fda:   2000        movs    r0, #0
> 1425     8fdc:   bd80        pop {r7, pc}
>
> But libc code is in ARM mode:
>
> 1563 000091d8 <srand>:
> 1564     91d8:   e3a02000    mov r2, #0
> 1565     91dc:   e59f300c    ldr r3, [pc, #12]   ; 91f0 <srand+0x18>
> 1566     91e0:   e5933000    ldr r3, [r3]
> 1567     91e4:   e58300a8    str r0, [r3, #168]  ; 0xa8
> 1568     91e8:   e58320ac    str r2, [r3, #172]  ; 0xac
> 1569     91ec:   e12fff1e    bx  lr
>
> As you can see, the call to srand is just a bl (Branch with Link), not a
blx
> (Branch with Link and Exchange instruction set), so I think something is
> going wrong here. Indeed, when using a binary analysis tool to simulate
this
> code, it cannot executes correctly srand because it decodes instruction in
> Thumb mode. Surprisingly, compiling this code with arm-none-eabi-gcc with
> these same options yields a better result: the user code doesn't
change, but
> libc code is now in Thumb mode, and the binary analysis tool can simulate
> the application just fine:
>
> 1743 00009198 <srand>:
> 1744     9198:   2200        movs    r2, #0
> 1745     919a:   4b03        ldr r3, [pc, #12]   ; (91a8
<srand+0x10>)
> 1746     919c:   681b        ldr r3, [r3, #0]
> 1747     919e:   f8c3 00a8   str.w   r0, [r3, #168]  ; 0xa8
> 1748     91a2:   f8c3 20ac   str.w   r2, [r3, #172]  ; 0xac
> 1749     91a6:   4770        bx  lr
>
> Can anyone kindly give me some pointers on how to debug this? Or at least
> tell me whether this is a bug? I am a bit lost now, I've tried to look
up
> for more information on this but cannot find out why Clang doesn't
generate
> Thumb code for libc functions.
>
> Thank you very much for your help,
>
> Son Tuan Vu
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>