Skip to content

arm --relocatable: import-call relocations use func_N, not the wasm import field name — won't link against a real host #173

@avrabe

Description

@avrabe

Summary

Follow-up to #167 (thanks — R_ARM_THM_CALL relocations now work and the Thumb BL encoding is fixed). One gap remains for linking a relocatable object against a real host (e.g. the Zephyr kernel):

synth emits the relocation target symbols for imported calls as generic func_0, func_1, … instead of the wasm import field name. synth knows the real names — it logs them — but they appear nowhere in the ELF, so the object cannot resolve against the host's actual symbols.

Reproduction

merged.both.wasm (z_impl_k_sem_give + gale_k_sem_give_decide + 5 env:: imports; WAT in the #167 gist):

synth compile merged.both.wasm --target cortex-m4f --all-exports --relocatable -o merged.both.o

synth's own log shows the names:

import[0]: env::k_spin_lock
import[1]: env::z_unpend_first_thread
import[2]: env::arch_thread_return_value_set
import[3]: env::z_ready_thread
import[4]: env::z_reschedule

but the relocations and symbol table use indices:

$ arm-zephyr-eabi-objdump -r merged.both.o
00000090 R_ARM_THM_CALL  func_0      # should be k_spin_lock
00000098 R_ARM_THM_CALL  func_1      # should be z_unpend_first_thread
000000c6 R_ARM_THM_CALL  func_6      # internal call to gale_k_sem_give_decide — OK as-is
...
$ arm-zephyr-eabi-nm merged.both.o
         U func_0          # should be `U k_spin_lock`
         U func_1
         ...
         U func_5          # core::panicking::panic_const_add_overflow (uncompiled) — also func_N

arm-zephyr-eabi-nm finds no k_spin_lock / z_unpend_first_thread / … anywhere. Linking against a kernel that defines k_spin_lock therefore fails to resolve (the linker is looking for func_0).

Expected

For imported functions, name the undefined symbol after the wasm import field name (k_spin_lock), not func_<index>. Internal defined calls keeping a stable name (the export name, e.g. gale_k_sem_give_decide, which already works) is correct; only the import symbols need their real field names.

A --defsym func_0=k_spin_lock … aliasing layer works as a local stopgap, but every consumer linking synth output into a real host would need to hand-maintain the index→name map, which defeats --relocatable's stated purpose ("for linking into a host build system").

Impact

This is the final blocker for the cross-language-LTO-via-wasm route end-to-end: with #167 fixed the merged object now carries real relocations and links with ld -r, but it still can't resolve against the Zephyr kernel because the kernel-import symbols are func_N. With import field names, merged.both.o would link straight into the bench and yield the long-blocked silicon cycle measurement.

Environment

  • synth v0.11.1 (6f7e3ac8), arm backend, target cortex-m4f
  • objdump/nm: Zephyr SDK 1.0.1 (binutils 2.43.1)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions