Skip to content

feat(cli): add --relocatable flag to force ET_REL output#83

Open
avrabe wants to merge 1 commit intomainfrom
feat/synth-relocatable-flag
Open

feat(cli): add --relocatable flag to force ET_REL output#83
avrabe wants to merge 1 commit intomainfrom
feat/synth-relocatable-flag

Conversation

@avrabe
Copy link
Copy Markdown
Contributor

@avrabe avrabe commented Apr 27, 2026

Summary

  • Currently synth produces ET_REL (relocatable .o) only when the input wasm has imports — the relocations they generate trigger that path. Self-contained wasm modules with no imports produce a complete ET_EXEC firmware (vector table, Reset_Handler, linear_memory section, etc.).
  • Adds a --relocatable flag that forces ET_REL output regardless of whether the wasm has imports — for linking into a host build system that has its own startup code (e.g., integrating verified Rust kernel primitives compiled to wasm into a Zephyr build).
  • Flag is additive; default behaviour is unchanged.

Context

This unblocks a follow-up experiment on the gale engine bench: compiling gale-ffi (formally-verified Rust replacement for Zephyr kernel primitives) to wasm32, then using synth to lower the wasm to a Cortex-M4F relocatable .o that links into the existing Zephyr build alongside the C kernel. The rest of the build expects libgale_ffi.a (which we'll wrap from synth's .o), so synth's output needs to be a relocatable, not a full firmware.

Tested with gale-ffi.wasm (200 functions, 0 imports):

  • Without --relocatable: 27052-byte ET_EXEC firmware with Reset_Handler, vector table, linear_memory section.
  • With --relocatable: 26645-byte ET_REL ARM EABI5 object with all gale_* symbols defined and no firmware machinery.

Test plan

  • cargo check passes
  • cargo install --path crates/synth-cli --force succeeds
  • Default path (no --relocatable) still produces ET_EXEC — verified with file output.elf
  • --relocatable produces ET_REL — verified with file output.o reporting "ELF 32-bit LSB relocatable, ARM, EABI5"
  • All 193 gale_* symbols present in the relocatable; Reset_Handler / Default_Handler / Trap_Handler / __linear_memory_base absent — verified with nm
  • CI passes

Currently synth produces a relocatable object (.o, ET_REL) only when the
input wasm has imports — the relocations they generate trigger the
relocatable code path. Self-contained wasm modules with no imports
produce a complete ET_EXEC firmware with vector table, Reset_Handler,
linear_memory section, etc.

For linking into a host build system (e.g. integrating verified Rust
kernel primitives compiled to wasm into a Zephyr build), the host
expects a relocatable .o it can pull into its existing link step. Add
a --relocatable CLI flag that forces ET_REL output regardless of
whether the wasm has imports.

The flag is additive — default behaviour is unchanged.

Tested with gale-ffi.wasm (200 functions, 0 imports): output is now
a 26645-byte ET_REL ARM EABI5 object with all gale_* symbols defined
and no vector-table machinery.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 27, 2026

Codecov Report

❌ Patch coverage is 90.00000% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
crates/synth-cli/src/main.rs 90.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

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.

1 participant