LINK ERROR: relocation truncated to fit: R_RISCV_JAL against symbol

Toolchain Version: riscv-none-embed-gcc-xpack v8.3.0-2.3, where the individual components’ versions are as follows:

      if [[ "${RELEASE_VERSION}" =~ 8\.3\.0-2\.[1] ]]




I got the following linkage errors with -O0 -ggdb options, while it’s okay with -Os and without -ggdb option.

build/kernel/libcpu/risc-v/k210/startup_gcc.o: in function `.L0 ':
/home/remember/my_work/k210-openmv_release/src/rt-thread/libcpu/risc-v/k210/startup_gcc.S:125:(.start+0x134): relocation truncated to fit: R_RISCV_JAL against symbol `secondary_cpu_c_start' defined in .text.secondary_cpu_c_start section in build/kernel/libcpu/risc-v/k210/cpuport_smp.o
build/kernel/libcpu/risc-v/common/context_gcc.o: in function `.L0 ':
/home/remember/my_work/k210-openmv_release/src/rt-thread/libcpu/risc-v/common/context_gcc.S:50:(.text+0x12): relocation truncated to fit: R_RISCV_JAL against symbol `rt_cpus_lock_status_restore' defined in .text.rt_cpus_lock_status_restore section in build/kernel/src/cpu.o
build/kernel/libcpu/risc-v/k210/interrupt_gcc.o: in function `.L0 ':
/home/remember/my_work/k210-openmv_release/src/rt-thread/libcpu/risc-v/k210/interrupt_gcc.S:77:(.text.entry+0x7c): relocation truncated to fit: R_RISCV_JAL against symbol `rt_hw_context_switch_exit' defined in .text section in build/kernel/libcpu/risc-v/common/context_gcc.o
collect2: error: ld returned 1 exit status
scons: *** [rtthread.elf] Error 1
scons: building terminated because of errors.

gcc-8.3 is 2 years old. I would suggest trying a newer toolchain. We aren’t maintaining gcc-8.3 anymore, only the current gcc-10.2. That is also a third party toolchain that you are using. You might have to report the bug to them.

I can’t do anything useful without a testcase to reproduce. However, this might be a binutils bug fixed about a year ago

The source files (which we aren’t given a reference to) are .S. Maybe they just have bare JAL.

Yes, there are jal instruction, j pseudoinstruction or conditional branch instruction in these .S files in the following links… Also, there errors generate after I add some new code package into my whole project. Before that it can be built correctly even with -ggdb -O0 options.

Do these errors mean that the targets of these instructions are beyond the address range they can access? And when options -Os is used, the size of the code is optimized to a smaller one so that those targets fall into the address range of those instructions again? If so, how should I fix it?

Sorry I cannot provide a complete testcase now.

The normal way to call a function is to use an auipc/jalr pair. The auipc loads the upper 20-bits, and the jalr loads the lower 12-bits. There is a call macro that expands to this sequence. And also a tail macro for tail calls.

jal by itself gives you only 20 bits, which means a +/-1MB range. If your final program is over 1MB then you can have out-of-range branches.

We don’t have linker support to fix out-of-range branches. We do have linker support to relax branches, so if you use auipc/jalr and it is in range of jal, then the linker will do the conversion if you used the call macro and you have relaxation enabled. So use of auipc/jalr via the call macro is the recommend way to write assembly code.


That helps me a lot and solves my problem. Thank you very much.