corevm_engine/
program_data.rs1use core::ops::Range;
2use corevm_host::PAGE_SIZE;
3use polkavm::{ArcBytes, MemoryMap};
4
5pub struct ProgramData {
9 address_ranges: [Range<u64>; 4],
10 pub ro_data: ArcBytes,
11 pub rw_data: ArcBytes,
12}
13
14impl ProgramData {
15 pub fn new(memory_map: &MemoryMap, ro_data: ArcBytes, rw_data: ArcBytes) -> Self {
16 let heap_start = (memory_map.heap_base() as u64).next_multiple_of(PAGE_SIZE);
17 let heap_end = heap_start + memory_map.max_heap_size() as u64;
18 let heap_range = heap_start..heap_end;
19 let stack_range = memory_map.stack_range();
20 let stack_range = (stack_range.start as u64)..(stack_range.end as u64);
21 let ro_data_range = memory_map.ro_data_range();
22 let ro_data_range = (ro_data_range.start as u64)..(ro_data_range.end as u64);
23 let rw_data_range = memory_map.rw_data_range();
24 let rw_data_range = (rw_data_range.start as u64)..(rw_data_range.end as u64);
25 assert!(ro_data.len() as u64 <= ro_data_range.end - ro_data_range.start);
27 assert!(rw_data.len() as u64 <= rw_data_range.end - rw_data_range.start);
28 Self {
29 address_ranges: [ro_data_range, rw_data_range, stack_range, heap_range],
30 ro_data,
31 rw_data,
32 }
33 }
34
35 pub fn classify_address(&self, address: u64) -> Option<AddressKind> {
37 AddressKind::ALL
38 .into_iter()
39 .find(|&kind| self.address_ranges[kind as usize].contains(&address))
40 }
41
42 pub fn address_range(&self, kind: AddressKind) -> &Range<u64> {
43 &self.address_ranges[kind as usize]
44 }
45
46 pub fn stack_range(&self) -> &Range<u64> {
48 self.address_range(AddressKind::Stack)
49 }
50
51 pub fn heap_range(&self) -> &Range<u64> {
53 self.address_range(AddressKind::Heap)
54 }
55
56 pub fn ro_data_range(&self) -> &Range<u64> {
58 self.address_range(AddressKind::RoData)
59 }
60
61 pub fn rw_data_range(&self) -> &Range<u64> {
63 self.address_range(AddressKind::RwData)
64 }
65}
66
67#[derive(Clone, Copy, PartialEq, Eq)]
69pub enum AddressKind {
70 RoData = 0,
71 RwData = 1,
72 Stack = 2,
73 Heap = 3,
74}
75
76impl AddressKind {
77 pub const ALL: [Self; 4] = [Self::RoData, Self::RwData, Self::Stack, Self::Heap];
78}
79
80impl core::fmt::Debug for AddressKind {
81 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
82 let s = match self {
83 Self::RoData => "ro",
84 Self::RwData => "rw",
85 Self::Stack => "stack",
86 Self::Heap => "heap",
87 };
88 f.write_str(s)
89 }
90}