Skip to content

[LinkerScript] Fix orphan section placement with scripts#1438

Open
quic-areg wants to merge 1 commit into
qualcomm:mainfrom
quic-areg:fix-orphan-placement-before-init
Open

[LinkerScript] Fix orphan section placement with scripts#1438
quic-areg wants to merge 1 commit into
qualcomm:mainfrom
quic-areg:fix-orphan-placement-before-init

Conversation

@quic-areg

Copy link
Copy Markdown
Contributor

Orphan insertion scan stopped at the first section with a greater rank than the orphan, placing the orphan before that section. This groups sections with like permissions together when the script is sorted by rank, but when a
script declares a lower ranked section first, the scan can insert a higher ranked orphan too early:

  SECTIONS {
      .init : { KEEP((.data.init.enter)) }  /* WA (picolibc) */
      .text : { (.text) }                   /* AX */
  }

Note: AX/.text has a lower rank than WA/.init.

A third (orphan) section orphan_code (AX) is placed before .init, the first section with a higher rank, but .init is expected to come first. lld/bfd instead group the orphan with its like ranked neighbor (.text) rather
than taking eld's single pass insertion shortcut, so the orphan lands after .text and .init keeps its place.

Scan the whole list and insert after the last section with rank <= the orphan's. For scripts sorted by rank, this is equivalent. The no linker script path is unchanged.

Also update Hexagon TrampolineMissingSymbol: the fix moved its orphaned .init next to .txt.foo, removing the long call. Add an explicit .init rule to restore the call distance and check that the expected trampoline is
emitted.

Fixes #1408

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we change and assign SHO_INIT rank to the init section instead ?

Comment thread lib/Target/GNULDBackend.cpp

@parth-07 Parth (parth-07) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

As a follow-up, it would be nice to formally document the orphan placement algorithm used by eld.

@quic-areg quic-areg added the zephyr-check Run Zephyr build/check workflow on this PR label Jul 13, 2026
Orphan insertion scan stopped at the first section with a greater
rank than the orphan, placing the orphan before that section. This groups
sections with like permissions together when the script is sorted by
rank, but when a script declares a lower ranked section first, the scan can
insert a higher ranked orphan too early:

script:

  SECTIONS {
      .init : { KEEP(*(.data.init.enter)) }  /* WA (picolibc) */
      .text : { *(.text) }                   /* AX */
  }

Note: AX/.text has a lower rank than WA/.init.

A third (orphan) section orphan_code (AX) is placed before .init, the
first section with a higher rank, but .init is expected to come first.
lld/bfd instead group the orphan with its like ranked neighbor (.text)
rather than taking eld's single pass insertion shortcut, so the orphan
lands after .text and .init keeps its place.

Scan the whole list and insert after the last section with rank <= the
orphan's. For scripts sorted by rank, this is equivalent. The no linker
script path is unchanged.

Also update Hexagon TrampolineMissingSymbol: the fix moved its orphaned
.init next to .txt.foo, removing the long call. Add an explicit .init
rule to restore the call distance and check that the expected trampoline
is emitted.

Fixes qualcomm#1408

Signed-off-by: quic-areg <aregmi@qti.qualcomm.com>
@bojle

Copy link
Copy Markdown

LGTM. This PR fixes the issue I am seeing. See #1194 (comment).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

zephyr-check Run Zephyr build/check workflow on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Executable orphan placed ahead of .init when .init contains data-flagged input

5 participants