static int insertbyvalue(void **tree, VALTYPE addr,int ct) { void *retval = 0; /* tsearch adds an entry if its not present already. */ /* Since in this test we do not malloc anything there is no free needed either. Instead we just let tsearch store the value in the pointer in the tree. */ VALTYPE newval = addr; retval = dwarf_tsearch((void *)newval,tree, value_compare_func ); if(retval == 0) { printf("FAIL ENOMEM in search on item %d, value %lu, " "error in insertbyvalue\n", ct, (unsigned long)newval); exit(1); } else { /* Since we insert a value there is no possible distinction to be made between newly-inserted and found-in-tree. */ #ifndef FULL_SPEED_RUN { /* For debugging. */ VALTYPE mt2 = addr; retval = dwarf_tfind((void *)mt2,tree,value_compare_func); if(!retval) { printf("insertone record %d value 0x%lu failed to add" " as desired, error\n", ct,(unsigned long)mt2); return 1; } } #endif /*FULL_SPEED_RUN */ } return 0; }
/* This was once a long list of tests using dss_data and dss_size to see if 'space' was inside a debug section. This tfind approach removes that maintenance headache. */ static int string_is_in_debug_section(Dwarf_Debug dbg,void * space) { /* See dwarf_line.c dwarf_srcfiles() for one way we can wind up with a DW_DLA_STRING string that may or may not be malloc-ed by _dwarf_get_alloc(). dwarf_formstring(), for example, returns strings which point into .debug_info or .debug_types but dwarf_dealloc is never supposed to be applied to strings dwarf_formstring() returns! Lots of calls returning strings have always been documented as requiring dwarf_dealloc(...DW_DLA_STRING) when the code just returns a pointer to a portion of a loaded section! It is too late to change the documentation. */ void *result = 0; result = dwarf_tfind((void *)space, &dbg->de_alloc_tree,simple_compare_function); if(!result) { /* Not in the tree, so not malloc-ed Nothing to delete. */ return TRUE; } /* We found the address in the tree, so it is NOT part of .debug_info or any other dwarf section, but is space malloc-d in _dwarf_get_alloc(). */ return FALSE; }
static struct Macrocheck_Map_Entry_s * macrocheck_map_find(Dwarf_Unsigned offset,void **tree1) { void *retval = 0; struct Macrocheck_Map_Entry_s *re = 0; struct Macrocheck_Map_Entry_s *e = 0; e = macrocheck_map_create_entry(offset,0,0); retval = dwarf_tfind(e,tree1, macrocheck_map_compare_func); if (retval) { re = *(struct Macrocheck_Map_Entry_s **)retval; } /* The one we created here must be deleted, it is dead. We look at the returned one instead. */ macrocheck_map_free_func(e); return re; }
struct Helpertree_Map_Entry_s * helpertree_find(Dwarf_Unsigned offset,struct Helpertree_Base_s *base) { void *retval = 0; struct Helpertree_Map_Entry_s *re = 0; struct Helpertree_Map_Entry_s *e = 0; e = helpertree_map_create_entry(offset,0); retval = dwarf_tfind(e,&base->hb_base, helpertree_map_compare_func); if (retval) { re = *(struct Helpertree_Map_Entry_s **)retval; } /* The one we created here must be deleted, it is dead. We look at the returned one instead. */ helpertree_map_free_func(e); return re; }
/* mt must point to data in static storage for this to make any sense. Malloc()ed data or unique static data for this instance mt points at. For example, if there was an immobile array and make_example_tentry() somehow selected a unique entry. */ static int insertonebypointer(void **tree, unsigned long addr,int ct) { struct example_tentry *mt = 0; void *retval = 0; mt = make_example_tentry(addr,0); /* tsearch adds an entry if its not present already. */ retval = dwarf_tsearch(mt,tree, mt_compare_func ); if(retval == 0) { printf("FAIL ENOMEM in search on rec %d adr 0x%lu," " error in insertonebypointer\n", ct,(unsigned long)addr); exit(1); } else { struct example_tentry *re = 0; re = *(struct example_tentry **)retval; if(re != mt) { /* Found existing, error. */ printf("insertonebypointer rec %d addr %lu 0x%lx found record" " preexisting, error\n", ct, (unsigned long)addr, (unsigned long)addr); mt_free_func(mt); return 1; } else { /* inserted new entry, make sure present. */ #ifndef FULL_SPEED_RUN struct example_tentry *mt2 = make_example_tentry(addr,0); retval = dwarf_tfind(mt2,tree,mt_compare_func); mt_free_func(mt2); if(!retval) { printf("insertonebypointer record %d addr 0x%lu " "failed to add as desired," " error\n", ct,(unsigned long)addr); return 1; } #endif /* FULL_SPEED_RUN */ } } return 0; }
static int findrecsbypointer(int max,int findexpected, const void **tree, const enum insertorder order) { int indx = 0; for(indx = 0 ; indx < max ; ++indx) { char kbuf[40]; char dbuf[60]; dbuf[0] = 0; struct example_tentry *mt = 0; struct example_tentry *retval = 0; int i = 0; i = get_record_id(order,indx); snprintf(kbuf,sizeof(kbuf),"%u",i); mt = make_example_tentry(i,dbuf); printf("findrec %d\n",i); retval = dwarf_tfind(mt,(void *const*)tree,mt_compare_func); if(!retval) { if(indx < findexpected) { mt_free_func(mt); printf("FAIL tfind on %s is FAILURE\n",kbuf); return 1; } else { printf("Not found with tfind on %s is ok\n",kbuf); } } else { printf("found ok %u\n",i); if(indx >= findexpected) { mt_free_func(mt); printf("FAIL: found with tfind on %s is FAILURE\n",kbuf); return 1; } else { printf("Found with tfind on %s is ok\n",kbuf); } } mt_free_func(mt); } return 0; }
static int deletebyvalue(void **tree, unsigned addr,int ct) { void *r = 0; int err=0; VALTYPE newval = addr; /* We are not mallocing, so nothing to free he tree holds simple values for us. */ r = dwarf_tfind((void *)newval,(void *const*)tree,value_compare_func); if (r) { void *r2 = dwarf_tdelete((void *)newval,tree,value_compare_func); if(r2) { /* tdelete returned parent */ } else { /* tdelete returned NULL, tree now empty */ } } else { printf("deletebyvalue action %d could not find rec! error!" " addr 0x%x\n", addr,ct); err = 1; } return err; }
/* For tfind and tdelete one can use static data and take its address for mt instead of using malloc/free. */ static int deleteonebypointer(void **tree, unsigned addr,int ct) { struct example_tentry *mt = 0; struct example_tentry *re3 = 0; void *r = 0; int err=0; mt = make_example_tentry(addr,0); r = dwarf_tfind(mt,(void *const*)tree,mt_compare_func); if (r) { re3 = *(struct example_tentry **)r; dwarf_tdelete(mt,tree,mt_compare_func); mt_free_func(mt); mt_free_func(re3); } else { printf("deleteonebypointer could not find rec %d ! error! addr" " 0x%lx\n", ct,(unsigned long)addr); mt_free_func(mt); err = 1; } return err; }
/* The dodump flag is so we can distinguish binarysearch actions from the binarysearch with eppinger mods easily in the test output. The difference is slight and not significant, but the difference is what we look for when we look. */ static int delrecsbypointer(int max,int findexpected, void **tree,const enum insertorder order,int dodump) { int indx = 0; for (indx = 0; indx < max; indx++) { struct example_tentry *mt = 0; struct example_tentry *re3 = 0; void *r = 0; int i = 0; i = get_record_id(order,indx); printf("delrec %d\n",i); mt = make_example_tentry(i,0); r = dwarf_tfind(mt,(void *const*)tree,mt_compare_func); if (r) { /* This is what tdelete will delete. tdelete just removes the reference from the tree, it does not actually delete the memory for the entry itself. In fact there is no way to know for sure what was done just given the return from tdelete. You just just assume the delete worked and use the tfind result to delete your contents if you want to.*/ re3 = *(struct example_tentry **)r; if(indx < findexpected) { ; } else { mt_free_func(mt); printf("FAIL delrecsbypointer should not have found record to delete for %d\n",i); return 1; } r = dwarf_tdelete(mt,tree,mt_compare_func); if (! *tree) { printf("tree itself now empty\n"); } /* We don't want the 'test' node left around. */ if(r) { /* If the node deleted was root, r is really the new root, not the parent. Or r is non-null but bogus. (so don't print). */ printf("tdelete returned parent or something.\n"); } else { printf("tdelete returned NULL, tree now empty.\n"); #ifdef HASHSEARCH printf("Only really means some hash chain is now empty.\n"); #endif /* HASHSEARCH */ } mt_free_func(mt); mt_free_func(re3); } else { if(indx >= findexpected) { ; } else { mt_free_func(mt); printf("FAIL delrecsbypointer should have found record to delete for %d\n",i); return 1; } /* There is no node like this to delete. */ /* We don't want the 'test' node left around. */ mt_free_func(mt); } if (dodump) { dwarf_tdump( *tree,mt_keyprint,"In Delrecs"); } dwarf_twalk( *tree,walk_entry); } return 0; }