1+ use std:: sync:: atomic:: Ordering ;
2+
3+ use deku:: ctx:: Endian ;
4+ use log:: { debug, trace} ;
15use ratatui:: {
26 layout:: { Constraint , Flex , Layout , Rect } ,
37 style:: { Color , Style , Stylize } ,
@@ -13,7 +17,13 @@ use super::{BLUE, DARK_GRAY, GREEN, ORANGE, SCROLL_CONTROL_TEXT, YELLOW};
1317pub const HEXDUMP_WIDTH : usize = 16 ;
1418
1519/// Convert bytes in hexdump, `skip` that many lines, `take` that many lines
16- fn to_hexdump_str ( buffer : & [ u8 ] , skip : usize , take : usize ) -> Vec < Line > {
20+ fn to_hexdump_str < ' a > (
21+ app : & mut App ,
22+ pos : u64 ,
23+ buffer : & [ u8 ] ,
24+ skip : usize ,
25+ take : usize ,
26+ ) -> Vec < Line < ' a > > {
1727 let mut lines = Vec :: new ( ) ;
1828 for ( offset, chunk) in buffer. chunks ( 16 ) . skip ( skip) . take ( take) . enumerate ( ) {
1929 let mut hex_spans = Vec :: new ( ) ;
@@ -31,10 +41,44 @@ fn to_hexdump_str(buffer: &[u8], skip: usize, take: usize) -> Vec<Line> {
3141 hex_spans. push ( Span :: styled ( ascii_char. to_string ( ) , Style :: default ( ) . fg ( color) ) ) ;
3242 }
3343
44+ // check if value has a register reference
45+ let thirty = app. thirty_two_bit . load ( Ordering :: Relaxed ) ;
46+
47+ let mut ref_spans = Vec :: new ( ) ;
48+ let endian = app. endian . lock ( ) . unwrap ( ) ;
49+ let registers = app. registers . lock ( ) . unwrap ( ) ;
50+
51+ ref_spans. push ( Span :: raw ( "| " ) ) ;
52+ // NOTE: This is disabled, since it's mostly useless?
53+ //deref_bytes_to_registers(&endian, chunk, thirty, &mut ref_spans, ®isters);
54+ let windows = if thirty { 4 } else { 8 } ;
55+ for r in registers. iter ( ) {
56+ if let Some ( reg) = & r. register {
57+ if !reg. is_set ( ) {
58+ continue ;
59+ }
60+ if let Some ( reg_value) = & reg. value {
61+ if let Ok ( val) = u64:: from_str_radix ( & reg_value[ 2 ..] , 16 ) {
62+ for n in 0 ..=windows {
63+ if val as usize == pos as usize + ( ( offset + skip) * HEXDUMP_WIDTH + n)
64+ {
65+ ref_spans. push ( Span :: raw ( format ! (
66+ "← ${}(0x{:02x}) " ,
67+ r. name. clone( ) ,
68+ val
69+ ) ) ) ;
70+ }
71+ }
72+ }
73+ }
74+ }
75+ }
76+
3477 let line = Line :: from_iter (
3578 vec ! [ Span :: raw( format!( "{:08x}: " , ( skip + offset) * HEXDUMP_WIDTH ) ) , Span :: raw( "" ) ]
3679 . into_iter ( )
37- . chain ( hex_spans) ,
80+ . chain ( hex_spans)
81+ . chain ( ref_spans) ,
3882 ) ;
3983
4084 lines. push ( line) ;
@@ -43,6 +87,56 @@ fn to_hexdump_str(buffer: &[u8], skip: usize, take: usize) -> Vec<Line> {
4387 lines
4488}
4589
90+ fn deref_bytes_to_registers (
91+ endian : & Option < Endian > ,
92+ chunk : & [ u8 ] ,
93+ thirty : bool ,
94+ ref_spans : & mut Vec < Span < ' _ > > ,
95+ registers : & Vec < crate :: register:: RegisterStorage > ,
96+ ) {
97+ let windows = if thirty { 4 } else { 8 } ;
98+ for w in chunk. windows ( windows) {
99+ let bytes_val = if thirty {
100+ let val = if endian. unwrap ( ) == Endian :: Big {
101+ // TODO: try_into()
102+ u32:: from_be_bytes ( [ w[ 0 ] , w[ 1 ] , w[ 2 ] , w[ 3 ] ] )
103+ } else {
104+ u32:: from_le_bytes ( [ w[ 0 ] , w[ 1 ] , w[ 2 ] , w[ 3 ] ] )
105+ } ;
106+
107+ val as u64
108+ } else {
109+ if endian. unwrap ( ) == Endian :: Big {
110+ u64:: from_be_bytes ( [ w[ 0 ] , w[ 1 ] , w[ 2 ] , w[ 3 ] , w[ 4 ] , w[ 5 ] , w[ 6 ] , w[ 7 ] ] )
111+ } else {
112+ u64:: from_le_bytes ( [ w[ 0 ] , w[ 1 ] , w[ 2 ] , w[ 3 ] , w[ 4 ] , w[ 5 ] , w[ 6 ] , w[ 7 ] ] )
113+ }
114+ } ;
115+
116+ for r in registers. iter ( ) {
117+ if let Some ( reg) = & r. register {
118+ if !reg. is_set ( ) {
119+ continue ;
120+ }
121+ if let Some ( reg_value) = & reg. value {
122+ if let Ok ( val) = u64:: from_str_radix ( & reg_value[ 2 ..] , 16 ) {
123+ if val != 0 {
124+ // Find registers that are pointing to the value at a byte offset
125+ if bytes_val == val {
126+ ref_spans. push ( Span :: raw ( format ! (
127+ "${}(0x{:02x?}) " ,
128+ r. name. clone( ) ,
129+ val
130+ ) ) ) ;
131+ }
132+ }
133+ }
134+ }
135+ }
136+ }
137+ }
138+ }
139+
46140fn color ( byte : u8 ) -> Color {
47141 if byte == 0x00 {
48142 DARK_GRAY
@@ -73,16 +167,17 @@ fn block(pos: &str) -> Block {
73167}
74168
75169pub fn draw_hexdump ( app : & mut App , f : & mut Frame , hexdump : Rect , show_popup : bool ) {
76- let hexdump_lock = app. hexdump . lock ( ) . unwrap ( ) ;
170+ let hexdump_active = app. hexdump . lock ( ) . unwrap ( ) . is_some ( ) ;
77171 let mut pos = "" . to_string ( ) ;
78172
79- if let Some ( r) = hexdump_lock. as_ref ( ) {
173+ if hexdump_active {
174+ let r = app. hexdump . lock ( ) . unwrap ( ) . clone ( ) . unwrap ( ) ;
80175 pos = format ! ( "(0x{:02x?})" , r. 0 ) ;
81176 let data = & r. 1 ;
82177
83178 let skip = app. hexdump_scroll ;
84179 let take = hexdump. height ;
85- let lines = to_hexdump_str ( data, skip as usize , take as usize ) ;
180+ let lines = to_hexdump_str ( app , r . 0 , data, skip as usize , take as usize ) ;
86181 let content_len = data. len ( ) / HEXDUMP_WIDTH ;
87182
88183 let lines: Vec < Line > = lines. into_iter ( ) . collect ( ) ;
0 commit comments