wasmer_types/compilation/
section.rs

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