@@ -56,6 +56,8 @@ struct Runner {
56
56
defmt_stream : Box < dyn StreamDecoder > ,
57
57
58
58
di : DebugInfo ,
59
+
60
+ exports : BTreeMap < String , u32 > ,
59
61
}
60
62
61
63
unsafe fn fuck_it < ' a , ' b , T > ( wtf : & ' a T ) -> & ' b T {
@@ -117,6 +119,36 @@ impl Runner {
117
119
let vector_table = vector_table. ok_or_else ( || anyhow ! ( "`.vector_table` section is missing" ) ) ?;
118
120
log:: debug!( "vector table: {:x?}" , vector_table) ;
119
121
122
+ // Build a map of exported variables, based on addresses found in the
123
+ // '.teleprobe.export' section.
124
+ let mut export_map = BTreeMap :: new ( ) ;
125
+
126
+ if let Some ( section) = elf. section_by_name ( ".teleprobe.export" ) {
127
+ let ptrs = section
128
+ . data ( ) ?
129
+ . chunks_exact ( 4 )
130
+ . map ( |chunk| u32:: from_le_bytes ( chunk. try_into ( ) . unwrap ( ) ) )
131
+ . collect :: < Vec < _ > > ( ) ;
132
+
133
+ if ptrs. len ( ) > 0 {
134
+ info ! ( "Found {} exported variables: {:#0x?}" , ptrs. len( ) , ptrs) ;
135
+
136
+ // TODO: Is there a better way?
137
+ for symbol in elf. symbols ( ) {
138
+ if ptrs. contains ( & ( symbol. address ( ) as u32 ) ) {
139
+ let addr = symbol. address ( ) as u32 ;
140
+ let name = String :: from ( symbol. name ( ) . unwrap ( ) ) ;
141
+ // Filter out private symbols, otherwise we get some false-positives
142
+ if name. starts_with ( "__" ) {
143
+ continue ;
144
+ }
145
+ export_map. insert ( String :: from ( symbol. name ( ) . unwrap ( ) ) , addr) ;
146
+ info ! ( "Found match for addr {:?} -> {:?}" , & addr, & name) ;
147
+ }
148
+ }
149
+ }
150
+ }
151
+
120
152
// reset ALL cores other than the main one.
121
153
// This is needed for rp2040 core1.
122
154
for ( i, _) in sess. list_cores ( ) {
@@ -244,6 +276,7 @@ impl Runner {
244
276
defmt,
245
277
defmt_stream,
246
278
di,
279
+ exports : export_map,
247
280
} )
248
281
}
249
282
@@ -342,6 +375,30 @@ impl Runner {
342
375
bail ! ( "Firmware crashed" ) ;
343
376
}
344
377
378
+ // Look up exported symbols
379
+ for ( symbol, addr) in & self . exports {
380
+ let mut buf = [ 0 ; 64 ] ;
381
+ /*
382
+ // XXX: Ideally we should use demangling information to
383
+ // either handle references ie bytestrings are stored as
384
+ // pointers to data. But for now, we only support hardcoded
385
+ // byte arrays of length 64.
386
+ let ptr = core.read_word_32(*addr as u64).unwrap();
387
+ let _ = core.read(ptr as u64, &mut buf).unwrap();
388
+ */
389
+ // TODO: Error handling?
390
+ let _ = core. read ( * addr as u64 , & mut buf) . unwrap ( ) ;
391
+ match String :: from_utf8 ( buf. to_vec ( ) ) {
392
+ Ok ( s) => {
393
+ info ! ( "Found: {} -> {}" , symbol, s) ;
394
+ }
395
+ Err ( _) => {
396
+ warn ! ( "Data for {} not found!" , symbol) ;
397
+ }
398
+ }
399
+ }
400
+ // TODO: Export our wanted symbols?
401
+
345
402
Ok ( ( ) )
346
403
}
347
404
@@ -439,7 +496,7 @@ impl Runner {
439
496
fn dump_state ( & mut self , core : & mut Core , force : bool ) -> anyhow:: Result < bool > {
440
497
core. halt ( TIMEOUT ) ?;
441
498
442
- // determine if the target is handling an interupt
499
+ // determine if the target is handling an interrupt
443
500
let xpsr: u32 = core. read_core_reg ( XPSR ) ?;
444
501
let exception_number = xpsr & 0xff ;
445
502
match exception_number {
0 commit comments