Path: blob/main/crates/environ/src/compile/trap_encoding.rs
1693 views
use crate::TrapInformation;1use crate::obj::ELF_WASMTIME_TRAPS;2use crate::prelude::*;3use object::write::{Object, StandardSegment};4use object::{LittleEndian, SectionKind, U32Bytes};5use std::ops::Range;67/// A helper structure to build the custom-encoded section of a wasmtime8/// compilation image which encodes trap information.9///10/// This structure is incrementally fed the results of compiling individual11/// functions and handles all the encoding internally, allowing usage of12/// `lookup_trap_code` below with the resulting section.13#[derive(Default)]14pub struct TrapEncodingBuilder {15offsets: Vec<U32Bytes<LittleEndian>>,16traps: Vec<u8>,17last_offset: u32,18}1920impl TrapEncodingBuilder {21/// Appends trap information about a function into this section.22///23/// This function is called to describe traps for the `func` range24/// specified. The `func` offsets are specified relative to the text section25/// itself, and the `traps` offsets are specified relative to the start of26/// `func`.27///28/// This is required to be called in-order for increasing ranges of `func`29/// to ensure the final array is properly sorted. Additionally `traps` must30/// be sorted.31pub fn push(&mut self, func: Range<u64>, traps: &[TrapInformation]) {32// NB: for now this only supports <=4GB text sections in object files.33// Alternative schemes will need to be created for >32-bit offsets to34// avoid making this section overly large.35let func_start = u32::try_from(func.start).unwrap();36let func_end = u32::try_from(func.end).unwrap();3738// Sanity-check to ensure that functions are pushed in-order, otherwise39// the `offsets` array won't be sorted which is our goal.40assert!(func_start >= self.last_offset);4142self.offsets.reserve(traps.len());43self.traps.reserve(traps.len());44for info in traps {45let pos = func_start + info.code_offset;46assert!(pos >= self.last_offset);47self.offsets.push(U32Bytes::new(LittleEndian, pos));48self.traps.push(info.trap_code as u8);49self.last_offset = pos;50}5152self.last_offset = func_end;53}5455/// Encodes this section into the object provided.56pub fn append_to(self, obj: &mut Object) {57let section = obj.add_section(58obj.segment_name(StandardSegment::Data).to_vec(),59ELF_WASMTIME_TRAPS.as_bytes().to_vec(),60SectionKind::ReadOnlyData,61);6263// NB: this matches the encoding expected by `lookup` below.64let amt = u32::try_from(self.traps.len()).unwrap();65obj.append_section_data(section, &amt.to_le_bytes(), 1);66obj.append_section_data(section, object::bytes_of_slice(&self.offsets), 1);67obj.append_section_data(section, &self.traps, 1);68}69}707172