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