wasmtime_environ/obj.rs
1//! Utilities for working with object files that operate as Wasmtime's
2//! serialization and intermediate format for compiled modules.
3
4/// Filler for the `os_abi` field of the ELF header.
5///
6/// This is just a constant that seems reasonable in the sense it's unlikely to
7/// clash with others.
8pub const ELFOSABI_WASMTIME: u8 = 200;
9
10/// Flag for the `e_flags` field in the ELF header indicating a compiled
11/// module.
12pub const EF_WASMTIME_MODULE: u32 = 1 << 0;
13
14/// Flag for the `e_flags` field in the ELF header indicating a compiled
15/// component.
16pub const EF_WASMTIME_COMPONENT: u32 = 1 << 1;
17
18/// A custom Wasmtime-specific section of our compilation image which stores
19/// mapping data from offsets in the image to offset in the original wasm
20/// binary.
21///
22/// This section has a custom binary encoding. Currently its encoding is:
23///
24/// * The section starts with a 32-bit little-endian integer. This integer is
25/// how many entries are in the following two arrays.
26/// * Next is an array with the previous count number of 32-bit little-endian
27/// integers. This array is a sorted list of relative offsets within the text
28/// section. This is intended to be a lookup array to perform a binary search
29/// on an offset within the text section on this array.
30/// * Finally there is another array, with the same count as before, also of
31/// 32-bit little-endian integers. These integers map 1:1 with the previous
32/// array of offsets, and correspond to what the original offset was in the
33/// wasm file.
34///
35/// Decoding this section is intentionally simple, it only requires loading a
36/// 32-bit little-endian integer plus some bounds checks. Reading this section
37/// is done with the `lookup_file_pos` function below. Reading involves
38/// performing a binary search on the first array using the index found for the
39/// native code offset to index into the second array and find the wasm code
40/// offset.
41///
42/// At this time this section has an alignment of 1, which means all reads of it
43/// are unaligned. Additionally at this time the 32-bit encodings chosen here
44/// mean that >=4gb text sections are not supported.
45pub const ELF_WASMTIME_ADDRMAP: &str = ".wasmtime.addrmap";
46
47/// A custom binary-encoded section of wasmtime compilation artifacts which
48/// encodes the ability to map an offset in the text section to the trap code
49/// that it corresponds to.
50///
51/// This section is used at runtime to determine what flavor of trap happened to
52/// ensure that embedders and debuggers know the reason for the wasm trap. The
53/// encoding of this section is custom to Wasmtime and managed with helpers in
54/// the `object` crate:
55///
56/// * First the section has a 32-bit little endian integer indicating how many
57/// trap entries are in the section.
58/// * Next is an array, of the same length as read before, of 32-bit
59/// little-endian integers. These integers are offsets into the text section
60/// of the compilation image.
61/// * Finally is the same count number of bytes. Each of these bytes corresponds
62/// to a trap code.
63///
64/// This section is decoded by `lookup_trap_code` below which will read the
65/// section count, slice some bytes to get the various arrays, and then perform
66/// a binary search on the offsets array to find the index corresponding to
67/// the pc being looked up. If found the same index in the trap array (the array
68/// of bytes) is the trap code for that offset.
69///
70/// Note that at this time this section has an alignment of 1. Additionally due
71/// to the 32-bit encodings for offsets this doesn't support images >=4gb.
72pub const ELF_WASMTIME_TRAPS: &str = ".wasmtime.traps";
73
74/// A custom section which consists of just 1 byte which is either 0 or 1 as to
75/// whether BTI is enabled.
76pub const ELF_WASM_BTI: &str = ".wasmtime.bti";
77
78/// A bincode-encoded section containing engine-specific metadata used to
79/// double-check that an artifact can be loaded into the current host.
80pub const ELF_WASM_ENGINE: &str = ".wasmtime.engine";
81
82/// This is the name of the section in the final ELF image which contains
83/// concatenated data segments from the original wasm module.
84///
85/// This section is simply a list of bytes and ranges into this section are
86/// stored within a `Module` for each data segment. Memory initialization and
87/// passive segment management all index data directly located in this section.
88///
89/// Note that this implementation does not afford any method of leveraging the
90/// `data.drop` instruction to actually release the data back to the OS. The
91/// data section is simply always present in the ELF image. If we wanted to
92/// release the data it's probably best to figure out what the best
93/// implementation is for it at the time given a particular set of constraints.
94pub const ELF_WASM_DATA: &'static str = ".rodata.wasm";
95
96/// This is the name of the section in the final ELF image which contains a
97/// `bincode`-encoded `CompiledModuleInfo`.
98///
99/// This section is optionally decoded in `CompiledModule::from_artifacts`
100/// depending on whether or not a `CompiledModuleInfo` is already available. In
101/// cases like `Module::new` where compilation directly leads into consumption,
102/// it's available. In cases like `Module::deserialize` this section must be
103/// decoded to get all the relevant information.
104pub const ELF_WASMTIME_INFO: &'static str = ".wasmtime.info";
105
106/// This is the name of the section in the final ELF image which contains a
107/// concatenated list of all function names.
108///
109/// This section is optionally included in the final artifact depending on
110/// whether the wasm module has any name data at all (or in the future if we add
111/// an option to not preserve name data). This section is a concatenated list of
112/// strings where `CompiledModuleInfo::func_names` stores offsets/lengths into
113/// this section.
114///
115/// Note that the goal of this section is to avoid having to decode names at
116/// module-load time if we can. Names are typically only used for debugging or
117/// things like backtraces so there's no need to eagerly load all of them. By
118/// storing the data in a separate section the hope is that the data, which is
119/// sometimes quite large (3MB seen for spidermonkey-compiled-to-wasm), can be
120/// paged in lazily from an mmap and is never paged in if we never reference it.
121pub const ELF_NAME_DATA: &'static str = ".name.wasm";
122
123/// This is the name of the section in the final ELF image that contains the
124/// concatenation of all the native DWARF information found in the original wasm
125/// files.
126///
127/// This concatenation is not intended to be read by external tools at this time
128/// and is instead indexed directly by relative indices stored in compilation
129/// metadata.
130pub const ELF_WASMTIME_DWARF: &str = ".wasmtime.dwarf";
131
132macro_rules! libcalls {
133 ($($rust:ident = $sym:tt)*) => (
134 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
135 #[allow(missing_docs)]
136 pub enum LibCall {
137 $($rust,)*
138 }
139
140 impl LibCall {
141 /// Returns the libcall corresponding to the provided symbol name,
142 /// if one matches.
143 pub fn from_str(s: &str) -> Option<LibCall> {
144 match s {
145 $($sym => Some(LibCall::$rust),)*
146 _ => None,
147 }
148 }
149
150 /// Returns the symbol name in object files associated with this
151 /// libcall.
152 pub fn symbol(&self) -> &'static str {
153 match self {
154 $(LibCall::$rust => $sym,)*
155 }
156 }
157 }
158 )
159}
160
161libcalls! {
162 FloorF32 = "libcall_floor32"
163 FloorF64 = "libcall_floor64"
164 NearestF32 = "libcall_nearestf32"
165 NearestF64 = "libcall_nearestf64"
166 CeilF32 = "libcall_ceilf32"
167 CeilF64 = "libcall_ceilf64"
168 TruncF32 = "libcall_truncf32"
169 TruncF64 = "libcall_truncf64"
170 FmaF32 = "libcall_fmaf32"
171 FmaF64 = "libcall_fmaf64"
172 X86Pshufb = "libcall_x86_pshufb"
173}