lucet_module/
traps.rs

1use num_derive::FromPrimitive;
2use num_traits::FromPrimitive;
3
4/// The type of a WebAssembly
5/// [trap](http://webassembly.github.io/spec/core/intro/overview.html#trap).
6#[repr(u32)]
7#[derive(Copy, Clone, Debug, FromPrimitive, PartialEq)]
8pub enum TrapCode {
9    StackOverflow = 0,
10    HeapOutOfBounds = 1,
11    OutOfBounds = 2,
12    IndirectCallToNull = 3,
13    BadSignature = 4,
14    IntegerOverflow = 5,
15    IntegerDivByZero = 6,
16    BadConversionToInteger = 7,
17    Interrupt = 8,
18    TableOutOfBounds = 9,
19    Unreachable = 10,
20}
21
22impl TrapCode {
23    pub fn try_from_u32(v: u32) -> Option<TrapCode> {
24        Self::from_u32(v)
25    }
26}
27
28/// Trap information for an address in a compiled function
29///
30/// To support zero-copy deserialization of trap tables, this
31/// must be repr(C) [to avoid cases where Rust may change the
32/// layout in some future version, mangling the interpretation
33/// of an old TrapSite struct]
34#[repr(C)]
35#[derive(Clone, Debug)]
36pub struct TrapSite {
37    pub offset: u32,
38    pub code: TrapCode,
39}
40
41/// A collection of trap sites, typically obtained from a
42/// single function (see [`FunctionSpec::traps`])
43#[repr(C)]
44#[derive(Clone, Debug)]
45pub struct TrapManifest<'a> {
46    pub traps: &'a [TrapSite],
47}
48
49impl<'a> TrapManifest<'a> {
50    pub fn new(traps: &'a [TrapSite]) -> TrapManifest<'_> {
51        TrapManifest { traps }
52    }
53    pub fn lookup_addr(&self, addr: u32) -> Option<TrapCode> {
54        // predicate to find the trapsite for the addr via binary search
55        let f = |ts: &TrapSite| ts.offset.cmp(&addr);
56
57        if let Ok(i) = self.traps.binary_search_by(f) {
58            Some(self.traps[i].code)
59        } else {
60            None
61        }
62    }
63}