@@ -108,7 +108,9 @@ pub struct Image {
108108 // Any read data callback set by this `Image` instance.
109109 callback : Option < BoxedCallback > ,
110110 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 > > ,
112114}
113115
114116impl Image {
@@ -233,7 +235,9 @@ impl Image {
233235 } ) ?;
234236
235237 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+ }
237241 Ok ( res)
238242 }
239243
@@ -252,7 +256,7 @@ impl Image {
252256 ) -> Result < ( ) , PtError > {
253257 let asid_ptr = if let Some ( a) = asid {
254258 // fixme: use get_or_insert once stable (if ever)
255- self . asids . insert ( * a ) ;
259+ self . asids . insert ( Rc :: new ( * a ) ) ;
256260 & raw const self . asids . get ( a) . unwrap ( ) . 0
257261 } else {
258262 ptr:: null ( )
@@ -275,9 +279,6 @@ impl Image {
275279 ) ;
276280 } ) ?;
277281 self . caches . push ( iscache) ;
278- if let Some ( a) = asid {
279- self . asids . insert ( * a) ;
280- }
281282 Ok ( ( ) )
282283 }
283284
@@ -303,7 +304,7 @@ impl Image {
303304 let cfilename = str_to_cstring_pterror ( filename) ?;
304305 let asid_ptr = if let Some ( a) = asid {
305306 // fixme: use get_or_insert once stable (if ever)
306- self . asids . insert ( * a ) ;
307+ self . asids . insert ( Rc :: new ( * a ) ) ;
307308 & raw const self . asids . get ( a) . unwrap ( ) . 0
308309 } else {
309310 ptr:: null ( )
@@ -318,9 +319,6 @@ impl Image {
318319 vaddr,
319320 )
320321 } ) ?;
321- if let Some ( a) = asid {
322- self . asids . insert ( * a) ;
323- }
324322 Ok ( ( ) )
325323 }
326324}
@@ -488,4 +486,29 @@ mod test {
488486 i. add_cached ( Rc :: new ( c) , isid, Some ( & asid) ) . unwrap ( ) ;
489487 assert_eq ! ( i. remove_by_asid( & asid) . unwrap( ) , 1 ) ;
490488 }
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+ }
491514}
0 commit comments