@@ -108,7 +108,9 @@ pub struct Image {
108
108
// Any read data callback set by this `Image` instance.
109
109
callback : Option < BoxedCallback > ,
110
110
caches : Vec < Rc < SectionCache > > ,
111
- asids : HashSet < Asid > ,
111
+ // `HashSet` might grow and move the content around, we cannot use `Asid` directly since we
112
+ // share a pointer with libipt and it must be valid for the entire Image (section) filetime.
113
+ asids : HashSet < Rc < Asid > > ,
112
114
}
113
115
114
116
impl Image {
@@ -233,7 +235,9 @@ impl Image {
233
235
} ) ?;
234
236
235
237
self . caches . extend_from_slice ( & src. caches ) ;
236
- self . asids . extend ( & src. asids ) ;
238
+ for asid in & src. asids {
239
+ self . asids . insert ( asid. clone ( ) ) ;
240
+ }
237
241
Ok ( res)
238
242
}
239
243
@@ -252,7 +256,7 @@ impl Image {
252
256
) -> Result < ( ) , PtError > {
253
257
let asid_ptr = if let Some ( a) = asid {
254
258
// fixme: use get_or_insert once stable (if ever)
255
- self . asids . insert ( * a ) ;
259
+ self . asids . insert ( Rc :: new ( * a ) ) ;
256
260
& raw const self . asids . get ( a) . unwrap ( ) . 0
257
261
} else {
258
262
ptr:: null ( )
@@ -275,9 +279,6 @@ impl Image {
275
279
) ;
276
280
} ) ?;
277
281
self . caches . push ( iscache) ;
278
- if let Some ( a) = asid {
279
- self . asids . insert ( * a) ;
280
- }
281
282
Ok ( ( ) )
282
283
}
283
284
@@ -303,7 +304,7 @@ impl Image {
303
304
let cfilename = str_to_cstring_pterror ( filename) ?;
304
305
let asid_ptr = if let Some ( a) = asid {
305
306
// fixme: use get_or_insert once stable (if ever)
306
- self . asids . insert ( * a ) ;
307
+ self . asids . insert ( Rc :: new ( * a ) ) ;
307
308
& raw const self . asids . get ( a) . unwrap ( ) . 0
308
309
} else {
309
310
ptr:: null ( )
@@ -318,9 +319,6 @@ impl Image {
318
319
vaddr,
319
320
)
320
321
} ) ?;
321
- if let Some ( a) = asid {
322
- self . asids . insert ( * a) ;
323
- }
324
322
Ok ( ( ) )
325
323
}
326
324
}
@@ -488,4 +486,29 @@ mod test {
488
486
i. add_cached ( Rc :: new ( c) , isid, Some ( & asid) ) . unwrap ( ) ;
489
487
assert_eq ! ( i. remove_by_asid( & asid) . unwrap( ) , 1 ) ;
490
488
}
489
+
490
+ #[ test]
491
+ fn img_extend ( ) {
492
+ let file: PathBuf = [ env ! ( "CARGO_MANIFEST_DIR" ) , "testfiles" , "garbage.txt" ]
493
+ . iter ( )
494
+ . collect ( ) ;
495
+
496
+ let mut img = Image :: new ( None ) . unwrap ( ) ;
497
+ {
498
+ let mut img2 = Image :: new ( None ) . unwrap ( ) ;
499
+ for i in 0 ..100 {
500
+ let mut cache = SectionCache :: new ( None ) . unwrap ( ) ;
501
+ let asid = Asid :: new ( Some ( i) , Some ( i) ) ;
502
+ let isid = cache. add_file ( file. to_str ( ) . unwrap ( ) , i, 1 , i) . unwrap ( ) ;
503
+ let rc = Rc :: new ( cache) ;
504
+ img2. add_cached ( rc. clone ( ) , isid, Some ( & asid) ) . unwrap ( )
505
+ }
506
+
507
+ img. extend ( & img2) . unwrap ( ) ;
508
+ }
509
+
510
+ for i in 0 ..100 {
511
+ assert_eq ! ( img. remove_by_asid( & Asid :: new( Some ( i) , Some ( i) ) ) . unwrap( ) , 1 ) ;
512
+ }
513
+ }
491
514
}
0 commit comments