[llvm-dev] ARM baremetal linking

Peter Smith via llvm-dev llvm-dev at lists.llvm.org
Tue Oct 9 02:12:48 PDT 2018


On Mon, 8 Oct 2018 at 20:48, Goran Mekić <meka at tilda.center> wrote:
>
> On Mon, Oct 08, 2018 at 05:47:11PM +0100, Peter Smith wrote:
> > By default I think that Clang looks for compiler-rt in the resource
> > directory, this is usually relative to the clang executable, something
> > like ../lib/clang/6.0.0/lib/baremetal/libclang_rt.builtins-armv7m.a
> > for a --target=armv7-m-none-eabi. You can find out where this is with
> > --print-resource-dir
>
> Strange:
>
> clang60 -target arm-none-eabi -march=armv7-m -mcpu=cortex-m4 -print-resource-dir
> /usr/local/llvm60/lib/clang/6.0.1
>
> clang60 -target arm-none-eabi -march=armv7-m -mcpu=cortex-m4 -print-libgcc-file-name
> /usr/local/llvm60/lib/clang/6.0.1/lib/libclang_rt.builtins-arm.a
>
> > If there is a SIGINT on push {r7, lr} that might indicate that the
> > stack pointer register isn't set correctly. Depending on how your
> > libraries work you may have to do this yourself prior to entering
> > __start. Will be worth seeing what SP (R13) is in your debugger at
> > that point.
>
> I made a mistake when I said it's not breaking on entrypoint. I just
> didn't enable debug build, so the lldb output was different. For
> completenes, this is the linker command now:
>
> ld.lld60 -m armelf --entry=__start -T/usr/home/meka/repos/nuttx/nuttx/configs/nucleo-f4x1re/scripts/f401re.ld -L"/usr/home/meka/repos/nuttx/nuttx/staging" -L"/usr/home/meka/repos/nuttx/nuttx/arch/arm/src/board" -o "/usr/home/meka/repos/nuttx/nuttx/nuttx" --start-group -lsched -ldrivers -lconfigs -lc -lmm -larch -lxx -lapps -lfs -lbinfmt -lxx -lboard /usr/local/lib/baremetal/libclang_rt.builtins-arm.a --end-group
>
> This is what debugger says when -g is added to CFLAGS:
>
> lldb nuttx
> (lldb) target create "nuttx"
> Current executable set to 'nuttx' (arm).
> (lldb) gdb-remote 3333                                                                                                                                                                                                            Process 1 stopped
> * thread #1, stop reason = signal SIGTRAP
>     frame #0: 0x08000188 nuttx`__start at stm32_start.c:274
>    271   ****************************************************************************/
>    272
>    273  void __start(void)
> -> 274  {
>    275    const uint32_t *src;
>    276    uint32_t *dest;
>    277
> (lldb) register read
> General Purpose Registers:
>         r0 = 0x00000000
>         r1 = 0x00000000
>         r2 = 0x00000000
>         r3 = 0x00000000
>         r4 = 0x00000000
>         r5 = 0x00000000
>         r6 = 0x00000000
>         r7 = 0x00000000
>         r8 = 0x00000000
>         r9 = 0x00000000
>        r10 = 0x00000000
>        r11 = 0x00000000
>        r12 = 0x00000000
>         sp = 0x200016c8
>         lr = 0xffffffff
>         pc = 0x08000188  nuttx`__start at stm32_start.c:274
>       cpsr = 0x00000000
>
> (lldb)
>
> In other words, it does break on entrypoint.

Ok. Good luck tracking down where the problem is.

>
> > Adding -mfpu=none -mfloat-abi=soft to the CMAKE_C_FLAGS and
> > CMAKE_ASM_FLAGS should prevent any use of floating point. There is a
> > check in the CMake files to remove the VFP sources if a particular
> > macro isn't defined with the compilation flags so this should make it
> > unnecessary to manual edit the CMakeLists.txt file.
> I compiled without hardware FPU now. I also added
> -DCMAKE_BUILD_TYPE=Debug
>
> GCC build readelf (without debug): https://pastebin.com/vJwCkD09
> Clang build readelf (with debug): https://pastebin.com/t75WQQvG
>
> When I diff'ed those two, what I noticed is this:
>
> -  Tag_ARM_ISA_use: Yes
> +  Tag_ARM_ISA_use: No
>
> Of course, there's tons of differences there, but this one is a bit funky.
>
> Regards,
> meka
>

It looks like the Tag_ARM_ISA_use is from the GCC build (from the
first pastebin link). From the symbol table it looks like there is
some ARM code in there ($a symbols) and from the file symbols most
likely from files _lshrdi3.o, _aeabi_ldivmod.o, _aeabi_uldivmod.o,
libgcc2.c, _dvmd_tls.o, _clzdi2.o and _clzsi2.o . It looks like the
GCC build may be picking up the wrong version of libgcc as I would
expect problems if this ARM code was ever run. Just as an aside are
you using LLD to link the GCC objects? I'd half expect GNU LD to give
you an error message for the presence of ARM code in M-profile.

Peter


More information about the llvm-dev mailing list