wasm_debug/
types.rs

1//! Data structures and functions used to get metadata into a format this
2//! crate can understand.
3
4use cranelift_entity::{EntityRef, PrimaryMap};
5use std::collections::HashMap;
6
7/// Index of a function.
8#[derive(Debug, PartialEq, Eq, Clone, Copy)]
9pub struct DefinedFuncIndex(usize);
10
11impl EntityRef for DefinedFuncIndex {
12    fn new(v: usize) -> Self {
13        Self(v)
14    }
15
16    fn index(self) -> usize {
17        self.0
18    }
19}
20
21/// Offset into the Wasm starting at the code section.
22#[derive(Debug, PartialEq, Eq, Clone, Copy)]
23pub struct SourceLoc(u32);
24
25impl SourceLoc {
26    /// Create a `SourceLoc`.
27    pub fn new(v: u32) -> Self {
28        Self(v)
29    }
30
31    /// Get the inner value.
32    pub fn get(&self) -> u32 {
33        self.0
34    }
35
36    /// Check if this is the default `SourceLoc`.
37    pub fn is_default(&self) -> bool {
38        self.0 == !0
39    }
40}
41
42/// Information about a compiled function.
43#[derive(Debug, PartialEq, Eq, Clone)]
44pub struct CompiledFunctionData {
45    /// Information about the instructions in this function in order.
46    pub instructions: Vec<CompiledInstructionData>,
47    /// The start location in the Wasm of this function.
48    pub start_srcloc: SourceLoc,
49    /// The end location in the Wasm of this function.
50    pub end_srcloc: SourceLoc,
51    /// The offset into the compiled code where this function is.
52    pub body_offset: usize,
53    /// The size of the compiled function.
54    pub body_len: usize,
55}
56
57/// Information about a compiled WebAssembly instruction.
58#[derive(Debug, PartialEq, Eq, Clone)]
59pub struct CompiledInstructionData {
60    /// The location in the Wasm of the instruction.
61    pub srcloc: SourceLoc,
62    /// The length of the instruction in bytes.
63    pub code_len: usize,
64    /// The offset from the start of the function? (TODO: figure out what this is).
65    pub code_offset: usize,
66}
67
68/// Build a [`ModuleAddressMap`].
69pub fn create_module_address_map<'a, I>(info: I) -> ModuleAddressMap
70where
71    I: Iterator<Item = &'a CompiledFunctionData>,
72{
73    let mut map = PrimaryMap::new();
74    for cfd in info {
75        map.push(cfd.clone());
76    }
77    map
78}
79
80/// Mapping to compiled functions.
81pub type ModuleAddressMap = PrimaryMap<DefinedFuncIndex, CompiledFunctionData>;
82
83/// Type to track in which register a value is located.
84pub type RegUnit = u16;
85
86/// Type to track where on the stack a value is located.
87#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
88pub struct StackSlot(u32);
89
90impl StackSlot {
91    /// Create a stack slot.
92    pub fn from_u32(x: u32) -> Self {
93        Self(x)
94    }
95
96    /// Get the inner value.
97    pub fn as_u32(self) -> u32 {
98        self.0
99    }
100}
101
102/// Type used to keep track of values during compilation.
103#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
104pub struct ValueLabel(u32);
105
106impl ValueLabel {
107    /// Create a value label.
108    pub fn from_u32(x: u32) -> Self {
109        Self(x)
110    }
111
112    /// Get the inner value.
113    pub fn as_u32(self) -> u32 {
114        self.0
115    }
116}
117
118impl EntityRef for ValueLabel {
119    fn new(v: usize) -> Self {
120        Self(v as u32)
121    }
122
123    fn index(self) -> usize {
124        self.0 as usize
125    }
126}
127
128/// The location where a value is.
129#[derive(Debug, Clone, Copy)]
130pub enum ValueLoc {
131    Unassigned,
132    /// Value is in a register.
133    Reg(RegUnit),
134    /// Value is at this location on the stack.
135    Stack(StackSlot),
136}
137
138/// A range in which a value is valid.
139#[derive(Debug, Clone)]
140pub struct ValueLocRange {
141    /// Where the value is.
142    pub loc: ValueLoc,
143    /// Where it starts being there.
144    pub start: u32,
145    /// Where it stops being there.
146    pub end: u32,
147}
148
149/// Create a [`ValueLabelsRanges`] from data.
150pub fn build_values_ranges<'a, I>(vlri_iter: I) -> ValueLabelsRanges
151where
152    I: Iterator<Item = &'a ValueLabelsRangesInner>,
153{
154    let mut map = PrimaryMap::new();
155
156    for i in vlri_iter {
157        map.push(i.clone());
158    }
159
160    map
161}
162
163/// Map of functions to information about when and where its values are valid.
164pub type ValueLabelsRanges = PrimaryMap<DefinedFuncIndex, ValueLabelsRangesInner>;
165/// Map of [`ValueLabel`] to all the locations that it's valid at.
166pub type ValueLabelsRangesInner = HashMap<ValueLabel, Vec<ValueLocRange>>;
167
168// Temporary code.  Code using this should be restructured or removed probably.
169// seems too backend specific
170pub fn get_vmctx_value_label() -> ValueLabel {
171    // copied from cranelift_wasm
172    ValueLabel(0xffff_fffe)
173}
174
175/// Information about the module and VM context.
176pub struct ModuleVmctxInfo {
177    /// Offset from the VMCtx where a pointer to memory can be found.
178    ///
179    /// Assume memory 0 for now.
180    pub memory_offset: i64,
181    /// The size of the VMCtx struct
182    pub vmctx_size: i64,
183    /// The offsets of the stack slots for each function.
184    pub stack_slot_offsets: PrimaryMap<DefinedFuncIndex, Vec<Option<i32>>>,
185}
186
187impl ModuleVmctxInfo {
188    pub fn new<'a, I>(memory_offset: i64, vmctx_size: i64, stack_slot_offsets: I) -> Self
189    where
190        I: Iterator<Item = &'a Vec<Option<i32>>>,
191    {
192        let mut map = PrimaryMap::new();
193        for o in stack_slot_offsets {
194            map.push(o.clone());
195        }
196        Self {
197            memory_offset,
198            vmctx_size,
199            stack_slot_offsets: map,
200        }
201    }
202}