what is and what does mcux-fixelf

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

what is and what does mcux-fixelf

2,459 Views
mastupristi
Senior Contributor I

Hi,

I use RT1175 and when I have tried multicore example I have seen that mcux-fixelf tool is called.

I wonder:

  • what is mcux-fixelf?
  • what is it used for?
  • What does it do in detail?
  • Where can I find the source code for mcux-fixelf?
  • if I wanted to do the same work as mcux-fixelf “by hand” using only tools from the toolchain and those from the linux command line (such as cat, tail, dd, etc.) how should I do it?

In our project is a very bad behavior to change the alignment of every section to 1. How to keep alignment of the original sections?

best regards

 

0 Kudos
Reply
7 Replies

2,398 Views
Harry_Zhang
NXP Employee
NXP Employee

Hi @mastupristi 

1. What is mcux-fixelf?
mcux-fixelf  primarily used to prepare ELF files for flashing and debugging. It's part of the MCUXpresso IDE toolchain.

2. What is it used for?
It's primarily used to:

Adjust section alignments: Ensure that sections in the ELF file are aligned to specific memory boundaries required by the target MCU.
Add symbols: Add symbols that might be missing from the ELF file, which are essential for debugging and analysis.
Modify other ELF attributes: Make changes to the ELF file's attributes, such as the entry point or the stack size.

3. What does mcux-fixelf do in detail?
In detail, mcux-fixelf performs the following tasks:
Section Alignment: The tool may alter section alignments to ensure that the memory layout complies with the requirements for multicore execution. This could involve aligning sections to specific boundaries that correspond to the memory regions for each core.
Memory Mapping Adjustments: It adjusts the memory mapping for the different cores to ensure that each core’s code and data reside in their designated memory areas without overlap.
Combining Binaries: If the cores are compiled separately, mcux-fixelf might combine their outputs into a single ELF file or properly manage the memory layout to ensure each core has its code/data in the correct location.
Header Modifications: It might also modify ELF headers to correctly reflect the memory layout or entry points for each core.

BR

Hang

0 Kudos
Reply

2,338 Views
mastupristi
Senior Contributor I

Hi @Harry_Zhang 

I want to add some information to my previous post.

I took the erpc_matrix_multiply_mu example from the SDK.
I tried and run objdump and readelf before and after running mcux-fixelf.

output of 'objdump -x', on the left before, and on the right after executing mcux-fixelf:

mastupristi_0-1726817774999.png

output of 'readelf -a', on the left before, and on the right after executing mcux-fixelf:

mastupristi_1-1726817944829.png

 

