bytecodealliance / bytecodealliance/wasmtime
Cranelift: RISCV frame pointer position differs from LLVM
- Dominant language
- Rust
- Stars
- 18.6k
- Forks
- 1.8k
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 121
Description
Cranelift on RISCV (when frame pointers are enabled) generated code where the `fp` register always points to the next frame pointer like so:
```
---- frame ----
ra,
fp, <- fp points here
...
---- frame ----
```
while LLVM generates code where `fp` points *one word above the frame* like so:
```
---- frame ---- <- fp points here
ra,
fp,
...
---- frame ----
```
While this is not a problem in isolation it means that stack walkers (for backtraces, perf stack traces, unwinding) cannot walk across a boundary where LLVM generated code calls cranelift generated code and vice-versa.
Since we cannot really change LLVMs behavior cranelift should match LLVM even though that means a really nasty breaking change for cranelift consumers that rely on the frame pointer position (nasty since code would continue to compile just be broken at runtime in weird ways).
AFAIK supporting this change in wasmtime would be quite trivial, it would just mean changing this from `0` to `-2 * size_of::()`
https://github.com/bytecodealliance/wasmtime/blob/de469e2790f0c33f99df483f2dae4ceb47e11c8e/crates/wasmtime/src/runtime/vm/arch/riscv64.rs#L22
which would mean this assertion no longer holds https://github.com/bytecodealliance/wasmtime/blob/07eeac40525246425073011bd707edd298443a96/crates/wasmtime/src/runtime/vm/traphandlers/backtrace.rs#L252
and the corresponding code in `save_last_wasm_exit_fp_pc` needs to be adjusted
https://github.com/bytecodealliance/wasmtime/blob/70a37939d367e83ab62002bad64fb11e763f3d2f/crates/cranelift/src/compiler.rs#L1173-L1176
Contributor guide
Assessment
This issue has not been assessed yet.