xref: /wasmtime-44.0.1/crates/environ/src/obj.rs (revision c07c94d2)
1 //! Utilities for working with object files that operate as Wasmtime's
2 //! serialization and intermediate format for compiled modules.
3 
4 use core::fmt;
5 
6 /// Filler for the `os_abi` field of the ELF header.
7 ///
8 /// This is just a constant that seems reasonable in the sense it's unlikely to
9 /// clash with others.
10 pub const ELFOSABI_WASMTIME: u8 = 200;
11 
12 /// Flag for the `e_flags` field in the ELF header indicating a compiled
13 /// module.
14 pub const EF_WASMTIME_MODULE: u32 = 1 << 0;
15 
16 /// Flag for the `e_flags` field in the ELF header indicating a compiled
17 /// component.
18 pub const EF_WASMTIME_COMPONENT: u32 = 1 << 1;
19 
20 /// Flag for the `e_flags` field in the ELF header indicating compiled code for
21 /// pulley32
22 pub const EF_WASMTIME_PULLEY32: u32 = 1 << 2;
23 
24 /// Flag for the `e_flags` field in the ELF header indicating compiled code for
25 /// pulley64
26 pub const EF_WASMTIME_PULLEY64: u32 = 1 << 3;
27 
28 /// Flag for the `sh_flags` field in the ELF text section that indicates that
29 /// the text section does not itself need to be executable. This is used for the
30 /// Pulley target, for example, to indicate that it does not need to be made
31 /// natively executable as it does not contain actual native code.
32 pub const SH_WASMTIME_NOT_EXECUTED: u64 = 1 << 0;
33 
34 /// A custom Wasmtime-specific section of our compilation image which stores
35 /// mapping data from offsets in the image to offset in the original wasm
36 /// binary.
37 ///
38 /// This section has a custom binary encoding. Currently its encoding is:
39 ///
40 /// * The section starts with a 32-bit little-endian integer. This integer is
41 ///   how many entries are in the following two arrays.
42 /// * Next is an array with the previous count number of 32-bit little-endian
43 ///   integers. This array is a sorted list of relative offsets within the text
44 ///   section. This is intended to be a lookup array to perform a binary search
45 ///   on an offset within the text section on this array.
46 /// * Finally there is another array, with the same count as before, also of
47 ///   32-bit little-endian integers. These integers map 1:1 with the previous
48 ///   array of offsets, and correspond to what the original offset was in the
49 ///   wasm file.
50 ///
51 /// Decoding this section is intentionally simple, it only requires loading a
52 /// 32-bit little-endian integer plus some bounds checks. Reading this section
53 /// is done with the `lookup_file_pos` function below. Reading involves
54 /// performing a binary search on the first array using the index found for the
55 /// native code offset to index into the second array and find the wasm code
56 /// offset.
57 ///
58 /// At this time this section has an alignment of 1, which means all reads of it
59 /// are unaligned. Additionally at this time the 32-bit encodings chosen here
60 /// mean that >=4gb text sections are not supported.
61 pub const ELF_WASMTIME_ADDRMAP: &str = ".wasmtime.addrmap";
62 
63 /// A custom Wasmtime-specific section of compilation which store information
64 /// about live gc references at various locations in the text section (stack
65 /// maps).
66 ///
67 /// This section has a custom binary encoding described in `stack_maps.rs` which
68 /// is used to implement the single query we want to satisfy of: where are the
69 /// live GC references at this pc? Like the addrmap section this has an
70 /// alignment of 1 with unaligned reads, and it additionally doesn't support
71 /// >=4gb text sections.
72 pub const ELF_WASMTIME_STACK_MAP: &str = ".wasmtime.stackmap";
73 
74 /// A custom binary-encoded section of wasmtime compilation artifacts which
75 /// encodes the ability to map an offset in the text section to the trap code
76 /// that it corresponds to.
77 ///
78 /// This section is used at runtime to determine what flavor of trap happened to
79 /// ensure that embedders and debuggers know the reason for the wasm trap. The
80 /// encoding of this section is custom to Wasmtime and managed with helpers in
81 /// the `object` crate:
82 ///
83 /// * First the section has a 32-bit little endian integer indicating how many
84 ///   trap entries are in the section.
85 /// * Next is an array, of the same length as read before, of 32-bit
86 ///   little-endian integers. These integers are offsets into the text section
87 ///   of the compilation image.
88 /// * Finally is the same count number of bytes. Each of these bytes corresponds
89 ///   to a trap code.
90 ///
91 /// This section is decoded by `lookup_trap_code` below which will read the
92 /// section count, slice some bytes to get the various arrays, and then perform
93 /// a binary search on the offsets array to find the index corresponding to
94 /// the pc being looked up. If found the same index in the trap array (the array
95 /// of bytes) is the trap code for that offset.
96 ///
97 /// Note that at this time this section has an alignment of 1. Additionally due
98 /// to the 32-bit encodings for offsets this doesn't support images >=4gb.
99 pub const ELF_WASMTIME_TRAPS: &str = ".wasmtime.traps";
100 
101 /// A custom binary-encoded section of the wasmtime compilation
102 /// artifacts which encodes exception tables.
103 ///
104 /// This section is used at runtime to allow the unwinder to find
105 /// exception handler blocks active at particular callsites.
106 ///
107 /// This section's format is defined by the `ExceptionTableBuilder` data
108 /// structure. Its code offsets are relative to the start of the text segment.
109 pub const ELF_WASMTIME_EXCEPTIONS: &str = ".wasmtime.exceptions";
110 
111 /// A custom binary-encoded section of the wasmtime compilation
112 /// artifacts which encodes frame tables.
113 ///
114 /// This section is used at runtime to allow debug APIs to decode Wasm
115 /// VM-level state from state stack slots.
116 ///
117 /// This section's format is defined by the
118 /// [`crate::compile::FrameTableBuilder`] data structure. Its code
119 /// offsets are relative to the start of the text segment.
120 pub const ELF_WASMTIME_FRAMES: &str = ".wasmtime.frames";
121 
122 /// A custom section which consists of just 1 byte which is either 0 or 1 as to
123 /// whether BTI is enabled.
124 pub const ELF_WASM_BTI: &str = ".wasmtime.bti";
125 
126 /// A bincode-encoded section containing engine-specific metadata used to
127 /// double-check that an artifact can be loaded into the current host.
128 pub const ELF_WASM_ENGINE: &str = ".wasmtime.engine";
129 
130 /// This is the name of the section in the final ELF image which contains
131 /// concatenated data segments from the original wasm module.
132 ///
133 /// This section is simply a list of bytes and ranges into this section are
134 /// stored within a `Module` for each data segment. Memory initialization and
135 /// passive segment management all index data directly located in this section.
136 ///
137 /// Note that this implementation does not afford any method of leveraging the
138 /// `data.drop` instruction to actually release the data back to the OS. The
139 /// data section is simply always present in the ELF image. If we wanted to
140 /// release the data it's probably best to figure out what the best
141 /// implementation is for it at the time given a particular set of constraints.
142 pub const ELF_WASM_DATA: &'static str = ".rodata.wasm";
143 
144 /// This is the name of the section in the final ELF image which contains a
145 /// `bincode`-encoded `CompiledModuleInfo`.
146 ///
147 /// This section is optionally decoded in `CompiledModule::from_artifacts`
148 /// depending on whether or not a `CompiledModuleInfo` is already available. In
149 /// cases like `Module::new` where compilation directly leads into consumption,
150 /// it's available. In cases like `Module::deserialize` this section must be
151 /// decoded to get all the relevant information.
152 pub const ELF_WASMTIME_INFO: &'static str = ".wasmtime.info";
153 
154 /// This is the name of the section in the final ELF image which contains a
155 /// concatenated list of all function names.
156 ///
157 /// This section is optionally included in the final artifact depending on
158 /// whether the wasm module has any name data at all (or in the future if we add
159 /// an option to not preserve name data). This section is a concatenated list of
160 /// strings where `CompiledModuleInfo::func_names` stores offsets/lengths into
161 /// this section.
162 ///
163 /// Note that the goal of this section is to avoid having to decode names at
164 /// module-load time if we can. Names are typically only used for debugging or
165 /// things like backtraces so there's no need to eagerly load all of them. By
166 /// storing the data in a separate section the hope is that the data, which is
167 /// sometimes quite large (3MB seen for spidermonkey-compiled-to-wasm), can be
168 /// paged in lazily from an mmap and is never paged in if we never reference it.
169 pub const ELF_NAME_DATA: &'static str = ".name.wasm";
170 
171 /// This is the name of the section in the final ELF image that contains the
172 /// concatenation of all the native DWARF information found in the original wasm
173 /// files.
174 ///
175 /// This concatenation is not intended to be read by external tools at this time
176 /// and is instead indexed directly by relative indices stored in compilation
177 /// metadata.
178 pub const ELF_WASMTIME_DWARF: &str = ".wasmtime.dwarf";
179 
180 /// This is the name of the section in the final ELF image which contains the
181 /// original Wasm bytecode for the module, preserved verbatim to support
182 /// debugger access to the source bytecode.
183 ///
184 /// This section is only emitted when the `guest-debug` tunable is enabled at
185 /// compile time. Its contents are the concatenated raw bytes of all core
186 /// module Wasm binaries in the artifact.
187 pub const ELF_WASMTIME_WASM_BYTECODE: &str = ".wasmtime.wasm_bytecode";
188 
189 /// This is the name of the companion section to [`ELF_WASMTIME_WASM_BYTECODE`]
190 /// that stores the end-offset table used to locate individual module bytecodes
191 /// within the concatenated data.
192 ///
193 /// The section contains one little-endian `u32` per core module in
194 /// the artifact giving the *end* of that module's bytecode in the
195 /// concatenated bytecode section above.
196 pub const ELF_WASMTIME_WASM_BYTECODE_ENDS: &str = ".wasmtime.wasm_bytecode_ends";
197 
198 /// Workaround to implement `core::error::Error` until
199 /// gimli-rs/object#747 is settled.
200 pub struct ObjectCrateErrorWrapper(pub object::Error);
201 
202 impl fmt::Debug for ObjectCrateErrorWrapper {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result203     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
204         self.0.fmt(f)
205     }
206 }
207 
208 impl fmt::Display for ObjectCrateErrorWrapper {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result209     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
210         self.0.fmt(f)
211     }
212 }
213 
214 impl core::error::Error for ObjectCrateErrorWrapper {}
215