@@ -97,6 +97,19 @@ impl Drop for BoxedCallback {
97
97
}
98
98
}
99
99
100
+ /// Info of a binary's section that can be used to populate an `Image`
101
+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
102
+ pub struct SectionInfo {
103
+ /// Path of the binary
104
+ pub filename : String ,
105
+ /// Offset of the section in the file
106
+ pub offset : u64 ,
107
+ /// Size of the section
108
+ pub size : u64 ,
109
+ /// Start virtual address of the section once loaded in memory
110
+ pub virtual_address : u64 ,
111
+ }
112
+
100
113
/// An Image defines the memory image that was traced as a collection
101
114
/// of file sections and the virtual addresses at which those sections were loaded.
102
115
#[ derive( Debug ) ]
@@ -109,7 +122,7 @@ pub struct Image {
109
122
callback : Option < BoxedCallback > ,
110
123
caches : Vec < Rc < SectionCache > > ,
111
124
// `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 .
125
+ // share a pointer with libipt, and it must be valid for the entire Image (section) lifetime .
113
126
asids : HashSet < Rc < Asid > > ,
114
127
}
115
128
@@ -321,6 +334,31 @@ impl Image {
321
334
} ) ?;
322
335
Ok ( ( ) )
323
336
}
337
+
338
+ /// Add multiple file sections to the traced memory image, backed by a cache.
339
+ ///
340
+ /// This is the same as creating a `SectionCache` and subsequently calling `add_cached()` for
341
+ /// each section.
342
+ pub fn add_files_cached (
343
+ & mut self ,
344
+ sections_info : & [ SectionInfo ] ,
345
+ asid : Option < & Asid > ,
346
+ ) -> Result < ( ) , PtError > {
347
+ let mut image_cache = SectionCache :: new ( None ) ?;
348
+
349
+ let mut isids = Vec :: with_capacity ( sections_info. len ( ) ) ;
350
+ for s in sections_info {
351
+ let isid = image_cache. add_file ( & s. filename , s. offset , s. size , s. virtual_address ) ?;
352
+ isids. push ( isid) ;
353
+ }
354
+
355
+ let rc_cache = Rc :: new ( image_cache) ;
356
+ for isid in isids {
357
+ self . add_cached ( rc_cache. clone ( ) , isid, asid) ?;
358
+ }
359
+
360
+ Ok ( ( ) )
361
+ }
324
362
}
325
363
326
364
impl Drop for Image {
@@ -511,4 +549,22 @@ mod test {
511
549
assert_eq ! ( img. remove_by_asid( & Asid :: new( Some ( i) , Some ( i) ) ) . unwrap( ) , 1 ) ;
512
550
}
513
551
}
552
+
553
+ #[ test]
554
+ fn img_add_files_cached ( ) {
555
+ let file: PathBuf = [ env ! ( "CARGO_MANIFEST_DIR" ) , "testfiles" , "garbage.txt" ]
556
+ . iter ( )
557
+ . collect ( ) ;
558
+
559
+ let section = SectionInfo {
560
+ filename : file. to_string_lossy ( ) . to_string ( ) ,
561
+ offset : 5 ,
562
+ size : 15 ,
563
+ virtual_address : 0x1337 ,
564
+ } ;
565
+ let mut i = img_with_file ( ) ;
566
+ let asid = Asid :: new ( Some ( 3 ) , Some ( 4 ) ) ;
567
+ i. add_files_cached ( & [ section] , Some ( & asid) ) . unwrap ( ) ;
568
+ assert_eq ! ( i. remove_by_asid( & asid) . unwrap( ) , 1 ) ;
569
+ }
514
570
}
0 commit comments