Javier-varez / Postform

Postponed formatting experiments with string interning in C++. Inspired by the defmt Rust crate
MIT License
14 stars 1 forks source link

Using clang-12 links against an ARM std library instead of Thumb #111

Closed Javier-varez closed 3 years ago

Javier-varez commented 3 years ago

When building with clang-12 the compiler actually links against an ARM std library instead of a Thumb standard library. Therefore, when running on the Cortex-M3, the processor immediately triggers a hardfault when it hits a blx instruction transitioning to the ARM execution mode.

This seems to only happen with clang-12, but it is not reproducible with clang-10 or clang-11.

The following snippet shows the blx call to ARM code:

08000b00 <Reset_Handler>:
 8000b00:   b5b0        push    {r4, r5, r7, lr}
 8000b02:   af02        add r7, sp, #8
 8000b04:   f240 0000   movw    r0, #0
 8000b08:   f240 0108   movw    r1, #8
 8000b0c:   f2c2 0000   movt    r0, #8192   ; 0x2000
 8000b10:   f2c2 0100   movt    r1, #8192   ; 0x2000
 8000b14:   1a0a        subs    r2, r1, r0
 8000b16:   d005        beq.n   8000b24 <Reset_Handler+0x24>
 8000b18:   f640 4110   movw    r1, #3088   ; 0xc10
 8000b1c:   f6c0 0100   movt    r1, #2048   ; 0x800
 8000b20:   f7ff ea8e   blx 8000040 <__aeabi_memcpy>

Instead, this should look like this:

08000aec <Reset_Handler>:
 8000aec:   b5b0        push    {r4, r5, r7, lr}
 8000aee:   af02        add r7, sp, #8
 8000af0:   f240 0000   movw    r0, #0
 8000af4:   f240 0108   movw    r1, #8
 8000af8:   f2c2 0000   movt    r0, #8192   ; 0x2000
 8000afc:   f2c2 0100   movt    r1, #8192   ; 0x2000
 8000b00:   1a0a        subs    r2, r1, r0
 8000b02:   d005        beq.n   8000b10 <Reset_Handler+0x24>
 8000b04:   f640 31fc   movw    r1, #3068   ; 0xbfc
 8000b08:   f6c0 0100   movt    r1, #2048   ; 0x800
 8000b0c:   f7ff fa98   bl  8000040 <__aeabi_memcpy>
Javier-varez commented 3 years ago

It looks like this is happening because somehow clang-12 links against the wrong library. below is a snippet from the map file of the elf file generated using clang-12:

 8000000  8000000       b4     4 .root_section
 8000000  8000000       40     4         _deps/cortex-m_startup-build/libcortex-m_startup.a(startup.cpp.o):(.exception_table)
 8000000  8000000       40     1                 g_exception_table
 8000040  8000040       10     4         /home/javier/Documents/devtools/gcc-arm-none-eabi-10-2020-q4-major/bin/../arm-none-eabi/lib/libc_nano.a(lib_a-aeabi_memcpy.o):(.text.__aeabi_memcpy)
 8000040  8000040        0     1                 $a
 8000040  8000040       10     1                 __aeabi_memcpy
 8000040  8000040       10     1                 __aeabi_memcpy8
 8000040  8000040       10     1                 __aeabi_memcpy4

Compared to an elf file built with clang-11 it is quite clear that the linked library is not correct:

 8000000  8000000       80     4 .root_section
 8000000  8000000       40     4         _deps/cortex-m_startup-build/libcortex-m_startup.a(startup.cpp.o):(.exception_table)
 8000000  8000000       40     1                 g_exception_table
 8000040  8000040        4     2         /home/javier/Documents/devtools/gcc-arm-none-eabi-10-2020-q4-major/bin/../arm-none-eabi/lib/thumb/v7-m/nofp/libc_nano.a(lib_a-aeabi_memcpy.o):(.text.__aeabi_memcpy)
 8000040  8000040        0     1                 $t
 8000041  8000041        4     1                 __aeabi_memcpy
 8000041  8000041        4     1                 __aeabi_memcpy8
 8000041  8000041        4     1                 __aeabi_memcpy4

It looks like clang-12 does not properly use the multilib settings to search for libs in lib/thumb/v7-m/nofp and instead links directly against the libc_nano library located in lib.

Javier-varez commented 3 years ago

It turns out that clang-12 adds the lib path to the library search paths based on the --sysroot option. The invocation of lld is:

 "/usr/bin/ld.lld-12" "--gc-sections" "--gc-sections" "CMakeFiles/test.dir/test.cpp.o"  "/lib/thumb/v7-m/nofp:/home/javier/Documents/devtools/gcc-arm-none-eabi-10-2020-q4-major/bin/../lib/gcc/arm-none-eabi/10.2.1/thumb/v7-m/nofp" "-lnosys" "-lc_nano" "-lstdc++_nano" "-lgcc" "-lnosys" "-lc_nano" "-lstdc++_nano" "-lgcc" "-Bstatic" "-L/usr/lib/llvm-12/lib/clang/12.0.1/lib/baremetal" "-L/home/javier/Documents/devtools/gcc-arm-none-eabi-10-2020-q4-major/bin/../arm-none-eabi/lib" "-L/home/javier/Documents/devtools/gcc-arm-none-eabi-10-2020-q4-major/bin/../arm-none-eabi/lib/thumb/v7-m/nofp" "-L/home/javier/Documents/devtools/gcc-arm-none-eabi-10-2020-q4-major/bin/../lib/gcc/arm-none-eabi/10.2.1/thumb/v7-m/nofp" "-o" "test"