1use x86defs::SegmentRegister;
7
8#[repr(usize)]
9#[derive(Debug, Copy, Clone, PartialEq)]
10#[expect(clippy::upper_case_acronyms)]
11pub enum Gp {
12 RAX = 0,
13 RCX = 1,
14 RDX = 2,
15 RBX = 3,
16 RSP = 4,
17 RBP = 5,
18 RSI = 6,
19 RDI = 7,
20 R8 = 8,
21 R9 = 9,
22 R10 = 10,
23 R11 = 11,
24 R12 = 12,
25 R13 = 13,
26 R14 = 14,
27 R15 = 15,
28}
29
30#[derive(Debug, Copy, Clone)]
31#[expect(clippy::upper_case_acronyms)]
32pub enum GpSize {
33 BYTE(usize),
35 WORD,
36 DWORD,
37 QWORD,
38}
39
40#[repr(usize)]
41#[derive(Debug, Copy, Clone)]
42pub enum Segment {
43 ES = 0,
44 CS = 1,
45 SS = 2,
46 DS = 3,
47 FS = 4,
48 GS = 5,
49}
50
51#[derive(Debug, Copy, Clone)]
52pub struct RegisterIndex {
53 pub extended_index: Gp,
55 pub size: GpSize,
57}
58
59impl RegisterIndex {
60 pub fn apply_sizing(&self, v: u64) -> u64 {
63 match self.size {
64 GpSize::BYTE(shift) => ((v >> shift) as u8).into(),
65 GpSize::WORD => (v as u16).into(),
66 GpSize::DWORD => (v as u32).into(),
67 GpSize::QWORD => v,
68 }
69 }
70
71 pub fn apply_sizing_signed(&self, v: u64) -> i64 {
72 match self.size {
73 GpSize::BYTE(shift) => ((v >> shift) as i8).into(),
74 GpSize::WORD => (v as i16).into(),
75 GpSize::DWORD => (v as i32).into(),
76 GpSize::QWORD => v as i64,
77 }
78 }
79
80 pub fn apply_update(&self, extended_register: u64, v: u64) -> u64 {
81 match self.size {
82 GpSize::BYTE(shift) => {
83 let mask = !(0xff << shift);
84 (extended_register & mask) | (((v as u8) as u64) << shift)
85 }
86 GpSize::WORD => (extended_register & !0xffff) | (v as u16) as u64,
87 GpSize::DWORD => (v as u32) as u64,
90 GpSize::QWORD => v,
91 }
92 }
93}
94
95impl From<Gp> for RegisterIndex {
96 fn from(val: Gp) -> Self {
97 RegisterIndex {
98 extended_index: val,
99 size: GpSize::QWORD,
100 }
101 }
102}
103
104pub(crate) fn bitness(cr0: u64, efer: u64, cs: SegmentRegister) -> Bitness {
105 if cr0 & x86defs::X64_CR0_PE != 0 {
106 if efer & x86defs::X64_EFER_LMA != 0 {
107 if cs.attributes.long() {
108 Bitness::Bit64
109 } else {
110 Bitness::Bit32
111 }
112 } else {
113 if cs.attributes.default() {
114 Bitness::Bit32
115 } else {
116 Bitness::Bit16
117 }
118 }
119 } else {
120 Bitness::Bit16
121 }
122}
123
124#[derive(Debug, Clone, Copy, PartialEq)]
125pub(crate) enum Bitness {
126 Bit64,
127 Bit32,
128 Bit16,
129}
130
131impl From<Bitness> for u32 {
132 fn from(bitness: Bitness) -> u32 {
133 match bitness {
134 Bitness::Bit64 => 64,
135 Bitness::Bit32 => 32,
136 Bitness::Bit16 => 16,
137 }
138 }
139}