I see these differences:

  1. EXEC_P flag is removed
  2. type become NONE instead of EXEC
  3. alignment of every section is set to 1
  4. symbol table address are offsets of 0x20000000 (I don't know if this is a consequence of some other action)
  5. type of .core_m4slave.ARM.exidx section changed from ARM_EXIDX to PROGBITS
  6. flags of .core_m4slave.ARM.exidx section changed from AL to A
  7. removed unwind sections

For each individual item on this list I need to answer the following questions:

  1. why to do it?
  2. what problem should it solve?
  3. Is it strictly required or optional?
  4. How to do this using linux command line tools and those provided by the toolchain?

 

I wonder if point 5, 6 and 7 are applied only to .core_m4slave.ARM.exidx or all section with similar attributes.

in conclusion, the questions from the previous post, which I report here, also remain open:

  1. Where can I find the source code for mcux-fixelf?
  2. if I wanted to do the same work as mcux-fixelf “by hand” using only tools from the toolchain and those from the linux command line (such as cat, tail, dd, etc.) how should I do it?

regards

Max

0 Kudos
Reply

2,206 Views
cristiantepus
NXP Employee
NXP Employee

Hi,

Historically, in IDE, we have a model of the multicore projects that are included in the SDK pack. This consisted into secondary project generating an image for the secondary core, then primary core project links the secondary’s image sections inside its own final image. The first core’s runtime model is then responsible to copy the secondary image to its own space and start execution in order to allow the second core to boot and execute.

 

Now, coming back to the multicore image construction, along the path some limitations or feature updates in the toolchain prevented the initial above mentioned approach and some “tweaks” were required to still keep this example’s model:

  • Linker updated some years ago its input file linking model in a way that executables were no longer allowed to be directly referred as “input files” for linking stage (see https://sourceware.org/bugzilla/show_bug.cgi?id=26047). At that time, the easiest workaround was to remove the executable flag to allow secondary image to still be seen as an object file. Initially, this was done using dd utility (if I trace this back correctly was done using dd if=/dev/zero of=<obj_file> bs=1 seek=16 conv=notrunc count=2)

 

  • Meanwhile, another limitation occurred, seen in particular applications, the exidx sections appeared to be internally optimized (linker relaxation message in logs – so its final size when importing secondary image into primary image being 0) so their content finally being discarded – a side effect was that sections located after this one were left shifted in final image to fulfill the space gap, obviously leading to runtime exception. Initially “--no-relax” was tried but with no effect. Actually, what happens, in the case of executable objects the linker will merge all input exidx sections into one. All input entries are sorted by ascending VMA, while consecutive "can't unwind" markers are coalesced in order to minimize the size of the final exidx section. After the table is constructed, all input exidx sections are discarded. This is misleadingly reflected in the map file as a relax optimization (this is a byproduct of keeping the exidx section consistent with ehabi standard). This finally results in a shift of the VMA layout for sections placed after secondary exidx by 8 bytes.

So the solution(s) here: make exidx sections (from second core) plain sections plus remove alignment constraints (make them 1) in order to avoid further linker section (re)placement decisions when constructing the final image. These were decided to be easier to be implemented in a c code / separate executable so the first bullet change was also moved here.

 

PS. As we didn’t intend to provide the source externally up to now, please allow us some time to make it externally available. We plan to delivery it in the next IDE, end of this month (end of this week). We'll keep you posted when available.

 

Regards,

Cristian

0 Kudos
Reply

2,032 Views
cristiantepus
NXP Employee
NXP Employee

Hi,

IDE 24.9 was just released. This contains <layout>/ide/binaries/mcux-fixelf.c as the source for mcux-fixelf executable file.

 

Regards,

Cristian

0 Kudos
Reply

2,283 Views
Harry_Zhang
NXP Employee
NXP Employee

Hi @mastupristi 

1. EXEC_P Flag Removed:
• Why to do it?: The EXEC_P flag indicates that the section is executable. This flag is likely removed because the section no longer needs to be executable, possibly due to a change in how the application or a specific section of code (like .core_m4slave) is handled.
• How to do this?: You can use objcopy to modify section flags:
objcopy --set-section-flags <section_name>=contents,alloc,data <input_file> <output_file>

2. Type Becomes NONE Instead of EXEC:
• Why to do it?: Changing the type to NONE indicates that this is no longer a loadable segment intended for execution.
• How to do this?: You may need to adjust the ELF headers using a combination of tools, such as objcopy or ld, to modify segment types.
3. Alignment of Every Section Set to 1:
• Why to do it?: Aligning sections to 1 may be necessary for certain memory configurations where strict alignment isn’t required or could cause issues (like running on different cores with different memory constraints).
• How to do this?: You can set section alignment using objcopy:
objcopy --adjust-section-vma <section_name>=0x<address> --set-section-flags <section_name>=contents,alloc <input_file> <output_file>

4. Symbol Table Addresses Are Offsets of 0x20000000:
• Why to do it?: This could be due to remapping the symbol table to match the physical memory address of where the symbols will actually be loaded or used.
• How to do this?: This might be handled internally by the linker script or can be adjusted using objcopy to change symbol addresses.
5. Type of .core_m4slave.ARM.exidx Changed from ARM_EXIDX to PROGBITS:
• Why to do it?: The .ARM.exidx section typically contains exception handling tables for ARM, but if these are not required, changing to PROGBITS allows it to be treated as regular data.
• How to do this?: This change usually happens in the linker script or might require manual header editing.
6. Flags of .core_m4slave.ARM.exidx Changed from AL to A:
• Why to do it?: The AL (allocatable and loadable) flag might not be necessary if the section is changed to non-executable data, hence reducing to A (allocatable).
• How to do this?: Use objcopy to adjust section flags:
objcopy --set-section-flags .core_m4slave.ARM.exidx=alloc <input_file> <output_file>

7. Removed Unwind Sections:
• Why to do it?: Unwind sections are used for stack unwinding during exceptions. If this is not needed (e.g., the target core doesn’t use exceptions), these sections can be removed to save space.
• How to do this?: You can strip specific sections using objcopy:
objcopy --remove-section=<section_name> <input_file> <output_file>

General Questions:
1. Source Code for mcux-fixelf:
• The source code for mcux-fixelf is typically not provided by NXP. However, I need to confirm internally whether the code can be provided.
2. Replicating mcux-fixelf with Command Line Tools:
• To replicate the functionality of mcux-fixelf, you would need a deep understanding of ELF headers and potentially create custom scripts using objdump, objcopy, readelf, and manual hex editing. Specific commands and operations would depend on exactly what mcux-fixelf modifies, as outlined above.

BR

Hang

0 Kudos
Reply

2,246 Views
mastupristi
Senior Contributor I

Hi @Harry_Zhang 

The EXEC_P flag indicates that the section is executable

EXEC_P is a flag that is part of the e_type field of the Elf32_Ehdr structure (the “real” name is ET_EXEC). So you're wrong to say it's a section-related flag!

The same thing applies to NONE

mastupristi_0-1727077299067.png

Aligning sections to 1 may be necessary for certain memory configurations where strict alignment isn’t required or could cause issues (like running on different cores with different memory constraints).

As I have said this before, this behavior harms us.

I wrote a post here.

Removed Unwind Sections:
• Why to do it?: Unwind sections are used for stack unwinding during exceptions. If this is not needed (e.g., the target core doesn’t use exceptions), these sections can be removed to save space.
• How to do this?: You can strip specific sections using objcopy:
objcopy --remove-section=<section_name> <input_file> <output_file>

mastupristi_1-1727078993307.png

Are you sure about this? The section listed is .core_m4slave.ARM.exidx, which I understand is still in the file processed by mcux_fixelf.

The source code for mcux-fixelf is typically not provided by NXP. However, I need to confirm internally whether the code can be provided.

This is really bad news for us. It's also unwarranted, by the way, because given what you're telling me, there shouldn't be any secrets to protect.

 

To replicate the functionality of mcux-fixelf, you would need a deep understanding of ELF headers and potentially create custom scripts using objdump, objcopy, readelf, and manual hex editing. Specific commands and operations would depend on exactly what mcux-fixelf modifies, as outlined above.

It's quite interesting—you mention that I should be thoroughly familiar with the ELF format to accomplish certain tasks. Ironically, it seems like you might be the one who could use a deeper understanding of it. But perhaps I'm mistaken; surely, anyone contributing to this forum couldn't possibly lack such knowledge, right? Maybe you just had a brief moment of distraction or a slip of the mind.

After all, we all have those days when the basics momentarily escape us!

regards

Max

0 Kudos
Reply

2,377 Views
mastupristi
Senior Contributor I

Hi @Harry_Zhang 

about aligning, it seems wrong to me what mcux-fixelf does.
In fact, in my scenario, it can't work.

on CM4 there will be an RTOS (maybe Zephyr) with USP stack and IP, on which a PTPv2 client will have to run. The code alone for these components is probably larger than the 128KB of ITC dedicated to CM4. But in your scenario in ITC there must also fit .data* that have, precisely, LMA in ITC.

One solution for this is to have CM7 populate all of CM4's memories, which will then no longer need to do so in startup.
To do this, though, the CM7 linker needs to know the alignment of the various sections. but this can't happen if mcux-fixelf changes it for all sections by putting it to 1.
Isn't it possible to avoid this with some parameter?

You also didn't answer perhaps the two most interesting questions:

  1. Where can I find the source code for mcux-fixelf?
  2. if I wanted to do the same work as mcux-fixelf “by hand” using only tools from the toolchain and those from the linux command line (such as cat, tail, dd, etc.) how should I do it?

 

best regards

 

 

0 Kudos
Reply