diff --git a/libgcc/unwind-dw2-fde.c b/libgcc/unwind-dw2-fde.c index d7c4a467754..51129906fac 100644 --- a/libgcc/unwind-dw2-fde.c +++ b/libgcc/unwind-dw2-fde.c @@ -124,6 +124,9 @@ __register_frame_info_bases (const void *begin, struct object *ob, #endif #ifdef ATOMIC_FDE_FAST_PATH + // Register the object itself to know the base pointer on deregistration. + btree_insert (®istered_frames, (uintptr_type) begin, 1, ob); + // Register the frame in the b-tree uintptr_type range[2]; get_pc_range (ob, range); @@ -175,6 +178,9 @@ __register_frame_info_table_bases (void *begin, struct object *ob, ob->s.b.encoding = DW_EH_PE_omit; #ifdef ATOMIC_FDE_FAST_PATH + // Register the object itself to know the base pointer on deregistration. + btree_insert (®istered_frames, (uintptr_type) begin, 1, ob); + // Register the frame in the b-tree uintptr_type range[2]; get_pc_range (ob, range); @@ -225,22 +231,17 @@ __deregister_frame_info_bases (const void *begin) return ob; #ifdef ATOMIC_FDE_FAST_PATH - // Find the corresponding PC range - struct object lookupob; - lookupob.tbase = 0; - lookupob.dbase = 0; - lookupob.u.single = begin; - lookupob.s.i = 0; - lookupob.s.b.encoding = DW_EH_PE_omit; -#ifdef DWARF2_OBJECT_END_PTR_EXTENSION - lookupob.fde_end = NULL; -#endif - uintptr_type range[2]; - get_pc_range (&lookupob, range); + // Find the originally registered object to get the base pointer. + ob = btree_remove (®istered_frames, (uintptr_type) begin); - // And remove - ob = btree_remove (®istered_frames, range[0]); - bool empty_table = (range[1] - range[0]) == 0; + // Remove the corresponding PC range. + if (ob) + { + uintptr_type range[2]; + get_pc_range (ob, range); + if (range[0] != range[1]) + btree_remove (®istered_frames, range[0]); + } // Deallocate the sort array if any. if (ob && ob->s.b.sorted) @@ -283,12 +284,11 @@ __deregister_frame_info_bases (const void *begin) out: __gthread_mutex_unlock (&object_mutex); - const int empty_table = 0; // The non-atomic path stores all tables. #endif // If we didn't find anything in the lookup data structures then they // were either already destroyed or we tried to remove an empty range. - gcc_assert (in_shutdown || (empty_table || ob)); + gcc_assert (in_shutdown || ob); return (void *) ob; }