@@ -293,6 +293,67 @@ fn split_extabindex(obj: &mut ObjInfo, start: SectionAddress) -> Result<()> {
293293 }
294294 }
295295
296+ // Pass 3: Merge groups with overlapping extabindex ranges.
297+ // After absorption, two groups may have interleaved extabindex entries,
298+ // producing overlapping covering splits. Merge such groups.
299+ if num_groups > 1 {
300+ // Compute extabindex range [eti_min, eti_max] for each group.
301+ let mut group_eti_ranges: Vec < Option < ( u32 , u32 ) > > = vec ! [ None ; num_groups] ;
302+ for ( i, & g) in group_ids. iter ( ) . enumerate ( ) {
303+ let addr = entries[ i] . eti_address . address ;
304+ match & mut group_eti_ranges[ g] {
305+ Some ( ( min, max) ) => {
306+ * min = ( * min) . min ( addr) ;
307+ * max = ( * max) . max ( addr) ;
308+ }
309+ None => {
310+ group_eti_ranges[ g] = Some ( ( addr, addr) ) ;
311+ }
312+ }
313+ }
314+
315+ // Sort groups by eti_min and merge overlapping ones.
316+ // Build a list of (eti_min, eti_end, group_id) for non-empty groups.
317+ let mut sorted_groups: Vec < ( u32 , u32 , usize ) > = group_eti_ranges
318+ . iter ( )
319+ . enumerate ( )
320+ . filter_map ( |( g, range) | range. map ( |( min, max) | ( min, max + 12 , g) ) )
321+ . collect ( ) ;
322+ sorted_groups. sort_by_key ( |& ( min, _, _) | min) ;
323+
324+ let mut merged = true ;
325+ while merged {
326+ merged = false ;
327+ for i in 0 ..sorted_groups. len ( ) . saturating_sub ( 1 ) {
328+ let ( _, end_a, ga) = sorted_groups[ i] ;
329+ let ( start_b, end_b, gb) = sorted_groups[ i + 1 ] ;
330+ if start_b < end_a && ga != gb {
331+ // Overlapping ranges: merge gb into ga.
332+ let merge_into = ga. min ( gb) ;
333+ let merge_from = ga. max ( gb) ;
334+ for gid in group_ids. iter_mut ( ) {
335+ if * gid == merge_from {
336+ * gid = merge_into;
337+ }
338+ }
339+ // Update the range for the merged group.
340+ sorted_groups[ i] . 1 = end_a. max ( end_b) ;
341+ sorted_groups[ i] . 2 = merge_into;
342+ sorted_groups. remove ( i + 1 ) ;
343+ merged = true ;
344+ log:: debug!(
345+ "Merged overlapping groups {} and {} (extabindex range {:#010X}-{:#010X})" ,
346+ merge_from,
347+ merge_into,
348+ sorted_groups[ i] . 0 ,
349+ sorted_groups[ i] . 1 ,
350+ ) ;
351+ break ;
352+ }
353+ }
354+ }
355+ }
356+
296357 // Build group ranges: collect entry indices per group, in iteration order.
297358 let mut group_entries: Vec < Vec < usize > > = vec ! [ Vec :: new( ) ; num_groups] ;
298359 for ( i, & g) in group_ids. iter ( ) . enumerate ( ) {
0 commit comments