1
+ use std:: sync:: atomic:: Ordering ;
2
+
3
+ use deku:: ctx:: Endian ;
4
+ use log:: { debug, trace} ;
1
5
use ratatui:: {
2
6
layout:: { Constraint , Flex , Layout , Rect } ,
3
7
style:: { Color , Style , Stylize } ,
@@ -13,7 +17,13 @@ use super::{BLUE, DARK_GRAY, GREEN, ORANGE, SCROLL_CONTROL_TEXT, YELLOW};
13
17
pub const HEXDUMP_WIDTH : usize = 16 ;
14
18
15
19
/// 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 > > {
17
27
let mut lines = Vec :: new ( ) ;
18
28
for ( offset, chunk) in buffer. chunks ( 16 ) . skip ( skip) . take ( take) . enumerate ( ) {
19
29
let mut hex_spans = Vec :: new ( ) ;
@@ -31,10 +41,46 @@ fn to_hexdump_str(buffer: &[u8], skip: usize, take: usize) -> Vec<Line> {
31
41
hex_spans. push ( Span :: styled ( ascii_char. to_string ( ) , Style :: default ( ) . fg ( color) ) ) ;
32
42
}
33
43
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
+
53
+ // NOTE: This is disabled, since it's mostly useless?
54
+ //deref_bytes_to_registers(&endian, chunk, thirty, &mut ref_spans, ®isters);
55
+
56
+ let windows = if thirty { 4 } else { 8 } ;
57
+ for r in registers. iter ( ) {
58
+ if let Some ( reg) = & r. register {
59
+ if !reg. is_set ( ) {
60
+ continue ;
61
+ }
62
+ if let Some ( reg_value) = & reg. value {
63
+ if let Ok ( val) = u64:: from_str_radix ( & reg_value[ 2 ..] , 16 ) {
64
+ for n in 0 ..=windows {
65
+ if val as usize == pos as usize + ( ( offset + skip) * HEXDUMP_WIDTH + n)
66
+ {
67
+ ref_spans. push ( Span :: raw ( format ! (
68
+ "← ${}(0x{:02x}) " ,
69
+ r. name. clone( ) ,
70
+ val
71
+ ) ) ) ;
72
+ }
73
+ }
74
+ }
75
+ }
76
+ }
77
+ }
78
+
34
79
let line = Line :: from_iter (
35
80
vec ! [ Span :: raw( format!( "{:08x}: " , ( skip + offset) * HEXDUMP_WIDTH ) ) , Span :: raw( "" ) ]
36
81
. into_iter ( )
37
- . chain ( hex_spans) ,
82
+ . chain ( hex_spans)
83
+ . chain ( ref_spans) ,
38
84
) ;
39
85
40
86
lines. push ( line) ;
@@ -43,6 +89,56 @@ fn to_hexdump_str(buffer: &[u8], skip: usize, take: usize) -> Vec<Line> {
43
89
lines
44
90
}
45
91
92
+ fn deref_bytes_to_registers (
93
+ endian : & Option < Endian > ,
94
+ chunk : & [ u8 ] ,
95
+ thirty : bool ,
96
+ ref_spans : & mut Vec < Span < ' _ > > ,
97
+ registers : & Vec < crate :: register:: RegisterStorage > ,
98
+ ) {
99
+ let windows = if thirty { 4 } else { 8 } ;
100
+ for w in chunk. windows ( windows) {
101
+ let bytes_val = if thirty {
102
+ let val = if endian. unwrap ( ) == Endian :: Big {
103
+ // TODO: try_into()
104
+ u32:: from_be_bytes ( [ w[ 0 ] , w[ 1 ] , w[ 2 ] , w[ 3 ] ] )
105
+ } else {
106
+ u32:: from_le_bytes ( [ w[ 0 ] , w[ 1 ] , w[ 2 ] , w[ 3 ] ] )
107
+ } ;
108
+
109
+ val as u64
110
+ } else {
111
+ if endian. unwrap ( ) == Endian :: Big {
112
+ u64:: from_be_bytes ( [ w[ 0 ] , w[ 1 ] , w[ 2 ] , w[ 3 ] , w[ 4 ] , w[ 5 ] , w[ 6 ] , w[ 7 ] ] )
113
+ } else {
114
+ u64:: from_le_bytes ( [ w[ 0 ] , w[ 1 ] , w[ 2 ] , w[ 3 ] , w[ 4 ] , w[ 5 ] , w[ 6 ] , w[ 7 ] ] )
115
+ }
116
+ } ;
117
+
118
+ for r in registers. iter ( ) {
119
+ if let Some ( reg) = & r. register {
120
+ if !reg. is_set ( ) {
121
+ continue ;
122
+ }
123
+ if let Some ( reg_value) = & reg. value {
124
+ if let Ok ( val) = u64:: from_str_radix ( & reg_value[ 2 ..] , 16 ) {
125
+ if val != 0 {
126
+ // Find registers that are pointing to the value at a byte offset
127
+ if bytes_val == val {
128
+ ref_spans. push ( Span :: raw ( format ! (
129
+ "${}(0x{:02x?}) " ,
130
+ r. name. clone( ) ,
131
+ val
132
+ ) ) ) ;
133
+ }
134
+ }
135
+ }
136
+ }
137
+ }
138
+ }
139
+ }
140
+ }
141
+
46
142
fn color ( byte : u8 ) -> Color {
47
143
if byte == 0x00 {
48
144
DARK_GRAY
@@ -73,16 +169,17 @@ fn block(pos: &str) -> Block {
73
169
}
74
170
75
171
pub fn draw_hexdump ( app : & mut App , f : & mut Frame , hexdump : Rect , show_popup : bool ) {
76
- let hexdump_lock = app. hexdump . lock ( ) . unwrap ( ) ;
172
+ let hexdump_active = app. hexdump . lock ( ) . unwrap ( ) . is_some ( ) ;
77
173
let mut pos = "" . to_string ( ) ;
78
174
79
- if let Some ( r) = hexdump_lock. as_ref ( ) {
175
+ if hexdump_active {
176
+ let r = app. hexdump . lock ( ) . unwrap ( ) . clone ( ) . unwrap ( ) ;
80
177
pos = format ! ( "(0x{:02x?})" , r. 0 ) ;
81
178
let data = & r. 1 ;
82
179
83
180
let skip = app. hexdump_scroll ;
84
181
let take = hexdump. height ;
85
- let lines = to_hexdump_str ( data, skip as usize , take as usize ) ;
182
+ let lines = to_hexdump_str ( app , r . 0 , data, skip as usize , take as usize ) ;
86
183
let content_len = data. len ( ) / HEXDUMP_WIDTH ;
87
184
88
185
let lines: Vec < Line > = lines. into_iter ( ) . collect ( ) ;
0 commit comments