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