earlephilhower / pico-quick-toolchain

GCC Cross-compiler chain for Raspberry Pi Pico
35 stars 6 forks source link

Invalid libgcc.a ? #10

Closed pierremolinaro closed 2 years ago

pierremolinaro commented 2 years ago

I am writing a bare metal blink led code for a Raspberry Pi Pico. I need GCC for Cortex-M0+, an elf2uf2 tool, and a uf2conv.py script.

The platform I use is a x86_64 MacIntosh running Monterey, and I have installed the 2.0.2 release of your Raspberry Pi Pico board manager.

I use the elf2uf2 tool at ~/Library/Arduino15/packages/rp2040/tools/pqt-elf2uf2/1.3.3-a-ed6d983/elf2uf2, and the uf2conv.py script at ~/Library/Arduino15/packages/rp2040/hardware/rp2040/2.0.2/tools/uf2conv.py

When I use the GCC compiler at ~/Library/Arduino15/packages/rp2040/tools/pqt-gcc/1.3.3-a-ed6d983/bin/, my program does not work (no blink). However it works well when I use an other compiler, either the one provided by ARM (https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/downloads), either the one provided by Adafruit at ~/Library/Arduino15/packages/adafruit/tools/arm-none-eabi-gcc/9-2019q4/bin/ with "Arduino SAMD Boards (32-bits ARM Cortex-M0+)" board manager".

I think the ~/Library/Arduino15/packages/rp2040/tools/pqt-gcc/1.3.3-a-ed6d983/lib/gcc/arm-none-eabi/10.3.0/thumb/libgcc.a file is the cause of the problem: when I replace it with one from the above GCC distributions, my program works.

I have objdump-ed the library by running: ~/Library/Arduino15/packages/rp2040/tools/pqt-gcc/1.3.3-a-ed6d983/bin/arm-none-eabi-objdump -d ~/Library/Arduino15/packages/rp2040/tools/pqt-gcc/1.3.3-a-ed6d983/lib/gcc/arm-none-eabi/10.3.0/thumb/libgcc.a

For the symbol __aeabi_ldivmod, I found this code:

00000000 <__aeabi_ldivmod>:
   0:   e3530000    cmp r3, #0
   4:   03520000    cmpeq   r2, #0
   8:   1a000007    bne 2c <__aeabi_ldivmod+0x2c>
   c:   e3510000    cmp r1, #0
  10:   b3a01102    movlt   r1, #-2147483648    ; 0x80000000
  14:   b3a00000    movlt   r0, #0
  18:   ba000002    blt 28 <__aeabi_ldivmod+0x28>
  ...

With the help of DDI0419E_armv6m_arm.pdf document, I think this binary code is not valid for a Cortex-M0+, for example op for "cmp r3, #0" is 2b00, the e3530000 op code is not valid for this processor.

There are many other functions with such 32-bits code.

And for the corresponding Adafruit library: ~/Library/Arduino15/packages/rp2040/tools/pqt-gcc/1.3.3-a-ed6d983/bin/arm-none-eabi-objdump -d ~/Library/Arduino15/packages/adafruit/tools/arm-none-eabi-gcc/9-2019q4/lib/gcc/arm-none-eabi/9.2.1/thumb/v6-m/nofp/libgcc.a

00000000 <__aeabi_ldivmod>:
   0:   2b00        cmp r3, #0
   2:   d115        bne.n   30 <__aeabi_ldivmod+0x30>
   4:   2a00        cmp r2, #0
   6:   d113        bne.n   30 <__aeabi_ldivmod+0x30>
   8:   2900        cmp r1, #0
   ...

Theses are valid Cortex-M0+ op-codes.

Best Regards,

Pierre Molinaro

earlephilhower commented 2 years ago

Yes, I think I may have the wrong softFP linked in. However, this is a non-issue for the core as there are ROM routines that run significantly faster (because they're in ROM so no flash XIP delay and they've been hand optimized to use special purpose HW like the HW divide unit). The pico-sdk has a shim file in it. You might be able to get away using only that (it's still bare metal since the ROM is already there...).

OTW, if you have any pointers on GCC build configs to get it to choose the right one for M0+ then I'd be happy to incorporate them!

earlephilhower commented 2 years ago

Looks like I need to add a --with-mode=thumb to the configures. I'll give that a try and see what I can see. Maybe some other cou flags....https://www.linkedin.com/pulse/cross-compiling-gcc-toolchain-arm-cortex-m-processors-ijaz-ahmad/

pierremolinaro commented 2 years ago

Hello,

Yes, I agree. I have also found some other settings in https://www.linkedin.com/pulse/cross-compiling-gcc-toolchain-arm-cortex-m-processors-ijaz-ahmad https://www.linkedin.com/pulse/cross-compiling-gcc-toolchain-arm-cortex-m-processors-ijaz-ahmad : configure += —with-cpu=cortex-m0 configure += —with-no-thumb-interwork configure += —with-mode=thumb

I try to recompile with these new settings.

Best Regards,

Pierre Molinaro

Le 1 juin 2022 à 11:47, Earle F. Philhower, III @.***> a écrit :

Looks like I need to add a --with-mode=thumb to the configures. I'll give that a try and see what I can see.

— Reply to this email directly, view it on GitHub https://github.com/earlephilhower/pico-quick-toolchain/issues/10#issuecomment-1143377881, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEWKZVHA2OWBCC7LTNBB5JTVM4WUXANCNFSM5XG2R4DA. You are receiving this because you authored the thread.

pierremolinaro commented 2 years ago

Hello,

I think that adding --with-cpu=cortex-m0plus to configure builds gcc and its librairies for Cortex-M0+. I think --with-no-thumb-interwork is also useful, but I am not sure. --with-mode=thumb makes -mthumb GCC command line option implicit, it can be omitted. I have deleted --enable-multilib, I think it is useless.

I have also modified CONFIGURENEWLIBCOM as following, not sure it is required:

CONFIGURENEWLIBCOM += --with-cpu=cortex-m0plus
CONFIGURENEWLIBCOM += --with-no-thumb-interwork
#CONFIGURENEWLIBCOM += --with-mode=thumb
#CONFIGURENEWLIBCOM += --enable-multilib

The .stage.LINUX.done works until it fails on .stage.LINUX.libstdcpp-nox: lib/libstdc++.a is not built anymore (I think this file in distribution is not valid for the Cortex-M0+), so I have changed the path to lib/thumb/libstdc++.a.

Now, building .stage.LINUX.done succeeds.

I have copied the new thumb/libgcc.a into the distribution, and now my blink led code works.

I attach the modified Makefile. Makefile.txt

Best Regards,

Pierre Molinaro

earlephilhower commented 2 years ago

Thanks again!