Coverage Report

Created: 2024-10-16 07:58

/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
}