memflow/architecture/x86/
mod.rs1pub mod x32;
2pub mod x32_pae;
3pub mod x64;
4
5use super::{Architecture, ArchitectureIdent, ArchitectureObj, Endianess};
6
7use crate::mem::virt_translate::{
8 mmu::ArchMmuSpec, VirtualTranslate3, VtopFailureCallback, VtopOutputCallback,
9};
10
11use crate::error::{Error, ErrorKind, ErrorOrigin, Result};
12use crate::iter::SplitAtIndex;
13use crate::mem::PhysicalMemory;
14use crate::types::{umem, Address};
15use cglue::tuple::*;
16
17use std::ptr;
18
19pub struct X86Architecture {
20 bits: u8,
22 mmu: ArchMmuSpec,
24}
25
26impl Architecture for X86Architecture {
27 fn bits(&self) -> u8 {
28 self.bits
29 }
30
31 fn endianess(&self) -> Endianess {
32 self.mmu.def.endianess
33 }
34
35 fn page_size(&self) -> usize {
36 self.mmu.page_size_level(1) as usize
37 }
38
39 fn size_addr(&self) -> usize {
40 self.mmu.def.addr_size.into()
41 }
42
43 fn address_space_bits(&self) -> u8 {
44 self.mmu.def.address_space_bits
45 }
46
47 fn ident(&self) -> ArchitectureIdent {
48 ArchitectureIdent::X86(
49 self.bits,
50 ptr::eq(self as *const _, &x32_pae::ARCH_SPEC as *const _),
51 )
52 }
53}
54
55#[derive(Clone, Copy)]
56pub struct X86VirtualTranslate {
57 arch: &'static X86Architecture,
58 dtb: Address,
59}
60
61impl X86VirtualTranslate {
62 pub fn new(arch: &'static X86Architecture, dtb: Address) -> Self {
63 Self { arch, dtb }
64 }
65}
66
67impl VirtualTranslate3 for X86VirtualTranslate {
68 fn virt_to_phys_iter<
69 T: PhysicalMemory + ?Sized,
70 B: SplitAtIndex,
71 VI: Iterator<Item = CTup3<Address, Address, B>>,
72 >(
73 &self,
74 mem: &mut T,
75 addrs: VI,
76 out: &mut VtopOutputCallback<B>,
77 out_fail: &mut VtopFailureCallback<B>,
78 tmp_buf: &mut [std::mem::MaybeUninit<u8>],
79 ) {
80 self.arch
81 .mmu
82 .virt_to_phys_iter(mem, self.dtb, addrs, out, out_fail, tmp_buf)
83 }
84
85 fn translation_table_id(&self, _address: Address) -> umem {
86 self.dtb.to_umem().overflowing_shr(12).0
87 }
88
89 fn arch(&self) -> ArchitectureObj {
90 self.arch
91 }
92}
93
94fn underlying_arch(arch: ArchitectureObj) -> Option<&'static X86Architecture> {
97 if arch == x64::ARCH {
98 Some(&x64::ARCH_SPEC)
99 } else if arch == x32::ARCH {
100 Some(&x32::ARCH_SPEC)
101 } else if arch == x32_pae::ARCH {
102 Some(&x32_pae::ARCH_SPEC)
103 } else {
104 None
105 }
106}
107
108pub fn new_translator(dtb: Address, arch: ArchitectureObj) -> Result<X86VirtualTranslate> {
109 let arch =
110 underlying_arch(arch).ok_or(Error(ErrorOrigin::Mmu, ErrorKind::InvalidArchitecture))?;
111 Ok(X86VirtualTranslate::new(arch, dtb))
112}
113
114pub fn is_x86_arch(arch: ArchitectureObj) -> bool {
115 underlying_arch(arch).is_some()
116}