Skip to main content
Technical proposal SIMD-0189 Idea

SBPF stricter ELF headers

  1. Idea
  2. Draft
  3. Review
  4. Accept
  5. Implement
  6. Active

Decision brief

Why this proposal matters

Imposes more restrictions on what is expected of ELF headers.

Source-backed reading aid · source language: EN

Proposal at a glance

What changes

  • e_ident.ei_mag must be [0x7F, 0x45, 0x4C, 0x46]
  • e_ident.ei_class must be ELFCLASS64 (0x02)
  • e_ident.ei_data must be ELFDATA2LSB (0x01)

Stakeholder map

Who is affected

Builders & client teams Medium impact

The toolchain linker will use a new linker script to adhere to these restrictions defined here and thus the change will be transparent to the dApp developers.

Action requirement unknown
Validators & operators Impact unknown

No proposal-specific evidence was found for this group.

Action requirement unknown
Users & stakers Impact unknown

No proposal-specific evidence was found for this group.

Action requirement unknown
Governance & ecosystem Impact unknown

No proposal-specific evidence was found for this group.

Action requirement unknown

Exact source revision

Full proposal document

Source-language document. Technical identifiers and evidence remain unchanged. 0616093b2952

Summary

Imposes more restrictions on what is expected of ELF headers.

Motivation

After the removal of relocations in SIMD-0178 the ELF layout could be massively be simplified by constraining it to a strict subset of what ELF otherwise allows. Doing so not only reduces the complexity of validator implementations but also reduces the attack surface.

Alternatives Considered

Moving away from ELF as a container format altogether. However this would only gain a very small file size advantage but otherwise loose all tooling compatibility.

New Terminology

None.

Detailed Design

The following must go into effect if and only if a program indicates the SBPF-version v3 or higher in its program header (see SIMD-0161).

File header

The file size must not be less than size_of::<Elf64Ehdr>() (64 bytes), otherwise ElfParserError::OutOfBounds must be thrown.

  • e_ident.ei_mag must be [0x7F, 0x45, 0x4C, 0x46]
  • e_ident.ei_class must be ELFCLASS64 (0x02)
  • e_ident.ei_data must be ELFDATA2LSB (0x01)
  • e_ident.ei_version must be EV_CURRENT (0x01)
  • e_ident.ei_osabi must be ELFOSABI_NONE (0x00)
  • e_ident.ei_abiversion must be 0x00
  • e_ident.ei_pad must be [0x00; 7]
  • e_type is not checked
  • e_machine must be EM_BPF (0x00F7)
  • e_version must be EV_CURRENT (0x00000001)
  • e_entry must be within the bounds of the second program header
  • e_phoff must be size_of::<Elf64Ehdr>() (64 bytes)
  • e_shoff is not checked
  • e_flags see SIMD-0161
  • e_ehsize must be size_of::<Elf64Ehdr>() (64 bytes)
  • e_phnum must be greater than or equal 0x0001
  • e_phoff + e_phnum * size_of::<Elf64Phdr>() must be less than or equal the file size
  • e_phentsize must be size_of::<Elf64Phdr>() (56 bytes)
  • e_shnum is not checked
  • e_shentsize is not checked
  • e_shstrndx is not checked

If any check fails ElfParserError::InvalidFileHeader must be thrown.

Program headers

indexpurposep_flagsp_vaddr
0ro dataPF_R0 << 32
1bytecodePF_X1 << 32

If p_flags of the first program header is not PF_R, then only the second program header is expected (effectively skipping the first). For each of these predefined program headers:

  • p_type must be PT_LOAD
  • p_flags must match the p_flags of the entry in the table above
  • p_offset be e_phoff + e_phnum * size_of::<Elf64Phdr>() for the first entry and be p_offset + p_filesz of the previous entry for all subsequent entries
  • p_offset must be less than or equal file.len() as u64
  • p_offset must be evenly divisible by 8 bytes,
  • p_vaddr must match the p_vaddr of the entry in the table above
  • p_paddr must match the p_vaddr of the entry in the table above
  • p_filesz must be p_memsz
  • p_filesz must not be greater than file.len() as u64 - p_offset
  • p_filesz must be evenly divisible by 8 bytes,
  • p_memsz must fit in 32 bits / be less than 1 << 32
  • p_align is ignored

If any check fails ElfParserError::InvalidProgramHeader must be thrown.

Impact

The toolchain linker will use a new linker script to adhere to these restrictions defined here and thus the change will be transparent to the dApp developers.

The section headers are ignored so arbitrary metadata can continue to be encoded there.

Security Considerations

None.

Evidence graph

Related proposals and rollout

One or more sources are unavailable.

Upstream review record

Upstream discussion & review

GitHub review is editorial context, not evidence of on-chain support, voting, or outcome.

PR #189 · merged SIMD-0189: SBPF stricter ELF headers 48 comments and reviews · Mar 16, 2026
@LucasSte

I'm just thinking about how we might be able to make sure our compiled binaries can be analyzed by upstream-compatible tooling. If our ELF layout is pretty closely aligned with ETEXEC, we might as well lean into that and use the proper etype so that off-the-shelf tools can analyze Solana binaries directly from the chain (or compiled locally). On one hand, the kernel expects a ETREL, not a ETEXEC. I asked the type not be ETREL, because I believe linkers won't solve relocations for ETREL files. On the other, llvm tools and gnu-binutils tools work with eBPF code regardless of the ELF type. As far as I can tell, Asymmetric Research was using Ghidra with our SBPFv0 ETDYN files without any problem

GitHub ↗
@simd-botbot

Thanks, topointon-jump(https://github.com/topointon-jump)! ⚠️ Status: Cannot merge yet - Missing approval from: Anza (t-nelson(https://github.com/t-nelson), sakridge(https://github.com/sakridge), or bw-solana(https://github.com/bw-solana))

GitHub ↗
@simd-botbot

Thanks, 0x0ece(https://github.com/0x0ece)! ⚠️ Status: Cannot merge yet - Missing approval from: Anza (t-nelson(https://github.com/t-nelson), sakridge(https://github.com/sakridge), or bw-solana(https://github.com/bw-solana))

GitHub ↗
@deanmlittle

resolved as headers are now removed and rodata header is now optional.

GitHub ↗
@simd-botbot

Thanks, ripatel-fd(https://github.com/ripatel-fd)! ⚠️ Status: Cannot merge yet - Missing approval from: Anza (t-nelson(https://github.com/t-nelson), sakridge(https://github.com/sakridge), or bw-solana(https://github.com/bw-solana))

GitHub ↗
@simd-botbot

✅ All approvals received! @Lichtso, you can now merge this by commenting /merge. ✅ Status: Ready to merge

GitHub ↗
@simd-botbot

✅ Merge successful! Lichtso(https://github.com/Lichtso)'s PR has been merged.

GitHub ↗

simd.watch community discussion · SIMD-0189

Powered by Giscus · Sign in with GitHub to comment

Community comments load when this section approaches the viewport.

Provenance

Evidence & technical details

Rollout or chain data, source revisions, freshness and integrity.
1

SIMD

Deployment Status

Document lifecycleIdea
CategoryCore protocol
Devnetinactive
Testnetinactive
Mainnet-Betainactive
GJav1vwg2etvSWraPT96QvYuQJswJTJwtcyARrvkhuV9

Exact source revision

Sources & integrity

  • Proposal document pinned_commit_blob
    0616093b2952ed6de52c4a27d66aadd11d48d4f9
  • simd-document document · current · Sep 11, 2026
    0616093b2952ed6de52c4a27d66aadd11d48d4f9

One or more sources are unavailable.