Son Tuan VU via llvm-dev
2018-Mar-12 15:06 UTC
[llvm-dev] Cross-compiling for ARM Cortex-M3 on x86
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 <*main*>: 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 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180312/ba125a84/attachment.html>
Tim Northover via llvm-dev
2018-Mar-12 15:15 UTC
[llvm-dev] Cross-compiling for ARM Cortex-M3 on x86
Hi, On 12 March 2018 at 15:06, Son Tuan VU via llvm-dev <llvm-dev at lists.llvm.org> wrote:> But libc code is in ARM mode:That's very bad, because Cortex-M doesn't support ARM mode. I think your libc is broken.> 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.Yes, Cortex-M has no blx instruction.> Can anyone kindly give me some pointers on how to debug this? Or at least > tell me whether this is a bug?You don't mention how you build libc, but that's what you need to fix.> 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.It'll be part of your libc's build system (Makefile?). Clang should simply refuse to produce ARM mode code if it knows it's targeting Cortex-M, so my guess is no -mcpu option is being specified. There might be subtle differences in how GCC has been compiled that means your version defaults to Thumb mode anyway, but Clang doesn't. Cheers. Tim.
Peter Smith via llvm-dev
2018-Mar-12 15:28 UTC
[llvm-dev] Cross-compiling for ARM Cortex-M3 on x86
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 <main>: > 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 >
Son Tuan VU via llvm-dev
2018-Mar-12 15:35 UTC
[llvm-dev] Cross-compiling for ARM Cortex-M3 on x86
Thanks for your prompt reply. I didn't build the libc at all, I downloaded a pre-built version of the whole toolchain from https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads, so I guess it is an official version provided by ARM and should work? This version targets ARM Cortex-M and Cortex-R family of processors... Son Tuan Vu On Mon, Mar 12, 2018 at 4:15 PM, Tim Northover <t.p.northover at gmail.com> wrote:> Hi, > > On 12 March 2018 at 15:06, Son Tuan VU via llvm-dev > <llvm-dev at lists.llvm.org> wrote: > > But libc code is in ARM mode: > > That's very bad, because Cortex-M doesn't support ARM mode. I think > your libc is broken. > > > 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. > > Yes, Cortex-M has no blx instruction. > > > Can anyone kindly give me some pointers on how to debug this? Or at least > > tell me whether this is a bug? > > You don't mention how you build libc, but that's what you need to fix. > > > 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. > > It'll be part of your libc's build system (Makefile?). Clang should > simply refuse to produce ARM mode code if it knows it's targeting > Cortex-M, so my guess is no -mcpu option is being specified. There > might be subtle differences in how GCC has been compiled that means > your version defaults to Thumb mode anyway, but Clang doesn't. > > Cheers. > > Tim. >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180312/9d8586f9/attachment.html>