1use crate::io::{Endian, ReadExt as _, WriteExt as _};
2use std::io::{Read, Write};
3
4#[derive(Debug, Clone, PartialEq, Eq)]
26pub struct UnixThreadCommand {
27 pub cmd: u32,
28 pub cmdsize: u32,
29 pub flavor: Flavor,
30 pub count: u32,
33 pub state: ThreadState,
34}
35
36impl UnixThreadCommand {
37 pub const TYPE: u32 = 0x5;
38
39 pub fn read_from_in<R: Read>(read: &mut R, endian: Endian) -> Self {
40 let cmd = read.read_u32_in(endian);
41 let cmdsize = read.read_u32_in(endian);
42 let flavor = Flavor::read_from_in(read, endian);
43 let count = read.read_u32_in(endian);
44
45 let state = match flavor {
46 Flavor::ThreadStateX86_64 => {
47 let state = StateX86_64::read_from_in(read, endian);
48 ThreadState::X86_64(state)
49 }
50 Flavor::Unknown(_) => {
51 let mut state = Vec::with_capacity(count as usize * 4);
52 state.resize(count as usize * 4, 0);
53 read.read_exact(&mut state).unwrap();
54 ThreadState::Unknown(state)
55 }
56 };
57
58 UnixThreadCommand {
59 cmd,
60 cmdsize,
61 flavor,
62 count,
63 state,
64 }
65 }
66
67 pub fn write_into<W: Write>(&self, write: &mut W) {
68 write.write_u32_native(self.cmd);
69 write.write_u32_native(self.cmdsize);
70 self.flavor.write_into(write);
71 write.write_u32_native(self.count);
72
73 match &self.state {
74 ThreadState::X86_64(state) => state.write_into(write),
75 ThreadState::Unknown(state) => write.write_all(&state).unwrap(),
76 }
77 }
78}
79
80#[derive(Debug, Clone, PartialEq, Eq)]
81pub enum Flavor {
82 ThreadStateX86_64,
83 Unknown(u32),
84}
85
86impl Flavor {
87 pub fn read_from_in<R: Read>(read: &mut R, endian: Endian) -> Self {
88 match read.read_u32_in(endian) {
89 4 => Flavor::ThreadStateX86_64,
90 n => Flavor::Unknown(n),
91 }
92 }
93
94 pub fn write_into<W: Write>(&self, write: &mut W) {
95 match self {
96 Flavor::ThreadStateX86_64 => write.write_u32_native(4),
97 Flavor::Unknown(n) => write.write_u32_native(*n),
98 }
99 }
100}
101
102#[derive(Debug, Clone, PartialEq, Eq)]
103pub enum ThreadState {
104 X86_64(StateX86_64),
105 Unknown(Vec<u8>),
106}
107
108#[derive(Debug, Clone, PartialEq, Eq)]
109pub struct StateX86_64 {
110 pub __rax: u64,
111 pub __rbx: u64,
112 pub __rcx: u64,
113 pub __rdx: u64,
114 pub __rdi: u64,
115 pub __rsi: u64,
116 pub __rbp: u64,
117 pub __rsp: u64,
118 pub __r8: u64,
119 pub __r9: u64,
120 pub __r10: u64,
121 pub __r11: u64,
122 pub __r12: u64,
123 pub __r13: u64,
124 pub __r14: u64,
125 pub __r15: u64,
126 pub __rip: u64,
127 pub __rflags: u64,
128 pub __cs: u64,
129 pub __fs: u64,
130 pub __gs: u64,
131}
132
133impl StateX86_64 {
134 pub fn read_from_in<R: Read>(read: &mut R, endian: Endian) -> Self {
135 StateX86_64 {
136 __rax: read.read_u64_in(endian),
137 __rbx: read.read_u64_in(endian),
138 __rcx: read.read_u64_in(endian),
139 __rdx: read.read_u64_in(endian),
140 __rdi: read.read_u64_in(endian),
141 __rsi: read.read_u64_in(endian),
142 __rbp: read.read_u64_in(endian),
143 __rsp: read.read_u64_in(endian),
144 __r8: read.read_u64_in(endian),
145 __r9: read.read_u64_in(endian),
146 __r10: read.read_u64_in(endian),
147 __r11: read.read_u64_in(endian),
148 __r12: read.read_u64_in(endian),
149 __r13: read.read_u64_in(endian),
150 __r14: read.read_u64_in(endian),
151 __r15: read.read_u64_in(endian),
152 __rip: read.read_u64_in(endian),
153 __rflags: read.read_u64_in(endian),
154 __cs: read.read_u64_in(endian),
155 __fs: read.read_u64_in(endian),
156 __gs: read.read_u64_in(endian),
157 }
158 }
159
160 pub fn write_into<W: Write>(&self, write: &mut W) {
161 write.write_u64_native(self.__rax);
162 write.write_u64_native(self.__rbx);
163 write.write_u64_native(self.__rcx);
164 write.write_u64_native(self.__rdx);
165 write.write_u64_native(self.__rdi);
166 write.write_u64_native(self.__rsi);
167 write.write_u64_native(self.__rbp);
168 write.write_u64_native(self.__rsp);
169 write.write_u64_native(self.__r8);
170 write.write_u64_native(self.__r9);
171 write.write_u64_native(self.__r10);
172 write.write_u64_native(self.__r11);
173 write.write_u64_native(self.__r12);
174 write.write_u64_native(self.__r13);
175 write.write_u64_native(self.__r14);
176 write.write_u64_native(self.__r15);
177 write.write_u64_native(self.__rip);
178 write.write_u64_native(self.__rflags);
179 write.write_u64_native(self.__cs);
180 write.write_u64_native(self.__fs);
181 write.write_u64_native(self.__gs);
182 }
183}