.ARM.exidx section question

Status
Not open for further replies.

john_c_kennedy

Active member
I'm using MCUXpresso for Teensy 4.1 so you guys might not be able to help with this question. But I'm modifying the linker script to link part of the code to run in ITCM RAM and I get an error with the .ARM.exidx section which is located in FLASH:
- There is a separate .ARM.exidx section created by the compiler which contains entries that refer to addresses in the code. I understand this is an ARM requirement?

- 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.

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: 0x6000_0000 Offset: 0x6000_0000

The linker produces a relocation error indicating the offset is to great to fit in the .ARM.exidx entry.
If parts of the code are placed in RAM at address 0x2020_0000 then no problem the offset is within range.

How does Teensyduino get around this problem, although I don't see the .arm.exidx section explicitly listed in the Teensy4.1 linker script?
Thanks, John
 
Thanks Paul, so you put the .ARM.exidx section in ITCM also. My version of the Teensy4.1 linker script doesn't have that so it must be old?
Thanks again,
John
 
Thanks Paul, so you put the .ARM.exidx section in ITCM also. My version of the Teensy4.1 linker script doesn't have that so it must be old?
The .ARM.exidx section was added just 25 days ago, it's not yet included in the latest official release of Teensyduino.

I ran into the same problem a couple of weeks ago, trying to copy the section from the Teensy 3 linker scripts, finding that the offsets are too large, etc. only to find Paul had just fixed it on GitHub :D

One question I couldn't find an answer to is whether the .ARM.exidx section is actually required, since all C++ code seems to be compiled with -fno-exceptions anyway.
From the ARM Exception Handling ABI:
4.4.1 Sections
An object producer must generate:
- One fragment of index table for each code section.
- One exception-handling table entry corresponding to each function that may need to be unwound.

Each fragment of index table (read-only data) must be generated in its own ELF section. It must contain an index
entry for each non-leaf function in the associated code section, in the same order as that of the functions in the
code section. The index table section name must be .ARM.exidx optionally followed by further characters. The
section type must be SHT_ARM_EXIDX (see [AAELF]). It must have the SHF_LINK_ORDER flag set in the sh_flags
field of its section header and be linked to its associated code section via the sh_link field of its section header.
An object producer may generate exception-handling table entries (read-only data) in one ELF section, or one
section per function. The name of a section containing an exception table fragment must be .ARM.extab
optionally followed by further characters. The section type must be SHT_PROGBITS.

Note Tables are not required for ABI compliance at the C/Assembler level but are required for C++.
It's unclear to me whether the "note" at the bottom applies to only the exception table or both the index table and the exception table.

I found that setting __exidx_start = 0; __exidx_end = 0; in the linker script also worked, with no changes in memory usage (in a program with std::vector and std:: ostream usage).

Pieter
 
The .ARM.exidx section was added just 25 days ago, it's not yet included in the latest official release of Teensyduino.

It is on my machine which has the currently released Teensyduino (1.53) which was released on July 1st.
 
You're right, I didn't double-check my version, I meant 1.52, 1.53 does indeed seem to include the change.
 
Thanks Pieter, I'm using C++ and I've tried -fno-exceptions but it doesn't help. But as I mentioned I'm using NXP's MCUXpresso not Teensyduino. And MCUXpresso has a managed linker script mechanism which uses FreeMarker template engine to build the linker script. It is quite flexible and the default templates can be overridden by the user. But it adds another layer of complexity to creating the linker script which doesn't help. However, when I move the .ARM.exidx section to ITCM with most of the other code, I still get link errors for the startup code which is in FLASH, same problem with the offsets being to big. I'm not sure why this occurs because although the startup code is a .cpp file it's pretty much just ordinary C code, nothing special? I'll try your suggestion of setting __exidx_start = 0; __exidx_end = 0; in the linker script.
John
 
I finally got this to link, I changed the startup file extension to .c rather than .cpp, linked the .ARM.extab and .ARM.exidx sections to ITCM with most of the other code and it linked without errors. For some reason this won't link if the startup file has a .cpp extension? I'm guessing the C++ compiler adds entries to the .ARM.exidx table even though the code doesn't generate any C++ exceptions? I haven't tested this yet as I'm waiting for my Teensy4.1 boards to arrive, and all the other Teensy4.1 boards I have are otherwise occupied on other projects.
John
 
For some reason this won't link if the startup file has a .cpp extension?

C code is generating entry points as is, while cpp modifies function names to contain also type of parameters and return value.
So all code that e.g. is called from assembler, should be c-code or (I think) be declared as static.
BTW this is also valid for ISR
 
One question I couldn't find an answer to is whether the .ARM.exidx section is actually required, since all C++ code seems to be compiled with -fno-exceptions anyway.

I have this question too. Please let me know if you find a definitive answer?


I'm guessing the C++ compiler adds entries to the .ARM.exidx table even though the code doesn't generate any C++ exceptions?

That seems like a pretty good guess.

The changes that went into version 1.53 were meant to make C++ STL "just work", but the truth is (so far) not much effort has gone into really investigating whether this data really is necessary or a way to do without it.

We'll probably attempt a toolchain update later this year. Digging into this for the old toolchain we're currently using hardly seems like a good use of limited dev time.
 
I have this question too. Please let me know if you find a definitive answer?
Can it be that some of the binary linked in standard libraries were compiled without -fno-exceptions?
 
Status
Not open for further replies.
Back
Top