Skip to content

port(MachO): Align __LINKEDIT sections#2186

Open
joanna-jo wants to merge 2 commits into
wild-linker:mainfrom
joanna-jo:linkedit_align
Open

port(MachO): Align __LINKEDIT sections#2186
joanna-jo wants to merge 2 commits into
wild-linker:mainfrom
joanna-jo:linkedit_align

Conversation

@joanna-jo

Copy link
Copy Markdown

Fixes #2063.

According to dyld (alignments, alignment check) and lld (alignments, code signature alignment), the current __LINKEDIT blobs/“sections” we have are expected to have a minimum alignment of:


STRTAB: 1
CHAINED_FIXUPS: 8
SYMTAB: 8
CODE_SIGNATURE: 16

STRTAB and CODE_SIGNATURE are already correctly aligned, so the alignments were only changed for CHAINED_FIXUPS and SYMTAB. CHAINED_FIXUPS’ size was also aligned upwards to USIZE since OffsetVerifier needs this “section” to have an aligned size (wild: error: Unexpected memory offsets: Part #36 (section DYLD_CHAINED_FIXUPS_TABLE alignment: 8) has non aligned size: 0x4e). This follows what lld does for padding CHAINED_FIXUPS.

I manually checked with dyld_info and otool using misaligned files, and while this fixes the errors for misaligned __LINKEDIT content, there’s another dyld_info error (chained fixups, segment_offset does not match vmaddr from LC_SEGMENT in segment #2) that seems like an off-by-one in how we calculate the index for __DATA_CONST when writing the chained fixup table. I’ve opened a separate issue for that here: #2185.

@joanna-jo joanna-jo marked this pull request as ready for review July 7, 2026 00:41

@davidlattimore davidlattimore left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks! Do you think it's practical to add a test that would catch this bug?

@davidlattimore

Copy link
Copy Markdown
Member

One possible way in which this might be tested is to look at making linker-diff detect that the alignment of these sections is different from what lld emits.

@joanna-jo

Copy link
Copy Markdown
Author

Thanks for looking this over and for the suggestion! :) I was also wondering what the best way to add a regression test here would be - I briefly looked into assertions but I’ll try supporting this directly with linker-diff then!

@marxin

marxin commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Thank you @joanna-jo for the very first contribution! Really appreciate your research part where you investigated what's the expected alignment of the various __LINKEDIT sections.

@joanna-jo

Copy link
Copy Markdown
Author

This is now the linker-diff output before vs. after our fix on a file with misaligned SYMTAB, DYLD_CHAINED_FIXUPS, and CODE_SIGNATURE:

Before:

cargo run --bin linker-diff -- --wild-defaults --only 'linkedit.*' --ref /tmp/t.lld /tmp/t.wild
   Compiling linker-diff v0.9.0 (/Users/joannajo/wild/linker-diff)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.18s
     Running `target/debug/linker-diff --wild-defaults --colour never --only 'linkedit.*' --ref /tmp/t.lld /tmp/t.wild`
wild: /tmp/t.wild
lld: /tmp/t.lld
linkedit.CODE_SIGNATURE.dataoff.alignment
  wild offset 0xc11f is not 16-byte aligned
  lld OK

linkedit.DYLD_CHAINED_FIXUPS.dataoff.alignment
  wild offset 0xc027 is not 8-byte aligned
  lld OK

linkedit.SYMTAB.symoff.alignment
  wild offset 0xc0cf is not 8-byte aligned
  lld OK

After:

cargo run --bin linker-diff -- --wild-defaults --only 'linkedit.*' --ref /tmp/t.lld /tmp/t.wild
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.25s
     Running `target/debug/linker-diff --wild-defaults --colour never --only 'linkedit.*' --ref /tmp/t.lld /tmp/t.wild`
No differences or validation failures detected

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

Successfully merging this pull request may close these issues.

Mach-O: properly align __LINKEDIT sections

3 participants