@@ -1615,8 +1615,7 @@ unit_addrs_search (const void *vkey, const void *ventry)
16151615
16161616static int
16171617resolve_unit_addrs_overlap_walk (struct backtrace_state * state ,
1618- size_t * pfrom , size_t * pto ,
1619- struct unit_addrs * enclosing ,
1618+ struct backtrace_vector * enclosing ,
16201619 struct unit_addrs_vector * old_vec ,
16211620 backtrace_error_callback error_callback ,
16221621 void * data ,
@@ -1627,91 +1626,100 @@ resolve_unit_addrs_overlap_walk (struct backtrace_state *state,
16271626 struct unit_addrs * new_addrs ;
16281627 size_t from ;
16291628 size_t to ;
1629+ size_t enclosing_count ;
16301630
16311631 old_addrs = (struct unit_addrs * ) old_vec -> vec .base ;
16321632 old_count = old_vec -> count ;
16331633 new_addrs = (struct unit_addrs * ) new_vec -> vec .base ;
16341634
1635- for (from = * pfrom , to = * pto ; from < old_count ; from ++ , to ++ )
1635+ enclosing_count = 0 ;
1636+
1637+ to = 0 ;
1638+ for (from = 0 ; from < old_count ; from ++ )
16361639 {
1637- /* If we are in the scope of a larger range that can no longer
1638- cover any further ranges, return back to the caller. */
1640+ struct unit_addrs * current_enclosing ;
1641+ new_addrs [to ] = old_addrs [from ];
1642+ to ++ ;
1643+
1644+ /* While we are in the scope of a larger range that can no longer
1645+ cover any further ranges, pop it from the enclosing stack. */
1646+ while (enclosing_count > 0
1647+ && ((struct unit_addrs * * )enclosing -> base )[enclosing_count - 1 ]-> high <= old_addrs [from ].low )
1648+ {
1649+ enclosing_count -- ;
1650+ enclosing -> alc += sizeof (struct unit_addrs * );
1651+ }
1652+ if (enclosing_count > 0 ) {
1653+ current_enclosing = ((struct unit_addrs * * )enclosing -> base )[enclosing_count - 1 ];
1654+ } else {
1655+ current_enclosing = NULL ;
1656+ }
16391657
1640- if (enclosing != NULL
1641- && enclosing -> high <= old_addrs [from ].low )
1642- {
1643- * pfrom = from ;
1644- * pto = to ;
1645- return 1 ;
1646- }
16471658
1648- new_addrs [to ] = old_addrs [from ];
16491659
16501660 /* If we are in scope of a larger range, fill in any gaps
16511661 between this entry and the next one.
16521662
16531663 There is an extra entry at the end of the vector, so it's
16541664 always OK to refer to from + 1. */
16551665
1656- if (enclosing != NULL
1657- && enclosing -> high > old_addrs [from ].high
1658- && old_addrs [from ].high < old_addrs [from + 1 ].low )
1659- {
1660- void * grew ;
1661- size_t new_high ;
1666+ if (current_enclosing != NULL
1667+ && current_enclosing -> high > old_addrs [from ].high
1668+ && old_addrs [from ].high < old_addrs [from + 1 ].low )
1669+ {
1670+ void * grew ;
1671+ size_t new_high ;
16621672
1663- grew = backtrace_vector_grow (state , sizeof (struct unit_addrs ),
1673+ grew = backtrace_vector_grow (state , sizeof (struct unit_addrs ),
16641674 error_callback , data , & new_vec -> vec );
1665- if (grew == NULL )
1666- return 0 ;
1667- new_addrs = (struct unit_addrs * ) new_vec -> vec .base ;
1668- to ++ ;
1669- new_addrs [ to ]. low = old_addrs [from ]. high ;
1670- new_high = old_addrs [ from + 1 ]. low ;
1671- if ( enclosing -> high < new_high )
1672- new_high = enclosing -> high ;
1673- new_addrs [to ].high = new_high ;
1674- new_addrs [ to ]. u = enclosing -> u ;
1675- }
1675+ if (grew == NULL )
1676+ return 0 ;
1677+ new_addrs = (struct unit_addrs * ) new_vec -> vec .base ;
1678+ new_addrs [ to ]. low = old_addrs [ from ]. high ;
1679+ new_high = old_addrs [from + 1 ]. low ;
1680+ if ( current_enclosing -> high < new_high )
1681+ new_high = current_enclosing -> high ;
1682+ new_addrs [ to ]. high = new_high ;
1683+ new_addrs [to ].u = current_enclosing -> u ;
1684+ to ++ ;
1685+ }
16761686
16771687 /* If this range has a larger scope than the next one, use it to
1678- fill in any gaps. */
1688+ fill in any gaps. */
16791689
16801690 if (old_addrs [from ].high > old_addrs [from + 1 ].high )
1681- {
1682- * pfrom = from + 1 ;
1683- * pto = to + 1 ;
1684- if (!resolve_unit_addrs_overlap_walk (state , pfrom , pto ,
1685- & old_addrs [from ], old_vec ,
1686- error_callback , data , new_vec ))
1687- return 0 ;
1688- from = * pfrom ;
1689- to = * pto ;
1690-
1691- /* Undo the increment the loop is about to do. */
1692- from -- ;
1693- to -- ;
1694- }
1691+ {
1692+ void * grew ;
1693+ struct unit_addrs * * enclosing_top ;
1694+
1695+ grew = backtrace_vector_grow (state , sizeof (struct unit_addrs * ),
1696+ error_callback , data , enclosing );
1697+ if (grew == NULL )
1698+ return 0 ;
1699+ enclosing_top = ((struct unit_addrs * * ) (enclosing -> base )) + enclosing_count ;
1700+
1701+ * enclosing_top = & old_addrs [from ];
1702+ }
16951703 }
16961704
1697- if ( enclosing == NULL )
1698- {
1699- struct unit_addrs * pa ;
1705+
1706+
1707+ struct unit_addrs * pa ;
17001708
1701- /* Add trailing entry. */
1709+ /* Add trailing entry. */
17021710
1703- pa = ((struct unit_addrs * )
1704- backtrace_vector_grow (state , sizeof (struct unit_addrs ),
1705- error_callback , data , & new_vec -> vec ));
1706- if (pa == NULL )
1707- return 0 ;
1708- pa -> low = 0 ;
1709- -- pa -> low ;
1710- pa -> high = pa -> low ;
1711- pa -> u = NULL ;
1711+ pa = ((struct unit_addrs * )
1712+ backtrace_vector_grow (state , sizeof (struct unit_addrs ),
1713+ error_callback , data , & new_vec -> vec ));
1714+ if (pa == NULL )
1715+ return 0 ;
1716+ pa -> low = 0 ;
1717+ -- pa -> low ;
1718+ pa -> high = pa -> low ;
1719+ pa -> u = NULL ;
17121720
1713- new_vec -> count = to ;
1714- }
1721+ new_vec -> count = to ;
1722+
17151723
17161724 return 1 ;
17171725}
@@ -1756,8 +1764,8 @@ resolve_unit_addrs_overlap (struct backtrace_state *state,
17561764 size_t i ;
17571765 struct unit_addrs_vector new_vec ;
17581766 void * grew ;
1759- size_t from ;
1760- size_t to ;
1767+ int walk_ok ;
1768+ struct backtrace_vector enclosing ;
17611769
17621770 addrs = (struct unit_addrs * ) addrs_vec -> vec .base ;
17631771 count = addrs_vec -> count ;
@@ -1787,15 +1795,16 @@ resolve_unit_addrs_overlap (struct backtrace_state *state,
17871795 error_callback , data , & new_vec .vec );
17881796 if (grew == NULL )
17891797 return 0 ;
1798+ memset (& enclosing , 0 , sizeof enclosing );
17901799
1791- from = 0 ;
1792- to = 0 ;
1793- resolve_unit_addrs_overlap_walk (state , & from , & to , NULL , addrs_vec ,
1800+ walk_ok = resolve_unit_addrs_overlap_walk (state , & enclosing , addrs_vec ,
17941801 error_callback , data , & new_vec );
17951802 backtrace_vector_free (state , & addrs_vec -> vec , error_callback , data );
1796- * addrs_vec = new_vec ;
1803+ backtrace_vector_free (state , & enclosing , error_callback , data );
1804+ if (walk_ok )
1805+ * addrs_vec = new_vec ;
17971806
1798- return 1 ;
1807+ return walk_ok ;
17991808}
18001809
18011810/* Sort the line vector by PC. We want a stable sort here to maintain
0 commit comments