Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linker script bug, generating invalid ELF files that confuse binutils #1538

Closed
mvds00 opened this issue Nov 8, 2023 · 2 comments
Closed
Milestone

Comments

@mvds00
Copy link
Contributor

mvds00 commented Nov 8, 2023

Due to the order of sections in the linker script, an ELF is generated with a strange layout, that confuses objcopy. This is easily solved by rearranging these sections.

Normally, objcopy is not used on ELF files within the pico-sdk, but there are cases where it is, such as when using the picowota firmware loader.

A pull request will follow.

@mvds00
Copy link
Contributor Author

mvds00 commented Nov 16, 2023

Some additional investigation led to the conclusion that the linker script contains a bug. The sections loaded to RAM are specified as follows:

.ram_vector_table (NOLOAD) { ... } > RAM
.data { ... } > RAM AT> FLASH
.uninitialized_data (NOLOAD) { ... } > RAM 

The documentation of ld states:

If neither AT nor AT> is specified for an allocatable section, the linker will use the following heuristic to determine the load address:

• If the section has a specific VMA address, then this is used as the LMA address as well.
• If the section is not allocatable then its LMA is set to its VMA.
Otherwise if a memory region can be found that is compatible with the current section, and this region contains at least one section, then the LMA is set so the difference between the VMA and LMA is the same as the difference between the VMA and LMA of the last section in the located region.
• If no memory regions have been declared then a default region that covers the entire address space is used in the previous step.
• If no suitable region could be found, or there was no previous section then the LMA is set equal to the VMA.

Bullet 3 leads to an implied AT> FLASH added to .uninitialized_data, which is incompatible with the attribute NOLOAD. This is casually verified by adding AT> FLASH explicitly and observing that the output is identical.

The generated ELF will contain two issues:

  • an additional RAM segment that overlaps with the default RAM region of bullet 4
  • a section .uninitialized_data with LMA != VMA with no loadable data

The overlapping segments trigger all kinds of issues in binutils (one issue in binutils is that the ELF_SECTION_IN_SEGMENT macro in binutils/include/elf/internal.h, applied to the offending section, returns true for more than one segment) and the offending section will mess up the segment it is loaded in, triggering addition of a strange offset to memsz (in binutils, a line bfd_vma adjust = s_start - p_end; in elf.c:assign_file_positions_for_load_sections()).

@mvds00 mvds00 changed the title Generated ELF files contain strange section that confuses objcopy Linker script bug, generating invalid ELF files that confuse binutils Nov 16, 2023
@kilograham kilograham modified the milestones: 1.6.0, 2.0 Dec 14, 2023
@kilograham kilograham modified the milestones: 2.0, 1.5.2 Jan 12, 2024
@kilograham
Copy link
Contributor

merged into develop

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants