diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index 9f8a612c374..0f322a5c352 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -337,6 +337,7 @@ struct module /* symbols & symbol tables */ int sortlist_valid; unsigned num_sorttab; /* number of symbols with addresses */ + unsigned num_symbols; struct symt_ht** addr_sorttab; struct hash_table ht_symbols; void (*loc_compute)(struct process* pcs, diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c index 1a3d94e316d..c71c7e9b5ec 100644 --- a/dlls/dbghelp/module.c +++ b/dlls/dbghelp/module.c @@ -169,6 +169,8 @@ struct module* module_new(struct process* pcs, const WCHAR* name, module->is_virtual = virtual ? TRUE : FALSE; module->sortlist_valid = FALSE; module->addr_sorttab = NULL; + module->num_sorttab = 0; + module->num_symbols = 0; /* FIXME: this seems a bit too high (on a per module basis) * need some statistics about this */ @@ -1036,6 +1038,7 @@ void module_reset_debug_info(struct module* module) { module->sortlist_valid = TRUE; module->addr_sorttab = NULL; + module->num_sorttab = module->num_symbols = 0; hash_table_destroy(&module->ht_symbols); module->ht_symbols.num_buckets = 0; module->ht_symbols.buckets = NULL; diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c index 25f9ec9e37c..b3e97d2ea3e 100644 --- a/dlls/dbghelp/symbol.c +++ b/dlls/dbghelp/symbol.c @@ -67,10 +67,34 @@ int symt_cmp_addr(const void* p1, const void* p2) return cmp_addr(a1, a2); } +static BOOL symt_grow_sorttab(struct module* module, unsigned sz) +{ + struct symt_ht** new; + + if (module->addr_sorttab) + new = HeapReAlloc(GetProcessHeap(), 0, module->addr_sorttab, + sz * sizeof(struct symt_ht*)); + else + new = HeapAlloc(GetProcessHeap(), 0, sz * sizeof(struct symt_ht*)); + if (!new) return FALSE; + module->addr_sorttab = new; + return TRUE; +} + static void symt_add_module_ht(struct module* module, struct symt_ht* ht) { + ULONG64 addr; + hash_table_add(&module->ht_symbols, &ht->hash_elt); - module->sortlist_valid = FALSE; + /* Don't store in sorttab a symbol without address, they are of + * no use here (e.g. constant values) + */ + if (symt_get_info(&ht->symt, TI_GET_ADDRESS, &addr) && + symt_grow_sorttab(module, module->num_symbols + 1)) + { + module->addr_sorttab[module->num_symbols++] = ht; + module->sortlist_valid = FALSE; + } } #ifdef HAVE_REGEX_H @@ -766,38 +790,11 @@ static BOOL symt_enum_module(struct module_pair* pair, const regex_t* regex, */ static BOOL resort_symbols(struct module* module) { - void* ptr; - struct symt_ht* sym; - struct hash_table_iter hti; - ULONG64 addr; - - if (!(module->module.NumSyms = module->ht_symbols.num_elts)) + if (!(module->module.NumSyms = module->num_symbols)) return FALSE; - - if (module->addr_sorttab) - module->addr_sorttab = HeapReAlloc(GetProcessHeap(), 0, - module->addr_sorttab, - module->module.NumSyms * sizeof(struct symt_ht*)); - else - module->addr_sorttab = HeapAlloc(GetProcessHeap(), 0, - module->module.NumSyms * sizeof(struct symt_ht*)); - if (!module->addr_sorttab) return FALSE; - module->num_sorttab = 0; - hash_table_iter_init(&module->ht_symbols, &hti, NULL); - while ((ptr = hash_table_iter_up(&hti))) - { - sym = GET_ENTRY(ptr, struct symt_ht, hash_elt); - assert(sym); - /* Don't store in sorttab symbol without address, they are of - * no use here (e.g. constant values) - * As the number of those symbols is very couple (a couple per module) - * we don't bother for the unused spots at the end of addr_sorttab - */ - if (symt_get_info(&sym->symt, TI_GET_ADDRESS, &addr)) - module->addr_sorttab[module->num_sorttab++] = sym; - } - qsort(module->addr_sorttab, module->num_sorttab, sizeof(struct symt_ht*), symt_cmp_addr); + qsort(module->addr_sorttab, module->num_symbols, sizeof(struct symt_ht*), symt_cmp_addr); + module->num_sorttab = module->num_symbols; return module->sortlist_valid = TRUE; }