@@ -572,14 +572,25 @@ fn merge_adjacent_segments(mut segments: Vec<Segment<'_>>) -> Vec<Segment<'_>> {
572572
573573 let mut merged: Vec < Segment < ' _ > > = Vec :: with_capacity ( segments. len ( ) ) ;
574574 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 {
577578 * last += segment. data ( ) ;
579+ continue ;
578580 }
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 ;
581590 }
582591 }
592+
593+ merged. push ( segment)
583594 }
584595
585596 merged
@@ -681,4 +692,18 @@ mod tests {
681692
682693 assert_eq ! ( encode_hex( & [ 222u8 , 202 , 251 , 173 ] ) , "decafbad" ) ;
683694 }
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+ }
684709}
0 commit comments