near_vm_compiler/
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 crate::Relocation;
9use crate::lib::std::vec::Vec;
10use near_vm_types::entity::entity_impl;
11
12/// Index type of a Section defined inside a WebAssembly `Compilation`.
13#[derive(rkyv::Serialize, rkyv::Deserialize, rkyv::Archive)]
14#[rkyv(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug))]
15#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
16pub struct SectionIndex(u32);
17entity_impl!(SectionIndex);
18entity_impl!(ArchivedSectionIndex);
19
20/// Custom section Protection.
21///
22/// Determines how a custom section may be used.
23#[derive(rkyv::Serialize, rkyv::Deserialize, rkyv::Archive, Debug, Copy, Clone, PartialEq, Eq)]
24pub enum CustomSectionProtection {
25    /// A custom section with read permission.
26    Read,
27
28    /// A custom section with read and execute permissions.
29    ReadExecute,
30}
31
32/// A Section for a `Compilation`.
33///
34/// This is used so compilers can store arbitrary information
35/// in the emitted module.
36#[derive(rkyv::Serialize, rkyv::Deserialize, rkyv::Archive, Debug, Clone, PartialEq, Eq)]
37pub struct CustomSection {
38    /// Memory protection that applies to this section.
39    pub protection: CustomSectionProtection,
40
41    /// The bytes corresponding to this section.
42    ///
43    /// > Note: These bytes have to be at-least 8-byte aligned
44    /// > (the start of the memory pointer).
45    /// > We might need to create another field for alignment in case it's
46    /// > needed in the future.
47    pub bytes: SectionBody,
48
49    /// Relocations that apply to this custom section.
50    pub relocations: Vec<Relocation>,
51}
52
53/// See [`CustomSection`].
54///
55/// Note that this does not reference the relocation data.
56#[derive(Clone, Copy)]
57pub struct CustomSectionRef<'a> {
58    /// See [`CustomSection::protection`].
59    pub protection: CustomSectionProtection,
60
61    /// See [`CustomSection::bytes`].
62    pub bytes: &'a [u8],
63}
64
65impl<'a> From<&'a CustomSection> for CustomSectionRef<'a> {
66    fn from(section: &'a CustomSection) -> Self {
67        CustomSectionRef { protection: section.protection, bytes: section.bytes.as_slice() }
68    }
69}
70
71impl<'a> From<&'a ArchivedCustomSection> for CustomSectionRef<'a> {
72    fn from(section: &'a ArchivedCustomSection) -> Self {
73        CustomSectionRef {
74            protection: match section.protection {
75                ArchivedCustomSectionProtection::Read => CustomSectionProtection::Read,
76                ArchivedCustomSectionProtection::ReadExecute => {
77                    CustomSectionProtection::ReadExecute
78                }
79            },
80            bytes: &section.bytes.0[..],
81        }
82    }
83}
84
85/// The bytes in the section.
86#[derive(
87    rkyv::Serialize, rkyv::Deserialize, rkyv::Archive, Debug, Clone, PartialEq, Eq, Default,
88)]
89pub struct SectionBody(Vec<u8>);
90
91impl SectionBody {
92    /// Create a new section body with the given contents.
93    pub fn new_with_vec(contents: Vec<u8>) -> Self {
94        Self(contents)
95    }
96
97    /// Returns a raw pointer to the section's buffer.
98    pub fn as_ptr(&self) -> *const u8 {
99        self.0.as_ptr()
100    }
101
102    /// Returns the length of this section in bytes.
103    pub fn len(&self) -> usize {
104        self.0.len()
105    }
106
107    /// Dereferences into the section's buffer.
108    pub fn as_slice(&self) -> &[u8] {
109        self.0.as_slice()
110    }
111
112    /// Returns whether or not the section body is empty.
113    pub fn is_empty(&self) -> bool {
114        self.0.is_empty()
115    }
116}