@@ -39,6 +39,13 @@ impl Address {
3939 pub fn zero_pad ( & self ) -> String {
4040 format ! ( "{:0>16}" , self . start)
4141 }
42+
43+ // Checks whether an entry's address range overlaps the limits specified by the range option.
44+ // Note: Even if a reversed range (high < low) is given, an entry still hits
45+ // only if the specified range lies entirely within the entry's address range.
46+ pub fn is_within_range ( & self , pmap_config : & PmapConfig ) -> bool {
47+ pmap_config. range_low < self . high && self . low <= pmap_config. range_high
48+ }
4249}
4350
4451// Represents a set of permissions from the "perms" column of /proc/<PID>/maps.
@@ -341,6 +348,90 @@ mod test {
341348 assert ! ( parse_address( "ffffffffff600000-zfffffffff601000" ) . is_err( ) ) ;
342349 }
343350
351+ fn limit_address_range_and_assert ( address : & Address , low : u64 , high : u64 , expected : bool ) {
352+ let mut pmap_config = PmapConfig :: default ( ) ;
353+ ( pmap_config. range_low , pmap_config. range_high ) = ( low, high) ;
354+ assert_eq ! (
355+ address. is_within_range( & pmap_config) ,
356+ expected,
357+ "`--range 0x{low:x},0x{high:x}` expected to be {expected} for address 0x{:x},0x{:x}" ,
358+ address. low,
359+ address. high,
360+ ) ;
361+ }
362+
363+ #[ test]
364+ fn test_limit_address_range ( ) {
365+ let low: u64 = 0x71af50000000 ;
366+ let high: u64 = 0x71af50021000 ;
367+ let address = Address {
368+ start : "0x71af50000000" . to_string ( ) ,
369+ low,
370+ high,
371+ } ;
372+
373+ limit_address_range_and_assert ( & address, 0x0 , u64:: MAX , true ) ;
374+ limit_address_range_and_assert ( & address, 0x70000000 , 0xffffffffffff , true ) ;
375+
376+ limit_address_range_and_assert ( & address, 0x0 , 0x0 , false ) ;
377+ limit_address_range_and_assert ( & address, 0x0 , 0x70000000 , false ) ;
378+ limit_address_range_and_assert ( & address, 0x0 , low - 1 , false ) ;
379+ limit_address_range_and_assert ( & address, low - 1 , low - 1 , false ) ;
380+
381+ limit_address_range_and_assert ( & address, 0x0 , low + 0 , true ) ;
382+ limit_address_range_and_assert ( & address, low - 1 , low + 0 , true ) ;
383+ limit_address_range_and_assert ( & address, low + 0 , low + 0 , true ) ;
384+
385+ limit_address_range_and_assert ( & address, low - 1 , high - 1 , true ) ;
386+ limit_address_range_and_assert ( & address, low - 1 , high + 0 , true ) ;
387+ limit_address_range_and_assert ( & address, low - 1 , high + 1 , true ) ;
388+ limit_address_range_and_assert ( & address, low + 0 , high - 1 , true ) ;
389+ limit_address_range_and_assert ( & address, low + 0 , high + 0 , true ) ;
390+ limit_address_range_and_assert ( & address, low + 0 , high + 1 , true ) ;
391+ limit_address_range_and_assert ( & address, low + 1 , high - 1 , true ) ;
392+ limit_address_range_and_assert ( & address, low + 1 , high + 0 , true ) ;
393+ limit_address_range_and_assert ( & address, low + 1 , high + 1 , true ) ;
394+
395+ limit_address_range_and_assert ( & address, high - 1 , high - 1 , true ) ;
396+ limit_address_range_and_assert ( & address, high - 1 , high + 0 , true ) ;
397+ limit_address_range_and_assert ( & address, high - 1 , u64:: MAX , true ) ;
398+
399+ limit_address_range_and_assert ( & address, high + 0 , high + 0 , false ) ;
400+ limit_address_range_and_assert ( & address, high + 0 , high + 1 , false ) ;
401+ limit_address_range_and_assert ( & address, high + 0 , u64:: MAX , false ) ;
402+ limit_address_range_and_assert ( & address, 0xffffffffffff , u64:: MAX , false ) ;
403+ limit_address_range_and_assert ( & address, u64:: MAX , u64:: MAX , false ) ;
404+
405+ // Reversed range
406+
407+ limit_address_range_and_assert ( & address, u64:: MAX , 0 , false ) ;
408+ limit_address_range_and_assert ( & address, 0xffffffffffff , 0x70000000 , false ) ;
409+
410+ limit_address_range_and_assert ( & address, 0x70000000 , 0x0 , false ) ;
411+ limit_address_range_and_assert ( & address, low - 1 , 0x0 , false ) ;
412+ limit_address_range_and_assert ( & address, low - 1 , low - 1 , false ) ;
413+
414+ limit_address_range_and_assert ( & address, low + 0 , 0x0 , false ) ;
415+ limit_address_range_and_assert ( & address, low + 0 , low - 1 , false ) ;
416+
417+ limit_address_range_and_assert ( & address, high - 1 , low - 1 , false ) ;
418+ limit_address_range_and_assert ( & address, high + 0 , low - 1 , false ) ;
419+ limit_address_range_and_assert ( & address, high + 1 , low - 1 , false ) ;
420+ limit_address_range_and_assert ( & address, high - 1 , low + 0 , true ) ; // true
421+ limit_address_range_and_assert ( & address, high + 0 , low + 0 , false ) ;
422+ limit_address_range_and_assert ( & address, high + 1 , low + 0 , false ) ;
423+ limit_address_range_and_assert ( & address, high - 1 , low + 1 , true ) ; // true
424+ limit_address_range_and_assert ( & address, high + 0 , low + 1 , false ) ;
425+ limit_address_range_and_assert ( & address, high + 1 , low + 1 , false ) ;
426+
427+ limit_address_range_and_assert ( & address, high + 0 , high - 1 , false ) ;
428+ limit_address_range_and_assert ( & address, u64:: MAX , high - 1 , false ) ;
429+
430+ limit_address_range_and_assert ( & address, high + 1 , high + 0 , false ) ;
431+ limit_address_range_and_assert ( & address, u64:: MAX , high + 0 , false ) ;
432+ limit_address_range_and_assert ( & address, u64:: MAX , 0xffffffffffff , false ) ;
433+ }
434+
344435 #[ test]
345436 fn test_parse_device ( ) {
346437 assert_eq ! ( "12:34" , parse_device( "12:34" ) . unwrap( ) . to_string( ) ) ;
0 commit comments