RT1064: How to solve gcc linker error (.ARM.exidx+0x0): relocation truncated to fit: R_ARM_PREL31

cancel
Showing results for 
Search instead for 
Did you mean: 

RT1064: How to solve gcc linker error (.ARM.exidx+0x0): relocation truncated to fit: R_ARM_PREL31

1,197 Views
udoeb
Contributor I

Hi,

According to my understanding this linker error occurs because of the following requirements from the ARM ABI standard:

- There is a separate .ARM.exidx section created by the compiler which contains entries that refer to addresses in the code.

- Each entry in .ARM.exidx contains a 31 bit signed integer to express the offset where the code resides. One bit is used for other purposes (to indicate the type of the entry). So the maximum offset that can be stored in an entry is 0x3FFF_FFFF.

- There is exactly one .ARM.exidx section in an image.

- The .ARM.exidx section is used for C++ exception handling but also for C code. Using compiler option -fno-exceptions does not solve the problem. In my specific case the entries in .ARM.exidx are created by assembler code in irq_cm4f.o (CMSIS RTOS) and C code in libgcc.a(_udivmoddi4.o).

If parts of the code are placed in ITCM (which is the whole purpose of ITCM) then the following problem occurs:

ITCM address: 0x0000_0000

FLASH address: 0x7000_0000  Offset: 0x7000_0000

The linker produces the above error message.

For RT1052 I was able to work around this by placing .ARM.exidx in OCRAM:

ITCM address: 0x0000_0000

OCRAM address: 0x2020_0000  Offset: 0x2020_0000

FLASH address: 0x6000_0000  Offset: 0x3FE_00000

For RT1064 this approach does not work because the internal FLASH resides at 0x7000_0000:

ITCM address: 0x0000_0000

OCRAM address: 0x2020_0000  Offset: 0x2020_0000

FLASH address: 0x7000_0000  Offset: 0x4FE_00000

The linker produces the above error message.

My questions:

1. Is there a solution to this problem at the linker level? For example, is it safe to simply discard the .ARM.exidx section?

2. Is it possible to map the FLASH to a lower address? It occurs to me that choosing such high addresses for the FLASH is a bit unfortunate.

Thanks

Udo

Labels (2)
0 Kudos
4 Replies

907 Views
john_c_kennedy
Contributor I

I'm using the EVKMIMXRT1060. I followed the example for modifying the linker script in the MCUXpresso Users Guide section 17.15.1 for keeping the startup code in flash but moving the bulk of the application code to RAM, specifically in my case SRAM_ITC.  This gives the same link errors because the generated managed linker script puts the .ARM.extab and .ARM.exidx sections in BOARD_FLASH so any offsets to code in SRAM_ITC are greater than 0x3FFF_FFFF.  So I also added a modified exdata.ldt file to my linkscripts folder which links the .ARM.extab and .ARM.exidx sections to SRAM_ITC also.  This compiled and linked without errors.  However, when I try to debug this code I get a hard fault in the startup code when it calls data_init to move the code from BOARD_FLASH to SRAM_ITC?  Also I tried using SRAM_OC instead of SRAM_ITC, this time the debugger actually made it to main in SRAM_OC but at that point it's stuck on the first instruction, never executes beyond that?

NXP should provide additional documentation about this as it seems to be a common problem when linking code in both BOARD_FLASH and SRAM_ITC and there doesn't seem to be any examples of how to do this.  I suggest updating the MCUXpresso Users Guide section 17.15.1 to provide explicit information about this for the MIMXRT1060 family and other NXP MCUs that it may be relevant to.

Note also that adding -fno-exceptions to the complier flags does NOT solve this problem.

0 Kudos

907 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi,

Please refer MCUXpresso SDK for RT1064 release note, which was tested with below version ARM GCC toolchain:

Makefiles support with GNU Tools for Arm Embedded Processors 8-2018q4-major

1> Please try with mentioned GCC ARM Embedded tool chain:

Download and run the installer from launchpad.net/gcc-arm-embedded. This is the actual toolset (in other words, compiler,linker, etc.). The GCC toolchain should correspond to the latest supported version, as described in the MCUXpresso SDK
Release Notes Supporting EVK-MIMXRT1064 (document MCUXSDKMIMXRT1064RN).

2> The onchip Flash address is fixed. 

Please let us know if you still have link issue with  release note suggested GCC ARM tool chain.

Wish it helps.


Have a great day,
Mike

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

907 Views
udoeb
Contributor I

Hi,

I verified that the issue occurs with the latest MCUXpresso v11.0.1 release as well. So it's not related to tool chain version.

Meanwhile I found the root cause. The problem occurs if the following conditions are met:

1. The project contains a .s (assembler language) file which implements functions called from C/C++ code.

2. The functions implemented in assembler use the .fnstart/.fnend directives which create an unwind table entry for the given function. This creates an .ARM.exidx section in the .o file produced from the .s file.

3. The .o file produced from assembler code is placed in ITCM via linker script.

The linker creates a .ARM.exidx output section which is placed in FLASH. But entries in that table cannot refer to the assembler functions in ITCM because the distance exceeds 0x3FFF_FFFF. The linker produces the error

"relocation truncated to fit: R_ARM_PREL31 ...".

I experienced this issue while using CMSIS RTOSv2 which comes with irq_cm4f.s which fulfills conditions 1 and 2 above. Then I tried to place the RTOS kernel in ITCM which adds condition 3.

Possible solutions:

- Remove the .fnstart/.fnend statements from assembler code.

- If the C++ project uses -fno-exceptions then it should be safe to discard .ARM.exidx input sections using a /DISCARD/  output section in the linker script. In this case __exidx_start/__exidx_end markers should still be placed in FLASH somewhere but may refer to an empty range.

Udo

0 Kudos

907 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Udo,

Many thanks for the sharing.

best regards,

Mike

0 Kudos