@@ -24,14 +24,14 @@ wit_bindgen::generate!({
24
24
use exports:: objdiff:: core:: {
25
25
diff:: {
26
26
DiffConfigBorrow , DiffResult , Guest as GuestDiff , GuestDiffConfig , GuestObject ,
27
- GuestObjectDiff , Object , ObjectBorrow , ObjectDiff , ObjectDiffBorrow ,
27
+ GuestObjectDiff , MappingConfig , Object , ObjectBorrow , ObjectDiff , ObjectDiffBorrow ,
28
+ SymbolFlags , SymbolInfo , SymbolKind , SymbolRef ,
28
29
} ,
29
30
display:: {
30
31
ContextItem , ContextItemCopy , ContextItemNavigate , DiffText , DiffTextColor , DiffTextOpcode ,
31
32
DiffTextSegment , DiffTextSymbol , DisplayConfig , Guest as GuestDisplay , HoverItem ,
32
33
HoverItemColor , HoverItemText , InstructionDiffKind , InstructionDiffRow , SectionDisplay ,
33
- SectionDisplaySymbol , SymbolDisplay , SymbolFilter , SymbolFlags , SymbolKind ,
34
- SymbolNavigationKind , SymbolRef ,
34
+ SymbolDisplay , SymbolFilter , SymbolNavigationKind ,
35
35
} ,
36
36
} ;
37
37
@@ -59,15 +59,17 @@ impl GuestDiff for Component {
59
59
left : Option < ObjectBorrow > ,
60
60
right : Option < ObjectBorrow > ,
61
61
diff_config : DiffConfigBorrow ,
62
+ mapping_config : MappingConfig ,
62
63
) -> Result < DiffResult , String > {
63
64
let diff_config = diff_config. get :: < ResourceDiffConfig > ( ) . 0 . borrow ( ) ;
65
+ let mapping_config = diff:: MappingConfig :: from ( mapping_config) ;
64
66
log:: debug!( "Running diff with config: {:?}" , diff_config) ;
65
67
let result = diff:: diff_objs (
66
68
left. as_ref ( ) . map ( |o| o. get :: < ResourceObject > ( ) . 0 . as_ref ( ) ) ,
67
69
right. as_ref ( ) . map ( |o| o. get :: < ResourceObject > ( ) . 0 . as_ref ( ) ) ,
68
70
None ,
69
71
& diff_config,
70
- & diff :: MappingConfig :: default ( ) ,
72
+ & mapping_config ,
71
73
)
72
74
. map_err ( |e| e. to_string ( ) ) ?;
73
75
Ok ( DiffResult {
@@ -134,48 +136,47 @@ impl GuestDisplay for Component {
134
136
name : d. name ,
135
137
size : d. size ,
136
138
match_percent : d. match_percent ,
137
- symbols : d
138
- . symbols
139
- . into_iter ( )
140
- . map ( |s| SectionDisplaySymbol {
141
- symbol : s. symbol as SymbolRef ,
142
- is_mapping_symbol : s. is_mapping_symbol ,
143
- } )
144
- . collect ( ) ,
139
+ symbols : d. symbols . into_iter ( ) . map ( to_symbol_ref) . collect ( ) ,
145
140
} )
146
141
. collect ( )
147
142
}
148
143
149
- fn display_symbol (
150
- diff : ObjectDiffBorrow ,
151
- symbol_display : SectionDisplaySymbol ,
152
- ) -> SymbolDisplay {
144
+ fn display_symbol ( diff : ObjectDiffBorrow , symbol_ref : SymbolRef ) -> SymbolDisplay {
153
145
let obj_diff = diff. get :: < ResourceObjectDiff > ( ) ;
154
146
let obj = obj_diff. 0 . as_ref ( ) ;
155
147
let obj_diff = & obj_diff. 1 ;
156
- let symbol_idx = symbol_display. symbol as usize ;
157
- let Some ( symbol) = obj. symbols . get ( symbol_idx) else {
158
- return SymbolDisplay { name : "<unknown>" . to_string ( ) , ..Default :: default ( ) } ;
148
+ let symbol_display = from_symbol_ref ( symbol_ref) ;
149
+ let Some ( symbol) = obj. symbols . get ( symbol_display. symbol ) else {
150
+ return SymbolDisplay {
151
+ info : SymbolInfo { name : "<unknown>" . to_string ( ) , ..Default :: default ( ) } ,
152
+ ..Default :: default ( )
153
+ } ;
159
154
} ;
160
155
let symbol_diff = if symbol_display. is_mapping_symbol {
161
156
obj_diff
162
157
. mapping_symbols
163
158
. iter ( )
164
- . find ( |s| s. symbol_index == symbol_idx )
159
+ . find ( |s| s. symbol_index == symbol_display . symbol )
165
160
. map ( |s| & s. symbol_diff )
166
161
} else {
167
- obj_diff. symbols . get ( symbol_idx )
162
+ obj_diff. symbols . get ( symbol_display . symbol )
168
163
} ;
169
164
SymbolDisplay {
170
- name : symbol. name . clone ( ) ,
171
- demangled_name : symbol. demangled_name . clone ( ) ,
172
- address : symbol. address ,
173
- size : symbol. size ,
174
- kind : SymbolKind :: from ( symbol. kind ) ,
175
- section : symbol. section . map ( |s| s as u32 ) ,
176
- flags : SymbolFlags :: from ( symbol. flags ) ,
177
- align : symbol. align . map ( |a| a. get ( ) ) ,
178
- virtual_address : symbol. virtual_address ,
165
+ info : SymbolInfo {
166
+ id : to_symbol_ref ( symbol_display) ,
167
+ name : symbol. name . clone ( ) ,
168
+ demangled_name : symbol. demangled_name . clone ( ) ,
169
+ address : symbol. address ,
170
+ size : symbol. size ,
171
+ kind : SymbolKind :: from ( symbol. kind ) ,
172
+ section : symbol. section . map ( |s| s as u32 ) ,
173
+ section_name : symbol
174
+ . section
175
+ . and_then ( |s| obj. sections . get ( s) . map ( |sec| sec. name . clone ( ) ) ) ,
176
+ flags : SymbolFlags :: from ( symbol. flags ) ,
177
+ align : symbol. align . map ( |a| a. get ( ) ) ,
178
+ virtual_address : symbol. virtual_address ,
179
+ } ,
179
180
target_symbol : symbol_diff. and_then ( |sd| sd. target_symbol . map ( |s| s as u32 ) ) ,
180
181
match_percent : symbol_diff. and_then ( |sd| sd. match_percent ) ,
181
182
diff_score : symbol_diff. and_then ( |sd| sd. diff_score ) ,
@@ -185,57 +186,53 @@ impl GuestDisplay for Component {
185
186
186
187
fn display_instruction_row (
187
188
diff : ObjectDiffBorrow ,
188
- symbol_display : SectionDisplaySymbol ,
189
+ symbol_ref : SymbolRef ,
189
190
row_index : u32 ,
190
191
diff_config : DiffConfigBorrow ,
191
192
) -> InstructionDiffRow {
192
193
let obj_diff = diff. get :: < ResourceObjectDiff > ( ) ;
193
194
let obj = obj_diff. 0 . as_ref ( ) ;
194
195
let obj_diff = & obj_diff. 1 ;
195
- let symbol_idx = symbol_display . symbol as usize ;
196
+ let symbol_display = from_symbol_ref ( symbol_ref ) ;
196
197
let symbol_diff = if symbol_display. is_mapping_symbol {
197
198
obj_diff
198
199
. mapping_symbols
199
200
. iter ( )
200
- . find ( |s| s. symbol_index == symbol_idx )
201
+ . find ( |s| s. symbol_index == symbol_display . symbol )
201
202
. map ( |s| & s. symbol_diff )
202
203
} else {
203
- obj_diff. symbols . get ( symbol_idx )
204
+ obj_diff. symbols . get ( symbol_display . symbol )
204
205
} ;
205
206
let Some ( row) = symbol_diff. and_then ( |sd| sd. instruction_rows . get ( row_index as usize ) )
206
207
else {
207
208
return InstructionDiffRow :: default ( ) ;
208
209
} ;
209
210
let diff_config = diff_config. get :: < ResourceDiffConfig > ( ) . 0 . borrow ( ) ;
210
211
let mut segments = Vec :: with_capacity ( 16 ) ;
211
- diff:: display:: display_row ( obj, symbol_idx , row, & diff_config, |segment| {
212
+ diff:: display:: display_row ( obj, symbol_display . symbol , row, & diff_config, |segment| {
212
213
segments. push ( DiffTextSegment :: from ( segment) ) ;
213
214
Ok ( ( ) )
214
215
} )
215
216
. unwrap ( ) ;
216
217
InstructionDiffRow { segments, diff_kind : InstructionDiffKind :: from ( row. kind ) }
217
218
}
218
219
219
- fn symbol_context (
220
- diff : ObjectDiffBorrow ,
221
- symbol_display : SectionDisplaySymbol ,
222
- ) -> Vec < ContextItem > {
220
+ fn symbol_context ( diff : ObjectDiffBorrow , symbol_ref : SymbolRef ) -> Vec < ContextItem > {
223
221
let obj_diff = diff. get :: < ResourceObjectDiff > ( ) ;
224
222
let obj = obj_diff. 0 . as_ref ( ) ;
223
+ let symbol_display = from_symbol_ref ( symbol_ref) ;
225
224
diff:: display:: symbol_context ( obj, symbol_display. symbol as usize )
226
225
. into_iter ( )
227
226
. map ( |item| ContextItem :: from ( item) )
228
227
. collect ( )
229
228
}
230
229
231
- fn symbol_hover (
232
- diff : ObjectDiffBorrow ,
233
- symbol_display : SectionDisplaySymbol ,
234
- ) -> Vec < HoverItem > {
230
+ fn symbol_hover ( diff : ObjectDiffBorrow , symbol_ref : SymbolRef ) -> Vec < HoverItem > {
235
231
let obj_diff = diff. get :: < ResourceObjectDiff > ( ) ;
236
232
let obj = obj_diff. 0 . as_ref ( ) ;
237
233
let addend = 0 ; // TODO
238
234
let override_color = None ; // TODO: colorize replaced/deleted/inserted relocations
235
+ let symbol_display = from_symbol_ref ( symbol_ref) ;
239
236
diff:: display:: symbol_hover ( obj, symbol_display. symbol as usize , addend, override_color)
240
237
. into_iter ( )
241
238
. map ( |item| HoverItem :: from ( item) )
@@ -244,22 +241,22 @@ impl GuestDisplay for Component {
244
241
245
242
fn instruction_context (
246
243
diff : ObjectDiffBorrow ,
247
- symbol_display : SectionDisplaySymbol ,
244
+ symbol_ref : SymbolRef ,
248
245
row_index : u32 ,
249
246
diff_config : DiffConfigBorrow ,
250
247
) -> Vec < ContextItem > {
251
248
let obj_diff = diff. get :: < ResourceObjectDiff > ( ) ;
252
249
let obj = obj_diff. 0 . as_ref ( ) ;
253
250
let obj_diff = & obj_diff. 1 ;
254
- let symbol_idx = symbol_display . symbol as usize ;
251
+ let symbol_display = from_symbol_ref ( symbol_ref ) ;
255
252
let symbol_diff = if symbol_display. is_mapping_symbol {
256
253
obj_diff
257
254
. mapping_symbols
258
255
. iter ( )
259
- . find ( |s| s. symbol_index == symbol_idx )
256
+ . find ( |s| s. symbol_index == symbol_display . symbol )
260
257
. map ( |s| & s. symbol_diff )
261
258
} else {
262
- obj_diff. symbols . get ( symbol_idx )
259
+ obj_diff. symbols . get ( symbol_display . symbol )
263
260
} ;
264
261
let Some ( ins_ref) = symbol_diff
265
262
. and_then ( |sd| sd. instruction_rows . get ( row_index as usize ) )
@@ -268,7 +265,7 @@ impl GuestDisplay for Component {
268
265
return Vec :: new ( ) ;
269
266
} ;
270
267
let diff_config = diff_config. get :: < ResourceDiffConfig > ( ) . 0 . borrow ( ) ;
271
- let Some ( resolved) = obj. resolve_instruction_ref ( symbol_idx , ins_ref) else {
268
+ let Some ( resolved) = obj. resolve_instruction_ref ( symbol_display . symbol , ins_ref) else {
272
269
return vec ! [ ContextItem :: Copy ( ContextItemCopy {
273
270
value: "Failed to resolve instruction" . to_string( ) ,
274
271
label: Some ( "error" . to_string( ) ) ,
@@ -291,22 +288,22 @@ impl GuestDisplay for Component {
291
288
292
289
fn instruction_hover (
293
290
diff : ObjectDiffBorrow ,
294
- symbol_display : SectionDisplaySymbol ,
291
+ symbol_ref : SymbolRef ,
295
292
row_index : u32 ,
296
293
diff_config : DiffConfigBorrow ,
297
294
) -> Vec < HoverItem > {
298
295
let obj_diff = diff. get :: < ResourceObjectDiff > ( ) ;
299
296
let obj = obj_diff. 0 . as_ref ( ) ;
300
297
let obj_diff = & obj_diff. 1 ;
301
- let symbol_idx = symbol_display . symbol as usize ;
298
+ let symbol_display = from_symbol_ref ( symbol_ref ) ;
302
299
let symbol_diff = if symbol_display. is_mapping_symbol {
303
300
obj_diff
304
301
. mapping_symbols
305
302
. iter ( )
306
- . find ( |s| s. symbol_index == symbol_idx )
303
+ . find ( |s| s. symbol_index == symbol_display . symbol )
307
304
. map ( |s| & s. symbol_diff )
308
305
} else {
309
- obj_diff. symbols . get ( symbol_idx )
306
+ obj_diff. symbols . get ( symbol_display . symbol )
310
307
} ;
311
308
let Some ( ins_ref) = symbol_diff
312
309
. and_then ( |sd| sd. instruction_rows . get ( row_index as usize ) )
@@ -315,7 +312,7 @@ impl GuestDisplay for Component {
315
312
return Vec :: new ( ) ;
316
313
} ;
317
314
let diff_config = diff_config. get :: < ResourceDiffConfig > ( ) . 0 . borrow ( ) ;
318
- let Some ( resolved) = obj. resolve_instruction_ref ( symbol_idx , ins_ref) else {
315
+ let Some ( resolved) = obj. resolve_instruction_ref ( symbol_display . symbol , ins_ref) else {
319
316
return vec ! [ HoverItem :: Text ( HoverItemText {
320
317
label: "Error" . to_string( ) ,
321
318
value: "Failed to resolve instruction" . to_string( ) ,
@@ -497,20 +494,56 @@ impl GuestObject for ResourceObject {
497
494
}
498
495
499
496
impl GuestObjectDiff for ResourceObjectDiff {
500
- fn find_symbol ( & self , name : String , section_name : Option < String > ) -> Option < SymbolRef > {
497
+ fn find_symbol ( & self , name : String , section_name : Option < String > ) -> Option < SymbolInfo > {
501
498
let obj = self . 0 . as_ref ( ) ;
502
- obj. symbols
503
- . iter ( )
504
- . position ( |s| {
505
- s. name == name
506
- && match section_name. as_deref ( ) {
507
- Some ( section_name) => {
508
- s. section . is_some_and ( |n| obj. sections [ n] . name == section_name)
509
- }
510
- None => true ,
499
+ let symbol_idx = obj. symbols . iter ( ) . position ( |s| {
500
+ s. name == name
501
+ && match section_name. as_deref ( ) {
502
+ Some ( section_name) => {
503
+ s. section . is_some_and ( |n| obj. sections [ n] . name == section_name)
511
504
}
512
- } )
513
- . map ( |i| i as SymbolRef )
505
+ None => true ,
506
+ }
507
+ } ) ?;
508
+ let symbol = obj. symbols . get ( symbol_idx) ?;
509
+ Some ( SymbolInfo {
510
+ id : symbol_idx as SymbolRef ,
511
+ name : symbol. name . clone ( ) ,
512
+ demangled_name : symbol. demangled_name . clone ( ) ,
513
+ address : symbol. address ,
514
+ size : symbol. size ,
515
+ kind : SymbolKind :: from ( symbol. kind ) ,
516
+ section : symbol. section . map ( |s| s as u32 ) ,
517
+ section_name : symbol
518
+ . section
519
+ . and_then ( |s| obj. sections . get ( s) . map ( |sec| sec. name . clone ( ) ) ) ,
520
+ flags : SymbolFlags :: from ( symbol. flags ) ,
521
+ align : symbol. align . map ( |a| a. get ( ) ) ,
522
+ virtual_address : symbol. virtual_address ,
523
+ } )
524
+ }
525
+
526
+ fn get_symbol ( & self , symbol_ref : SymbolRef ) -> Option < SymbolInfo > {
527
+ let obj = self . 0 . as_ref ( ) ;
528
+ let symbol_display = from_symbol_ref ( symbol_ref) ;
529
+ let Some ( symbol) = obj. symbols . get ( symbol_display. symbol ) else {
530
+ return None ;
531
+ } ;
532
+ Some ( SymbolInfo {
533
+ id : to_symbol_ref ( symbol_display) ,
534
+ name : symbol. name . clone ( ) ,
535
+ demangled_name : symbol. demangled_name . clone ( ) ,
536
+ address : symbol. address ,
537
+ size : symbol. size ,
538
+ kind : SymbolKind :: from ( symbol. kind ) ,
539
+ section : symbol. section . map ( |s| s as u32 ) ,
540
+ section_name : symbol
541
+ . section
542
+ . and_then ( |s| obj. sections . get ( s) . map ( |sec| sec. name . clone ( ) ) ) ,
543
+ flags : SymbolFlags :: from ( symbol. flags ) ,
544
+ align : symbol. align . map ( |a| a. get ( ) ) ,
545
+ virtual_address : symbol. virtual_address ,
546
+ } )
514
547
}
515
548
}
516
549
@@ -580,18 +613,28 @@ impl Default for SymbolFlags {
580
613
fn default ( ) -> Self { Self :: empty ( ) }
581
614
}
582
615
583
- impl Default for SymbolDisplay {
616
+ impl Default for SymbolInfo {
584
617
fn default ( ) -> Self {
585
618
Self {
619
+ id : u32:: MAX ,
586
620
name : Default :: default ( ) ,
587
621
demangled_name : Default :: default ( ) ,
588
622
address : Default :: default ( ) ,
589
623
size : Default :: default ( ) ,
590
624
kind : Default :: default ( ) ,
591
625
section : Default :: default ( ) ,
626
+ section_name : Default :: default ( ) ,
592
627
flags : Default :: default ( ) ,
593
628
align : Default :: default ( ) ,
594
629
virtual_address : Default :: default ( ) ,
630
+ }
631
+ }
632
+ }
633
+
634
+ impl Default for SymbolDisplay {
635
+ fn default ( ) -> Self {
636
+ Self {
637
+ info : Default :: default ( ) ,
595
638
target_symbol : Default :: default ( ) ,
596
639
match_percent : Default :: default ( ) ,
597
640
diff_score : Default :: default ( ) ,
@@ -600,4 +643,30 @@ impl Default for SymbolDisplay {
600
643
}
601
644
}
602
645
646
+ impl From < MappingConfig > for diff:: MappingConfig {
647
+ fn from ( config : MappingConfig ) -> Self {
648
+ Self {
649
+ mappings : config. mappings . into_iter ( ) . collect ( ) ,
650
+ selecting_left : config. selecting_left ,
651
+ selecting_right : config. selecting_right ,
652
+ }
653
+ }
654
+ }
655
+
656
+ fn from_symbol_ref ( symbol_ref : SymbolRef ) -> diff:: display:: SectionDisplaySymbol {
657
+ diff:: display:: SectionDisplaySymbol {
658
+ symbol : ( symbol_ref & !( 1 << 31 ) ) as usize ,
659
+ is_mapping_symbol : ( symbol_ref & ( 1 << 31 ) ) != 0 ,
660
+ }
661
+ }
662
+
663
+ fn to_symbol_ref ( display_symbol : diff:: display:: SectionDisplaySymbol ) -> SymbolRef {
664
+ if display_symbol. is_mapping_symbol {
665
+ // Use the highest bit to indicate a mapping symbol
666
+ display_symbol. symbol as u32 | ( 1 << 31 )
667
+ } else {
668
+ display_symbol. symbol as u32
669
+ }
670
+ }
671
+
603
672
export ! ( Component ) ;
0 commit comments