@@ -572,14 +572,25 @@ fn merge_adjacent_segments(mut segments: Vec<Segment<'_>>) -> Vec<Segment<'_>> {
572
572
573
573
let mut merged: Vec < Segment < ' _ > > = Vec :: with_capacity ( segments. len ( ) ) ;
574
574
for segment in segments {
575
- match merged. last_mut ( ) {
576
- Some ( last) if last. addr + last. size ( ) == segment. addr => {
575
+ if let Some ( last) = merged. last_mut ( ) {
576
+ let last_end = last. addr + last. size ( ) ;
577
+ if last_end == segment. addr {
577
578
* last += segment. data ( ) ;
579
+ continue ;
578
580
}
579
- _ => {
580
- merged. push ( segment) ;
581
+
582
+ // There is some space between the segments. We can merge them if they would
583
+ // either be contiguous, or overlap, if the first segment was 4-byte
584
+ // aligned.
585
+ let max_padding = ( 4 - last_end % 4 ) % 4 ;
586
+ if last_end + max_padding >= segment. addr {
587
+ * last += & [ 0u8 ; 4 ] [ ..( segment. addr - last_end) as usize ] ;
588
+ * last += segment. data ( ) ;
589
+ continue ;
581
590
}
582
591
}
592
+
593
+ merged. push ( segment)
583
594
}
584
595
585
596
merged
@@ -681,4 +692,18 @@ mod tests {
681
692
682
693
assert_eq ! ( encode_hex( & [ 222u8 , 202 , 251 , 173 ] ) , "decafbad" ) ;
683
694
}
695
+
696
+ #[ test]
697
+ fn merge_adjacent_segments_pads ( ) {
698
+ let segments = vec ! [
699
+ Segment :: new( 0x1000 , & [ 0u8 ; 0x100 ] ) ,
700
+ Segment :: new( 0x1100 , & [ 0u8 ; 0xFF ] ) ,
701
+ Segment :: new( 0x1200 , & [ 0u8 ; 0x100 ] ) ,
702
+ ] ;
703
+
704
+ let merged = merge_adjacent_segments ( segments) ;
705
+ assert_eq ! ( merged. len( ) , 1 ) ;
706
+ assert_eq ! ( merged[ 0 ] . addr, 0x1000 ) ;
707
+ assert_eq ! ( merged[ 0 ] . size( ) , 0x300 ) ;
708
+ }
684
709
}
0 commit comments