/src/wasmer/lib/types/src/compilation/symbols.rs
Line | Count | Source (jump to first uncovered line) |
1 | | //! This module define the required structures for compilation symbols. |
2 | | use crate::{ |
3 | | entity::{EntityRef, PrimaryMap}, |
4 | | CompileModuleInfo, DeserializeError, FunctionIndex, LocalFunctionIndex, OwnedDataInitializer, |
5 | | SectionIndex, SerializeError, SignatureIndex, |
6 | | }; |
7 | | use rkyv::{ |
8 | | archived_value, check_archived_value, de::deserializers::SharedDeserializeMap, |
9 | | ser::serializers::AllocSerializer, ser::Serializer as RkyvSerializer, Archive, |
10 | | Deserialize as RkyvDeserialize, Serialize as RkyvSerialize, |
11 | | }; |
12 | | #[cfg(feature = "enable-serde")] |
13 | | use serde::{Deserialize, Serialize}; |
14 | | |
15 | | /// The kinds of wasmer_types objects that might be found in a native object file. |
16 | | #[derive( |
17 | 0 | RkyvSerialize, RkyvDeserialize, Archive, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Unexecuted instantiation: <wasmer_types::compilation::symbols::Symbol as rkyv::Serialize<_>>::serialize Unexecuted instantiation: <wasmer_types::compilation::symbols::Symbol as rkyv::Serialize<_>>::serialize Unexecuted instantiation: <wasmer_types::compilation::symbols::Symbol as rkyv::Deserialize<wasmer_types::compilation::symbols::Symbol, _>>::deserialize Unexecuted instantiation: <wasmer_types::compilation::symbols::Symbol as rkyv::Deserialize<wasmer_types::compilation::symbols::Symbol, _>>::deserialize Unexecuted instantiation: <wasmer_types::compilation::symbols::Symbol as rkyv::Archive>::resolve Unexecuted instantiation: <wasmer_types::compilation::symbols::Symbol as rkyv::Archive>::resolve |
18 | | )] |
19 | | #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] |
20 | | #[archive(as = "Self")] |
21 | | pub enum Symbol { |
22 | | /// A metadata section, indexed by a unique prefix |
23 | | /// (usually the wasm file SHA256 hash) |
24 | | Metadata, |
25 | | |
26 | | /// A function defined in the wasm. |
27 | | LocalFunction(LocalFunctionIndex), |
28 | | |
29 | | /// A wasm section. |
30 | | Section(SectionIndex), |
31 | | |
32 | | /// The function call trampoline for a given signature. |
33 | | FunctionCallTrampoline(SignatureIndex), |
34 | | |
35 | | /// The dynamic function trampoline for a given function. |
36 | | DynamicFunctionTrampoline(FunctionIndex), |
37 | | } |
38 | | |
39 | | /// This trait facilitates symbol name lookups in a native object file. |
40 | | pub trait SymbolRegistry: Send + Sync { |
41 | | /// Given a `Symbol` it returns the name for that symbol in the object file |
42 | | fn symbol_to_name(&self, symbol: Symbol) -> String; |
43 | | |
44 | | /// Given a name it returns the `Symbol` for that name in the object file |
45 | | /// |
46 | | /// This function is the inverse of [`SymbolRegistry::symbol_to_name`] |
47 | | fn name_to_symbol(&self, name: &str) -> Option<Symbol>; |
48 | | } |
49 | | |
50 | | /// Serializable struct that represents the compiled metadata. |
51 | 0 | #[derive(Debug, RkyvSerialize, RkyvDeserialize, Archive)] Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadata as rkyv::Serialize<rkyv::ser::serializers::CompositeSerializer<rkyv::ser::serializers::alloc::AlignedSerializer<rkyv::util::aligned_vec::AlignedVec>, rkyv::ser::serializers::core::FallbackScratch<rkyv::ser::serializers::alloc::HeapScratch<4096>, rkyv::ser::serializers::alloc::AllocScratch>, rkyv::ser::serializers::alloc::SharedSerializeMap>>>::serialize Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadata as rkyv::Serialize<rkyv::ser::serializers::CompositeSerializer<rkyv::ser::serializers::alloc::AlignedSerializer<rkyv::util::aligned_vec::AlignedVec>, rkyv::ser::serializers::core::FallbackScratch<rkyv::ser::serializers::alloc::HeapScratch<4096>, rkyv::ser::serializers::alloc::AllocScratch>, rkyv::ser::serializers::alloc::SharedSerializeMap>>>::serialize Unexecuted instantiation: <wasmer_types::compilation::symbols::ArchivedModuleMetadata as rkyv::Deserialize<wasmer_types::compilation::symbols::ModuleMetadata, rkyv::de::deserializers::alloc::SharedDeserializeMap>>::deserialize Unexecuted instantiation: <wasmer_types::compilation::symbols::ArchivedModuleMetadata as rkyv::Deserialize<wasmer_types::compilation::symbols::ModuleMetadata, rkyv::de::deserializers::alloc::SharedDeserializeMap>>::deserialize Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadata as rkyv::Archive>::resolve Unexecuted instantiation: <wasmer_types::compilation::symbols::ArchivedModuleMetadata as bytecheck::CheckBytes<rkyv::validation::validators::DefaultValidator>>::check_bytes::{closure#4}Unexecuted instantiation: <wasmer_types::compilation::symbols::ArchivedModuleMetadata as bytecheck::CheckBytes<rkyv::validation::validators::DefaultValidator>>::check_bytes::{closure#3}Unexecuted instantiation: <wasmer_types::compilation::symbols::ArchivedModuleMetadata as bytecheck::CheckBytes<rkyv::validation::validators::DefaultValidator>>::check_bytes::{closure#2}Unexecuted instantiation: <wasmer_types::compilation::symbols::ArchivedModuleMetadata as bytecheck::CheckBytes<rkyv::validation::validators::DefaultValidator>>::check_bytes::{closure#1}Unexecuted instantiation: <wasmer_types::compilation::symbols::ArchivedModuleMetadata as bytecheck::CheckBytes<rkyv::validation::validators::DefaultValidator>>::check_bytes::{closure#0}Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadata as rkyv::Archive>::resolve Unexecuted instantiation: <wasmer_types::compilation::symbols::ArchivedModuleMetadata as bytecheck::CheckBytes<rkyv::validation::validators::DefaultValidator>>::check_bytes::{closure#4}Unexecuted instantiation: <wasmer_types::compilation::symbols::ArchivedModuleMetadata as bytecheck::CheckBytes<rkyv::validation::validators::DefaultValidator>>::check_bytes::{closure#3}Unexecuted instantiation: <wasmer_types::compilation::symbols::ArchivedModuleMetadata as bytecheck::CheckBytes<rkyv::validation::validators::DefaultValidator>>::check_bytes::{closure#2}Unexecuted instantiation: <wasmer_types::compilation::symbols::ArchivedModuleMetadata as bytecheck::CheckBytes<rkyv::validation::validators::DefaultValidator>>::check_bytes::{closure#1}Unexecuted instantiation: <wasmer_types::compilation::symbols::ArchivedModuleMetadata as bytecheck::CheckBytes<rkyv::validation::validators::DefaultValidator>>::check_bytes::{closure#0} |
52 | | #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] |
53 | | #[archive_attr(derive(rkyv::CheckBytes, Debug))] |
54 | | pub struct ModuleMetadata { |
55 | | /// Compile info |
56 | | pub compile_info: CompileModuleInfo, |
57 | | /// Prefix for function etc symbols |
58 | | pub prefix: String, |
59 | | /// Data initializers |
60 | | pub data_initializers: Box<[OwnedDataInitializer]>, |
61 | | /// The function body lengths (used to find function by address) |
62 | | pub function_body_lengths: PrimaryMap<LocalFunctionIndex, u64>, |
63 | | /// CPU features used (See [`CpuFeature`](crate::CpuFeature)) |
64 | | pub cpu_features: u64, |
65 | | } |
66 | | |
67 | | /// A simple metadata registry |
68 | | pub struct ModuleMetadataSymbolRegistry { |
69 | | /// Symbol prefix stirng |
70 | | pub prefix: String, |
71 | | } |
72 | | |
73 | | impl ModuleMetadata { |
74 | | /// Get mutable ref to compile info and a copy of the registry |
75 | 0 | pub fn split(&mut self) -> (&mut CompileModuleInfo, ModuleMetadataSymbolRegistry) { |
76 | 0 | let compile_info = &mut self.compile_info; |
77 | 0 | let symbol_registry = ModuleMetadataSymbolRegistry { |
78 | 0 | prefix: self.prefix.clone(), |
79 | 0 | }; |
80 | 0 | (compile_info, symbol_registry) |
81 | 0 | } Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadata>::split Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadata>::split |
82 | | |
83 | | /// Returns symbol registry. |
84 | 0 | pub fn get_symbol_registry(&self) -> ModuleMetadataSymbolRegistry { |
85 | 0 | ModuleMetadataSymbolRegistry { |
86 | 0 | prefix: self.prefix.clone(), |
87 | 0 | } |
88 | 0 | } Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadata>::get_symbol_registry Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadata>::get_symbol_registry |
89 | | /// Serialize a Module into bytes |
90 | | /// The bytes will have the following format: |
91 | | /// RKYV serialization (any length) + POS (8 bytes) |
92 | 0 | pub fn serialize(&self) -> Result<Vec<u8>, SerializeError> { |
93 | 0 | let mut serializer = AllocSerializer::<4096>::default(); |
94 | 0 | let pos = serializer |
95 | 0 | .serialize_value(self) |
96 | 0 | .map_err(|err| SerializeError::Generic(format!("{}", err)))? as u64;Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadata>::serialize::{closure#0}Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadata>::serialize::{closure#0} |
97 | 0 | let mut serialized_data = serializer.into_serializer().into_inner(); |
98 | 0 | serialized_data.extend_from_slice(&pos.to_le_bytes()); |
99 | 0 | Ok(serialized_data.to_vec()) |
100 | 0 | } Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadata>::serialize Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadata>::serialize |
101 | | |
102 | | /// Deserialize a Module from a slice. |
103 | | /// The slice must have the following format: |
104 | | /// RKYV serialization (any length) + POS (8 bytes) |
105 | | /// |
106 | | /// # Safety |
107 | | /// |
108 | | /// This method is unsafe since it deserializes data directly |
109 | | /// from memory. |
110 | | /// Right now we are not doing any extra work for validation, but |
111 | | /// `rkyv` has an option to do bytecheck on the serialized data before |
112 | | /// serializing (via `rkyv::check_archived_value`). |
113 | 0 | pub unsafe fn deserialize_unchecked(metadata_slice: &[u8]) -> Result<Self, DeserializeError> { |
114 | 0 | let archived = Self::archive_from_slice(metadata_slice)?; |
115 | 0 | Self::deserialize_from_archive(archived) |
116 | 0 | } Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadata>::deserialize_unchecked Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadata>::deserialize_unchecked |
117 | | |
118 | | /// Deserialize a Module from a slice. |
119 | | /// The slice must have the following format: |
120 | | /// RKYV serialization (any length) + POS (8 bytes) |
121 | 0 | pub fn deserialize(metadata_slice: &[u8]) -> Result<Self, DeserializeError> { |
122 | 0 | let archived = Self::archive_from_slice_checked(metadata_slice)?; |
123 | 0 | Self::deserialize_from_archive(archived) |
124 | 0 | } Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadata>::deserialize Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadata>::deserialize |
125 | | |
126 | | /// # Safety |
127 | | /// |
128 | | /// This method is unsafe. |
129 | | /// Please check `ModuleMetadata::deserialize` for more details. |
130 | 0 | unsafe fn archive_from_slice( |
131 | 0 | metadata_slice: &[u8], |
132 | 0 | ) -> Result<&ArchivedModuleMetadata, DeserializeError> { |
133 | 0 | if metadata_slice.len() < 8 { |
134 | 0 | return Err(DeserializeError::Incompatible( |
135 | 0 | "invalid serialized ModuleMetadata".into(), |
136 | 0 | )); |
137 | 0 | } |
138 | 0 | let mut pos: [u8; 8] = Default::default(); |
139 | 0 | pos.copy_from_slice(&metadata_slice[metadata_slice.len() - 8..metadata_slice.len()]); |
140 | 0 | let pos: u64 = u64::from_le_bytes(pos); |
141 | 0 | Ok(archived_value::<Self>( |
142 | 0 | &metadata_slice[..metadata_slice.len() - 8], |
143 | 0 | pos as usize, |
144 | 0 | )) |
145 | 0 | } Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadata>::archive_from_slice Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadata>::archive_from_slice |
146 | | |
147 | | /// # Safety |
148 | | /// |
149 | | /// This method is unsafe. |
150 | | /// Please check `ModuleMetadata::deserialize` for more details. |
151 | 0 | fn archive_from_slice_checked( |
152 | 0 | metadata_slice: &[u8], |
153 | 0 | ) -> Result<&ArchivedModuleMetadata, DeserializeError> { |
154 | 0 | if metadata_slice.len() < 8 { |
155 | 0 | return Err(DeserializeError::Incompatible( |
156 | 0 | "invalid serialized ModuleMetadata".into(), |
157 | 0 | )); |
158 | 0 | } |
159 | 0 | let mut pos: [u8; 8] = Default::default(); |
160 | 0 | pos.copy_from_slice(&metadata_slice[metadata_slice.len() - 8..metadata_slice.len()]); |
161 | 0 | let pos: u64 = u64::from_le_bytes(pos); |
162 | 0 | check_archived_value::<Self>(&metadata_slice[..metadata_slice.len() - 8], pos as usize) |
163 | 0 | .map_err(|e| DeserializeError::CorruptedBinary(e.to_string())) Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadata>::archive_from_slice_checked::{closure#0}Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadata>::archive_from_slice_checked::{closure#0} |
164 | 0 | } Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadata>::archive_from_slice_checked Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadata>::archive_from_slice_checked |
165 | | |
166 | | /// Deserialize a compilation module from an archive |
167 | 0 | pub fn deserialize_from_archive( |
168 | 0 | archived: &ArchivedModuleMetadata, |
169 | 0 | ) -> Result<Self, DeserializeError> { |
170 | 0 | let mut deserializer = SharedDeserializeMap::new(); |
171 | 0 | RkyvDeserialize::deserialize(archived, &mut deserializer) |
172 | 0 | .map_err(|e| DeserializeError::CorruptedBinary(format!("{:?}", e)))Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadata>::deserialize_from_archive::{closure#0}Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadata>::deserialize_from_archive::{closure#0} |
173 | 0 | } Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadata>::deserialize_from_archive Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadata>::deserialize_from_archive |
174 | | } |
175 | | |
176 | | impl SymbolRegistry for ModuleMetadataSymbolRegistry { |
177 | 0 | fn symbol_to_name(&self, symbol: Symbol) -> String { |
178 | 0 | match symbol { |
179 | | Symbol::Metadata => { |
180 | 0 | format!("WASMER_METADATA_{}", self.prefix.to_uppercase()) |
181 | | } |
182 | 0 | Symbol::LocalFunction(index) => { |
183 | 0 | format!("wasmer_function_{}_{}", self.prefix, index.index()) |
184 | | } |
185 | 0 | Symbol::Section(index) => format!("wasmer_section_{}_{}", self.prefix, index.index()), |
186 | 0 | Symbol::FunctionCallTrampoline(index) => { |
187 | 0 | format!( |
188 | 0 | "wasmer_trampoline_function_call_{}_{}", |
189 | 0 | self.prefix, |
190 | 0 | index.index() |
191 | 0 | ) |
192 | | } |
193 | 0 | Symbol::DynamicFunctionTrampoline(index) => { |
194 | 0 | format!( |
195 | 0 | "wasmer_trampoline_dynamic_function_{}_{}", |
196 | 0 | self.prefix, |
197 | 0 | index.index() |
198 | 0 | ) |
199 | | } |
200 | | } |
201 | 0 | } Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadataSymbolRegistry as wasmer_types::compilation::symbols::SymbolRegistry>::symbol_to_name Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadataSymbolRegistry as wasmer_types::compilation::symbols::SymbolRegistry>::symbol_to_name |
202 | | |
203 | 0 | fn name_to_symbol(&self, name: &str) -> Option<Symbol> { |
204 | 0 | if name == self.symbol_to_name(Symbol::Metadata) { |
205 | 0 | Some(Symbol::Metadata) |
206 | 0 | } else if let Some(index) = name.strip_prefix(&format!("wasmer_function_{}_", self.prefix)) |
207 | | { |
208 | 0 | index |
209 | 0 | .parse::<u32>() |
210 | 0 | .ok() |
211 | 0 | .map(|index| Symbol::LocalFunction(LocalFunctionIndex::from_u32(index))) Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadataSymbolRegistry as wasmer_types::compilation::symbols::SymbolRegistry>::name_to_symbol::{closure#0}Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadataSymbolRegistry as wasmer_types::compilation::symbols::SymbolRegistry>::name_to_symbol::{closure#0} |
212 | 0 | } else if let Some(index) = name.strip_prefix(&format!("wasmer_section_{}_", self.prefix)) { |
213 | 0 | index |
214 | 0 | .parse::<u32>() |
215 | 0 | .ok() |
216 | 0 | .map(|index| Symbol::Section(SectionIndex::from_u32(index))) Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadataSymbolRegistry as wasmer_types::compilation::symbols::SymbolRegistry>::name_to_symbol::{closure#1}Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadataSymbolRegistry as wasmer_types::compilation::symbols::SymbolRegistry>::name_to_symbol::{closure#1} |
217 | 0 | } else if let Some(index) = |
218 | 0 | name.strip_prefix(&format!("wasmer_trampoline_function_call_{}_", self.prefix)) |
219 | | { |
220 | 0 | index |
221 | 0 | .parse::<u32>() |
222 | 0 | .ok() |
223 | 0 | .map(|index| Symbol::FunctionCallTrampoline(SignatureIndex::from_u32(index))) Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadataSymbolRegistry as wasmer_types::compilation::symbols::SymbolRegistry>::name_to_symbol::{closure#2}Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadataSymbolRegistry as wasmer_types::compilation::symbols::SymbolRegistry>::name_to_symbol::{closure#2} |
224 | 0 | } else if let Some(index) = name.strip_prefix(&format!( |
225 | 0 | "wasmer_trampoline_dynamic_function_{}_", |
226 | 0 | self.prefix |
227 | 0 | )) { |
228 | 0 | index |
229 | 0 | .parse::<u32>() |
230 | 0 | .ok() |
231 | 0 | .map(|index| Symbol::DynamicFunctionTrampoline(FunctionIndex::from_u32(index))) Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadataSymbolRegistry as wasmer_types::compilation::symbols::SymbolRegistry>::name_to_symbol::{closure#3}Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadataSymbolRegistry as wasmer_types::compilation::symbols::SymbolRegistry>::name_to_symbol::{closure#3} |
232 | | } else { |
233 | 0 | None |
234 | | } |
235 | 0 | } Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadataSymbolRegistry as wasmer_types::compilation::symbols::SymbolRegistry>::name_to_symbol Unexecuted instantiation: <wasmer_types::compilation::symbols::ModuleMetadataSymbolRegistry as wasmer_types::compilation::symbols::SymbolRegistry>::name_to_symbol |
236 | | } |