ARM-software / LLVM-embedded-toolchain-for-Arm

A project dedicated to building LLVM toolchain for Arm and AArch64 embedded targets.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Error when linking with some assembly files

zxtxin opened this issue · comments

I compiled this two assembly file
05a35c16359c84b563df49b4f02122c8_
5587cd33291f6a8fe01b804799b87568_
with the following parameters
'-std=c11 --config armv6m_soft_nofp_nosys.cfg -mno-unaligned-access -fshort-enums -fshort-wchar -g -ffunction-sections -fdata-sections -faapcs-bitfield-width -fno-common -Wall -Os'

But the linker report errors
bf7419d874cc828b58a36fa95690d096_
with the following parameters
--config armv6m_soft_nofp_nosys.cfg -T /home/wsl/ls_sdk/soc/arm_cm/le501x/compiler/gnu/ble.ld -Wl,--gc-sections

This looks like it should be simple to fix. LLD doesn't implement the R_ARM_THM_JUMP8 relocation. I'm a little surprised that the assembler generated the relocation as arm_cm_delay_asm is in the same section. If you need a work-around in the mean-time then I suggest a local symbol at the same offset as arm_cm_delay_asm as that will cause the assembler to resolve the relocation.

Hoping to get some time to send a patch to upstream lld to implement the missing relocation soon.

Looks like this has already been fixed upstream in https://reviews.llvm.org/D113509 but this isn't in LLD 13.0.0. The 14.0.0 release will include this relocation.

Great, thank you for the update!

This means that building the toolchain manually with HEAD (https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/blob/main/docs/building-from-source.md) should have the fix.

I've tested release 14.0.
It still does not work. But the error log becomes
image

The first couple of errors are symptomatic of missing the SHF_ALLOC flag in a section containing code. A section without SHF_ALLOC is not part of the memory that will be seen at run-time, they are used for metadata such as .debug. GNU ld is not as fussy as LLD about this.

The fix for this is to make sure the "ax" flags are included when making a custom ELF section in assembler. For example,

 .section mysection, "ax", %progbits

Link to GCC .section docs https://sourceware.org/binutils/docs/as/Section.html

The last error message is likely to come from something like:

        .text
        .global foo 
        beq foo // conditional branch outside section

On most AArch32 Arm CPUs the branch will be a wide branch, but on Cortex-M0 the only relocation is the very short range narrow conditional branch (with the R_ARM_THM_JUMP8) relocation

If foo is too far away from the conditional branch then the linker will give an error message. It looks like the destination is too far in your case. Given the short range of the conditional branch it is not usually practical to use it outside of a section. I suggest replacing it with something like:

       .text
        .global foo
        bne  skip // If not equal to then skip
        b foo  // unconditional branch to foo with long range
skip:
        ...

The first couple of errors are symptomatic of missing the SHF_ALLOC flag in a section containing code. A section without SHF_ALLOC is not part of the memory that will be seen at run-time, they are used for metadata such as .debug. GNU ld is not as fussy as LLD about this.

The fix for this is to make sure the "ax" flags are included when making a custom ELF section in assembler. For example,

 .section mysection, "ax", %progbits

Link to GCC .section docs https://sourceware.org/binutils/docs/as/Section.html

The last error message is likely to come from something like:

        .text
        .global foo 
        beq foo // conditional branch outside section

On most AArch32 Arm CPUs the branch will be a wide branch, but on Cortex-M0 the only relocation is the very short range narrow conditional branch (with the R_ARM_THM_JUMP8) relocation

If foo is too far away from the conditional branch then the linker will give an error message. It looks like the destination is too far in your case. Given the short range of the conditional branch it is not usually practical to use it outside of a section. I suggest replacing it with something like:

       .text
        .global foo
        bne  skip // If not equal to then skip
        b foo  // unconditional branch to foo with long range
skip:
        ...

Thank you.
When I add "ax" flags, all error logs disappear.
Is there any document about the difference between lld and GNU ld?

Unfortunately there isn't a lot. Most of the differences that are documented are in https://github.com/llvm/llvm-project/tree/main/lld/docs/ELF mostly in the linker_script.rst area.

The issue seems to be resolved and 14.0.0 release binaries with the LLD fix available https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases/tag/release-14.0.0 so I am closing.