I'd like FrameUnwindSink to allow collecting records for multiple functions into one sink. Currently, TargetIsa::emit_unwind_info is designed around emitting one full record (a whole .eh_frame or the UnwindInfo part of a RUNTIME_FUNCTION) per function, which is awkward to use in the face of multiple functions. In squaring away this interface with bytecodealliance/cranelift#902, I've realized that to generate good unwind information through cranelift-module, we would have to do a lot of legwork already done by gimli to join all distinct .eh_frame, so I'd rather just build the right structures in the first place. As @philipc commented the existing interface isn't entirely how gimli is intended to be used, either.
Functionally, I want isa::x86::fde::emit_fde to be designed around adding to a FrameTable provided by sink, rather than constructing and writing an .eh_frame section for the function being described. Windows unwind info generation wouldn't have to change much, with implementors of FrameUnwindSink collecting an array of UnwindInfo rather than just one.
I imagine this looking like FrameUnwindSink impls building a collection of records, either a FrameTable for Libunwind or a vec of UnwindInfo for Fastcall. To go along with this, I expect such impls would be added in cranelift-module. These may or may not be suitable for use from wasmtime, I'm optimistic that they could because in the worst case a FrameUnwindSink can be created, used for one function, and then discarded, preserving the current behavior.
My expectation is that a trait like
trait FrameUnwindSink {
/// Create an instance of the implementor for the provided unwind style.
fn for_style(kind: FrameUnwindKind) -> Self;
/// Add a function to the sink. May panic if the function's calling convention
/// is not compatible with the unwind style this sink was created with.
fn add_function(&mut self, func: &Function, isa: &dyn TargetIsa);
/// Serialize this sink's contents in a manner appropriate for this sink's
/// unwind style.
fn serialize(&self) -> Vec<u8>;
should satisfy everyone's needs?
The notable benefit of this is making it easy to generate a single .eh_frame section when using cranelift-faerie or cranelift-object, meaning lucet can unwind wasm, have backtraces, all that good stuff :) I imagine @bjorn3 might like this for having unwind information when using Cranelift as a rustc backend as well?
This also seems like a good excuse to move isa::x86::fde and isa::x86::unwind to isa::x86::unwind::windows and isa::x86::unwind::libunwind respectively?
cc @yurydelendik as I'd like your thoughts on this idea, and @peterhuene as I know you've also worked on unwind information here.
Opening an issue to make sure this gets a design friendly to both lucet and wasmtime, rather than just tweaking bytecodealliance/cranelift#902 until something looks right :)
I'd like
FrameUnwindSinkto allow collecting records for multiple functions into one sink. Currently,TargetIsa::emit_unwind_infois designed around emitting one full record (a whole.eh_frameor theUnwindInfopart of a RUNTIME_FUNCTION) per function, which is awkward to use in the face of multiple functions. In squaring away this interface with bytecodealliance/cranelift#902, I've realized that to generate good unwind information throughcranelift-module, we would have to do a lot of legwork already done bygimlito join all distinct.eh_frame, so I'd rather just build the right structures in the first place. As @philipc commented the existing interface isn't entirely howgimliis intended to be used, either.Functionally, I want
isa::x86::fde::emit_fdeto be designed around adding to aFrameTableprovided bysink, rather than constructing and writing an.eh_framesection for the function being described. Windows unwind info generation wouldn't have to change much, with implementors ofFrameUnwindSinkcollecting an array ofUnwindInforather than just one.I imagine this looking like
FrameUnwindSinkimpls building a collection of records, either aFrameTableforLibunwindor a vec ofUnwindInfoforFastcall. To go along with this, I expect such impls would be added incranelift-module. These may or may not be suitable for use from wasmtime, I'm optimistic that they could because in the worst case aFrameUnwindSinkcan be created, used for one function, and then discarded, preserving the current behavior.My expectation is that a trait like
should satisfy everyone's needs?
The notable benefit of this is making it easy to generate a single
.eh_framesection when usingcranelift-faerieorcranelift-object, meaninglucetcan unwind wasm, have backtraces, all that good stuff :) I imagine @bjorn3 might like this for having unwind information when using Cranelift as arustcbackend as well?This also seems like a good excuse to move
isa::x86::fdeandisa::x86::unwindtoisa::x86::unwind::windowsandisa::x86::unwind::libunwindrespectively?cc @yurydelendik as I'd like your thoughts on this idea, and @peterhuene as I know you've also worked on unwind information here.
Opening an issue to make sure this gets a design friendly to both lucet and wasmtime, rather than just tweaking bytecodealliance/cranelift#902 until something looks right :)