@@ -5,7 +5,14 @@ use capstone::{
55 prelude:: * ,
66} ;
77use edbgserver_common:: DataT ;
8- use gdbstub_arch:: x86:: reg:: X86_64CoreRegs ;
8+ use gdbstub:: {
9+ common:: Tid ,
10+ target:: { TargetError , TargetResult , ext:: base:: single_register_access:: SingleRegisterAccess } ,
11+ } ;
12+ use gdbstub_arch:: x86:: reg:: {
13+ X86_64CoreRegs ,
14+ id:: { X86_64CoreRegId , X86SegmentRegId } ,
15+ } ;
916use log:: { debug, error, trace, warn} ;
1017
1118use crate :: target:: EdbgTarget ;
@@ -32,6 +39,79 @@ pub fn fill_regs(regs: &mut X86_64CoreRegs, ctx: &DataT) {
3239 regs. eflags = ctx. eflags as u32 ;
3340}
3441
42+ impl SingleRegisterAccess < Tid > for EdbgTarget {
43+ fn read_register (
44+ & mut self ,
45+ tid : Tid ,
46+ reg_id : <Self :: Arch as gdbstub:: arch:: Arch >:: RegId ,
47+ buf : & mut [ u8 ] ,
48+ ) -> TargetResult < usize , Self > {
49+ let ctx = match & self . context {
50+ Some ( c) if !self . is_multi_thread || c. tid == tid. get ( ) as u32 => c,
51+ _ => {
52+ warn ! ( "read_register: no context with tid {}" , tid. get( ) ) ;
53+ return Ok ( 0 ) ;
54+ }
55+ } ;
56+
57+ match reg_id {
58+ X86_64CoreRegId :: Gpr ( i) => {
59+ // RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP, r8-r15
60+ let val = match i {
61+ 0 => ctx. rax ,
62+ 1 => ctx. rbx ,
63+ 2 => ctx. rcx ,
64+ 3 => ctx. rdx ,
65+ 4 => ctx. rsi ,
66+ 5 => ctx. rdi ,
67+ 6 => ctx. rbp ,
68+ 7 => ctx. rsp ,
69+ 8 => ctx. r8 ,
70+ 9 => ctx. r9 ,
71+ 10 => ctx. r10 ,
72+ 11 => ctx. r11 ,
73+ 12 => ctx. r12 ,
74+ 13 => ctx. r13 ,
75+ 14 => ctx. r14 ,
76+ 15 => ctx. r15 ,
77+ _ => return Ok ( 0 ) ,
78+ } ;
79+ buf. copy_from_slice ( & val. to_le_bytes ( ) ) ;
80+ Ok ( 8 )
81+ }
82+ X86_64CoreRegId :: Rip => {
83+ buf. copy_from_slice ( & ctx. rip . to_le_bytes ( ) ) ;
84+ Ok ( 8 )
85+ }
86+ X86_64CoreRegId :: Eflags => {
87+ let val = ctx. eflags as u32 ;
88+ buf. copy_from_slice ( & val. to_le_bytes ( ) ) ;
89+ Ok ( 4 )
90+ }
91+ X86_64CoreRegId :: Segment ( segments) => {
92+ let val = match segments {
93+ X86SegmentRegId :: CS => ctx. cs ,
94+ X86SegmentRegId :: SS => ctx. ss ,
95+ _ => 0 ,
96+ } ;
97+ buf. copy_from_slice ( & ( val as u32 ) . to_le_bytes ( ) ) ;
98+ Ok ( 4 )
99+ }
100+ _ => Ok ( 0 ) ,
101+ }
102+ }
103+
104+ fn write_register (
105+ & mut self ,
106+ _tid : Tid ,
107+ _reg_id : <Self :: Arch as gdbstub:: arch:: Arch >:: RegId ,
108+ _val : & [ u8 ] ,
109+ ) -> TargetResult < ( ) , Self > {
110+ warn ! ( "write single register not fully implemented (requires ptrace or inline hooking)" ) ;
111+ Err ( TargetError :: NonFatal )
112+ }
113+ }
114+
35115impl EdbgTarget {
36116 fn create_capstone ( ) -> Result < Capstone > {
37117 Capstone :: new ( )
0 commit comments