void VG_(redir_notify_delete_DebugInfo)( DebugInfo* delsi ) { TopSpec* ts; TopSpec* tsPrev; Spec* sp; Spec* sp_next; OSet* tmpSet; Active* act; Bool delMe; Addr addr; vg_assert(delsi); /* Search for it, and make tsPrev point to the previous entry, if any. */ tsPrev = NULL; ts = topSpecs; while (True) { if (ts == NULL) break; if (ts->seginfo == delsi) break; tsPrev = ts; ts = ts->next; } vg_assert(ts); /* else we don't have the deleted DebugInfo */ vg_assert(ts->seginfo == delsi); /* Traverse the actives, copying the addresses of those we intend to delete into tmpSet. */ tmpSet = VG_(OSetWord_Create)(dinfo_zalloc, "redir.rndD.1", dinfo_free); ts->mark = True; VG_(OSetGen_ResetIter)( activeSet ); while ( (act = VG_(OSetGen_Next)(activeSet)) ) { delMe = act->parent_spec != NULL && act->parent_sym != NULL && act->parent_spec->seginfo != NULL && act->parent_sym->seginfo != NULL && (act->parent_spec->mark || act->parent_sym->mark); /* While we're at it, a bit of paranoia: delete any actives which don't have both feet in valid client executable areas. But don't delete hardwired-at-startup ones; these are denoted by having parent_spec or parent_sym being NULL. */ if ( (!delMe) && act->parent_spec != NULL && act->parent_sym != NULL ) { if (!is_plausible_guest_addr(act->from_addr)) delMe = True; if (!is_plausible_guest_addr(act->to_addr)) delMe = True; } if (delMe) { VG_(OSetWord_Insert)( tmpSet, act->from_addr ); /* While we have our hands on both the 'from' and 'to' of this Active, do paranoid stuff with tt/tc. */ VG_(discard_translations)( (Addr64)act->from_addr, 1, "redir_del_DebugInfo(from_addr)"); VG_(discard_translations)( (Addr64)act->to_addr, 1, "redir_del_DebugInfo(to_addr)"); } } /* Now traverse tmpSet, deleting corresponding elements in activeSet. */ VG_(OSetWord_ResetIter)( tmpSet ); while ( VG_(OSetWord_Next)(tmpSet, &addr) ) { act = VG_(OSetGen_Remove)( activeSet, &addr ); vg_assert(act); VG_(OSetGen_FreeNode)( activeSet, act ); } VG_(OSetWord_Destroy)( tmpSet ); /* The Actives set is now cleaned up. Free up this TopSpec and everything hanging off it. */ for (sp = ts->specs; sp; sp = sp_next) { if (sp->from_sopatt) dinfo_free(sp->from_sopatt); if (sp->from_fnpatt) dinfo_free(sp->from_fnpatt); sp_next = sp->next; dinfo_free(sp); } if (tsPrev == NULL) { /* first in list */ topSpecs = ts->next; } else { tsPrev->next = ts->next; } dinfo_free(ts); if (VG_(clo_trace_redir)) show_redir_state("after VG_(redir_notify_delete_DebugInfo)"); }
static void free_symname_array ( UChar** names, UChar** twoslots ) { if (names != twoslots) dinfo_free(names); }