wasmer_compiler/types/
section.rs

1/*
2 * ! Remove me once rkyv generates doc-comments for fields or generates an #[allow(missing_docs)]
3 * on their own.
4 */
5#![allow(missing_docs)]
6
7//! This module define the required structures to emit custom
8//! Sections in a `Compilation`.
9//!
10//! The functions that access a custom [`CustomSection`] would need
11//! to emit a custom relocation: `RelocationTarget::CustomSection`, so
12//! it can be patched later by the engine (native or JIT).
13
14use super::relocation::{ArchivedRelocation, Relocation, RelocationLike};
15use crate::lib::std::vec::Vec;
16use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
17#[cfg(feature = "enable-serde")]
18use serde::{Deserialize, Serialize};
19use wasmer_types::entity_impl;
20
21/// Index type of a Section defined inside a WebAssembly `Compilation`.
22#[derive(
23    RkyvSerialize,
24    RkyvDeserialize,
25    Archive,
26    Copy,
27    Clone,
28    PartialEq,
29    Eq,
30    Hash,
31    PartialOrd,
32    Ord,
33    Debug,
34    Default,
35)]
36#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
37#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
38#[rkyv(derive(Debug, Hash, PartialEq, Eq), compare(PartialEq, PartialOrd))]
39pub struct SectionIndex(u32);
40
41entity_impl!(SectionIndex);
42
43/// Custom section Protection.
44///
45/// Determines how a custom section may be used.
46#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
47#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
48#[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, Clone, PartialEq, Eq)]
49#[rkyv(derive(Debug), compare(PartialEq, PartialOrd))]
50#[repr(u8)]
51pub enum CustomSectionProtection {
52    /// A custom section with read permission.
53    Read,
54
55    /// A custom section with read and execute permissions.
56    ReadExecute,
57}
58
59/// A Section for a `Compilation`.
60///
61/// This is used so compilers can store arbitrary information
62/// in the emitted module.
63#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
64#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
65#[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, Clone, PartialEq, Eq)]
66#[rkyv(derive(Debug), compare(PartialEq))]
67pub struct CustomSection {
68    /// Memory protection that applies to this section.
69    pub protection: CustomSectionProtection,
70
71    /// The bytes corresponding to this section.
72    ///
73    /// > Note: These bytes have to be at-least 8-byte aligned
74    /// > (the start of the memory pointer).
75    /// > We might need to create another field for alignment in case it's
76    /// > needed in the future.
77    pub bytes: SectionBody,
78
79    /// Relocations that apply to this custom section.
80    pub relocations: Vec<Relocation>,
81}
82
83/// Any struct that acts like a `CustomSection`.
84#[allow(missing_docs)]
85pub trait CustomSectionLike<'a> {
86    type Relocations: RelocationLike;
87
88    fn protection(&self) -> CustomSectionProtection;
89    fn bytes(&self) -> &[u8];
90    fn relocations(&'a self) -> &[Self::Relocations];
91}
92
93impl<'a> CustomSectionLike<'a> for CustomSection {
94    type Relocations = Relocation;
95
96    fn protection(&self) -> CustomSectionProtection {
97        self.protection.clone()
98    }
99
100    fn bytes(&self) -> &[u8] {
101        self.bytes.0.as_ref()
102    }
103
104    fn relocations(&'a self) -> &[Self::Relocations] {
105        self.relocations.as_slice()
106    }
107}
108
109impl<'a> CustomSectionLike<'a> for ArchivedCustomSection {
110    type Relocations = ArchivedRelocation;
111
112    fn protection(&self) -> CustomSectionProtection {
113        let protection = rkyv::deserialize::<CustomSectionProtection, ()>(&self.protection);
114        protection.unwrap()
115    }
116
117    fn bytes(&self) -> &[u8] {
118        self.bytes.0.as_ref()
119    }
120
121    fn relocations(&'a self) -> &[Self::Relocations] {
122        self.relocations.as_slice()
123    }
124}
125
126/// The bytes in the section.
127#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
128#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
129#[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, Clone, PartialEq, Eq, Default)]
130#[rkyv(derive(Debug), compare(PartialEq, PartialOrd))]
131pub struct SectionBody(#[cfg_attr(feature = "enable-serde", serde(with = "serde_bytes"))] Vec<u8>);
132
133impl SectionBody {
134    /// Create a new section body with the given contents.
135    pub fn new_with_vec(contents: Vec<u8>) -> Self {
136        Self(contents)
137    }
138
139    /// Returns a raw pointer to the section's buffer.
140    pub fn as_ptr(&self) -> *const u8 {
141        self.0.as_ptr()
142    }
143
144    /// Returns the length of this section in bytes.
145    pub fn len(&self) -> usize {
146        self.0.len()
147    }
148
149    /// Dereferences into the section's buffer.
150    pub fn as_slice(&self) -> &[u8] {
151        self.0.as_slice()
152    }
153
154    /// Returns whether or not the section body is empty.
155    pub fn is_empty(&self) -> bool {
156        self.0.is_empty()
157    }
158}
159
160impl ArchivedSectionBody {
161    /// Returns the length of this section in bytes.
162    pub fn len(&self) -> usize {
163        self.0.len()
164    }
165
166    /// Returns whether or not the section body is empty.
167    pub fn is_empty(&self) -> bool {
168        self.0.is_empty()
169    }
170}