简体   繁体   中英

Linker relocation truncated to fit: R_ARM_THM_JUMP11 error and gcc output too big

I'm an embedded programmer since 4 years now. I've been working with microchip PICs and ST STM32 all this time but I've never done real bare-metal programming as I've always used Microchip code configuration or ST CubeMX to do the work for me.

However, as someone interested in this field, I wanted to try to do some bare-metal programming on a NUCLEO-F072RB, to understand how the compiler knows where to put each bit of program, for example.

As a tutorial, I followed this blog https://vivonomicon.com/2018/04/02/bare-metal-stm32-programming-part-1-hello-arm/ and made the necessary modifications to fit my hardware.

After getting a little bit more confident and starting my own "HAL" implementation of the GPIO peripheral driver, I rapidly came into the linker error:

startup_stm32f072rb.o: in function reset_bss_loop: (.text.default_interrupt_handler+0x2c): relocation truncated to fit: R_ARM_THM_JUMP11 against symbol `main' defined in.text section in main.o

I've made research around this type of errors and, as I understand it, it seems that the compiler is telling to the linker that there is a symbol named main in the startup_STM32... file and that the same symbol is also in the main file. However the linker tells that the addresses of those two symbols does not match or there is one that must be outside of the maximum address of memory.

After playing a bit to try to debug this, I had the idea of increasing the optimisation level. And it worked, with the same source code.

So now, I assume that the problem is coming from the way I compile and link that is producing executable too big for my hardware. But I don't really understand how this can be possible considering the relative small size of my project.

So, my real question is: how can I understand what is going on here? And is there a way to compile the same source code without using -O1? It does not seem to be the right solution to me (just a trick to mask an underlying problem).

The source code I'm using is located here https://github.com/FlorianRemy/bare_metal_part3 . There is pieces of code (startup, makefile and linker script) almost copied from the tutorial and the macro definitions for register manipulation (in misc_definition.h) are coming from a teacher.

Edit

As mentioned in the accepted answer, the problem is coming from the B (ranch) instruction, which is not wide enough to address where the main label is. However, the BW instruction is not supported by cortex-m0 architecture. According to the STM32F072 programming manual (page 59 and 60), the correct instruction to use in this case seems to be BL , which resolved my problem.

The problem is coming from your startup code. As the linker error is telling you, there's a problem at the end of your reset vector where you "call" main (really just branch to it); namely that the branch instruction you are using to branch to main doesn't have enough bits in it's label field to fit the needed offset to where the linker ended up putting main .

So, it's not really a hardware limitation but instead a limitation of the instruction you used ( B main ) since in ARM Thumb16, the distance you can branch is quite limited. The reason optimizing the code helps is that now the code is overall smaller (as was the case when you had less code overall) so the distance in flash between the start of main and the branch at the end of your reset vector was small enough to work with the Thumb16 version of branch. You are correct that you're just masking the problem, and as you progress further and add more code, the problem could reemerge even with optimizations in your compilation.

To fix the problem, try forcing the assembler to use the 32bit encoding for the branch instruction so you have a wider range of offsets, thus can always reach main from your branch instruction:

B.W main /* instead of B main at the end of reset_handler */

Edit:

As mentioned, since this instruction set does not support BW , using BL instead results in the wider range needed for the branch

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM