This MR does: - improve startup time when loading a large PDB file (a chromium based PDB file (larger than 4G) now loads in 3,5s) (at the begining of this rewrite, loading the very same PDB file ended with a reboot triggered by the Linux OOM after 30 minutes of heavy swap) - finally untie the new PDB backend for the old one (they are now considered as two independant debug formats, so that we can eventually drop the old one at some point)
From: Eric Pouech epouech@codeweavers.com
Also introducting helpers to handle a stream as a whole chunk of memory.
Signed-off-by: Eric Pouech epouech@codeweavers.com --- dlls/dbghelp/pdb.c | 140 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 106 insertions(+), 34 deletions(-)
diff --git a/dlls/dbghelp/pdb.c b/dlls/dbghelp/pdb.c index c0dd06e411c..12baa0f8683 100644 --- a/dlls/dbghelp/pdb.c +++ b/dlls/dbghelp/pdb.c @@ -1779,12 +1779,79 @@ static enum pdb_result pdb_reader_read_DBI_codeview_symbol_by_name(struct pdb_re return R_PDB_NOT_FOUND; }
+struct pdb_reader_whole_stream +{ + unsigned short stream_id; + const BYTE *data; +}; + +static enum pdb_result pdb_reader_alloc_and_load_whole_stream(struct pdb_reader *pdb, unsigned short stream_id, struct pdb_reader_whole_stream *whole) +{ + enum pdb_result result; + const uint32_t *blocks; + unsigned num_blocks, i, j; + BYTE *buffer; + + memset(whole, 0, sizeof(*whole)); + if (stream_id >= pdb->toc->num_streams) return R_PDB_INVALID_ARGUMENT; + if (pdb->toc->stream_size[stream_id] == 0 || pdb->toc->stream_size[stream_id] == 0xFFFFFFFF) return R_PDB_NOT_FOUND; + + blocks = pdb->streams[stream_id].blocks; + num_blocks = ((pdboff_t)pdb->toc->stream_size[stream_id] + pdb->block_size - 1) / pdb->block_size; + buffer = HeapAlloc(GetProcessHeap(), 0, num_blocks * pdb->block_size); + if (!buffer) return R_PDB_OUT_OF_MEMORY; + + for (i = 0; i < num_blocks; i = j) + { + /* find all contiguous blocks to read them at once */ + for (j = i + 1; j < num_blocks && blocks[j] == blocks[j - 1] + 1; j++) {} + if ((result = pdb_reader_fetch_file_no_cache(pdb, buffer + i * pdb->block_size, + (pdboff_t)blocks[i] * pdb->block_size, (j - i) * pdb->block_size))) + { + HeapFree(GetProcessHeap(), 0, buffer); + return result; + } + } + whole->stream_id = stream_id; + whole->data = buffer; + return R_PDB_SUCCESS; +} + +static enum pdb_result pdb_reader_dispose_whole_stream(struct pdb_reader *pdb, struct pdb_reader_whole_stream *whole) +{ + HeapFree(GetProcessHeap(), 0, (void *)whole->data); + return R_PDB_SUCCESS; +} + +static enum pdb_result pdb_reader_whole_stream_access_codeview_symbol(struct pdb_reader *pdb, struct pdb_reader_whole_stream *whole, + unsigned offset, const union codeview_symbol **cv_symbol) +{ + const union codeview_symbol *cv = (const void *)(whole->data + offset); + if (!whole->data || + offset + sizeof(cv->generic) > pdb->toc->stream_size[whole->stream_id] || + offset + sizeof(cv->generic.len) + cv->generic.len > pdb->toc->stream_size[whole->stream_id]) return R_PDB_INVALID_ARGUMENT; + *cv_symbol = cv; + return R_PDB_SUCCESS; +} + +static int my_action_global_obj_cmp(const void *p1, const void *p2) +{ + pdbsize_t o1 = ((const struct pdb_action_entry *)p1)->stream_offset; + pdbsize_t o2 = ((const struct pdb_action_entry *)p2)->stream_offset; + + if (o1 < o2) return -1; + if (o1 > o2) return +1; + return 0; +} + static enum pdb_result pdb_reader_init_DBI(struct pdb_reader *pdb) { enum pdb_result result; struct pdb_reader_compiland_iterator compiland_iter; struct pdb_reader_walker walker; - union codeview_symbol cv_symbol; + struct pdb_reader_whole_stream whole; + const union codeview_symbol *cv_global_symbol, *cv_global_symbol2; + unsigned hash; symref_t symref; unsigned i;
@@ -1811,40 +1878,43 @@ static enum pdb_result pdb_reader_init_DBI(struct pdb_reader *pdb) } if ((result = pdb_reader_load_DBI_hash_table(pdb))) return result;
- /* register the globals entries not bound to a compiland */ - if ((result = pdb_reader_walker_init(pdb, pdb->dbi_header.gsym_stream, &walker))) return result; - while (pdb_reader_READ(pdb, &walker, &cv_symbol.generic) == R_PDB_SUCCESS) + if ((result = pdb_reader_alloc_and_load_whole_stream(pdb, pdb->dbi_header.gsym_stream, &whole))) return result; + + for (hash = 0; hash < DBI_MAX_HASH; hash++) { - switch (cv_symbol.generic.id) + struct pdb_dbi_hash_entry *entry, *entry2; + DWORD64 address; + symref_t type_symref; + BOOL found; + + if (pdb->dbi_symbols_hash[hash].next == &pdb->dbi_symbols_hash[hash]) continue; + for (entry = &pdb->dbi_symbols_hash[hash]; entry; entry = entry->next) { - case S_UDT: - if ((result = pdb_reader_push_action(pdb, action_type_globals, walker.offset - sizeof(cv_symbol.generic), - cv_symbol.generic.len + sizeof(cv_symbol.generic.len), 0, &symref))) return result; - break; - case S_GDATA32: + if (!pdb_reader_whole_stream_access_codeview_symbol(pdb, &whole, entry->dbi_stream_offset, &cv_global_symbol)) { - DWORD64 address; - symref_t type_symref; - union codeview_symbol *cv_global_symbol; - union codeview_symbol zzcv; - struct pdb_reader_walker global_walker = walker; - pdbsize_t global_hash_offset, global_offset; - - /* There are cases (incremental linking) where we have several entries of same name, but - * only one is valid. - * We discriminate valid with: - * - the hash for that name points to this global entry - * - the address is valid - * - the typeid is valid - * Note: checking address map doesn't bring nothing as the invalid entries are also listed - * there. - */ - global_walker.offset -= sizeof(cv_symbol.generic); - global_offset = global_walker.offset; - if (!pdb_reader_alloc_and_read_full_codeview_symbol(pdb, &global_walker, &cv_global_symbol)) + switch (cv_global_symbol->generic.id) { - if (!pdb_reader_read_DBI_codeview_symbol_by_name(pdb, cv_global_symbol->data_v3.name, &global_hash_offset, &zzcv) && - global_hash_offset == global_offset && + case S_UDT: + if ((result = pdb_reader_push_action(pdb, action_type_globals, entry->dbi_stream_offset, + cv_global_symbol->generic.len + sizeof(cv_global_symbol->generic.len), 0, &symref))) return result; + break; + case S_GDATA32: + /* There are cases (incremental linking) where we have several entries of same name, but + * only one is valid. + * We discriminate valid with: + * - there's no other entry with same name before this entry in hash bucket, + * - the address is valid + * - the typeid is valid + * Note: checking address map doesn't bring nothing as the invalid entries are also listed + * there. + */ + found = FALSE; + for (entry2 = &pdb->dbi_symbols_hash[hash]; !found && entry2 && entry2 != entry; entry2 = entry2->next) + { + if (!pdb_reader_whole_stream_access_codeview_symbol(pdb, &whole, entry2->dbi_stream_offset, &cv_global_symbol2)) + found = !strcmp(cv_global_symbol->data_v3.name, cv_global_symbol2->data_v3.name); + } + if (!found && !pdb_reader_get_segment_address(pdb, cv_global_symbol->data_v3.segment, cv_global_symbol->data_v3.offset, &address) && !pdb_reader_symref_from_cv_typeid(pdb, cv_global_symbol->data_v3.symtype, &type_symref)) { @@ -1852,14 +1922,16 @@ static enum pdb_result pdb_reader_init_DBI(struct pdb_reader *pdb) symt_new_global_variable(pdb->module, 0, cv_global_symbol->data_v3.name, FALSE, loc, 0, type_symref); } - pdb_reader_free(pdb, cv_global_symbol); + break; } } - break; } - walker.offset += cv_symbol.generic.len - sizeof(cv_symbol.generic.id); } + if ((result = pdb_reader_dispose_whole_stream(pdb, &whole))) return result; pdb->num_action_globals = pdb->num_action_entries; + /* as we walked the DBI stream according to hash order, resort by stream_offset */ + qsort(pdb->action_store, pdb->num_action_globals, sizeof(pdb->action_store[0]), + &my_action_global_obj_cmp);
return R_PDB_SUCCESS; }
From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- dlls/dbghelp/pdb.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-)
diff --git a/dlls/dbghelp/pdb.c b/dlls/dbghelp/pdb.c index 12baa0f8683..19c3dc4b2f9 100644 --- a/dlls/dbghelp/pdb.c +++ b/dlls/dbghelp/pdb.c @@ -150,6 +150,7 @@ struct pdb_reader unsigned num_action_entries; struct pdb_action_entry *action_store; struct pdb_dbi_hash_entry *dbi_symbols_hash; + unsigned short dbi_substreams[16]; /* 0 means non existing stream */
/* compilands */ unsigned num_compilands; @@ -1844,6 +1845,28 @@ static int my_action_global_obj_cmp(const void *p1, const void *p2) return 0; }
+static enum pdb_result pdb_reader_init_DBI_substreams(struct pdb_reader *pdb) +{ + enum pdb_result result; + struct pdb_reader_walker walker; + PDB_SYMBOLS dbi_header; + unsigned i; + unsigned short streamid; + + if ((result = pdb_reader_read_DBI_header(pdb, &dbi_header, &walker))) return result; + walker.offset += dbi_header.module_size + dbi_header.sectcontrib_size + + dbi_header.segmap_size + dbi_header.srcmodule_size + + dbi_header.pdbimport_size + dbi_header.unknown2_size; + walker.last = walker.offset + dbi_header.stream_index_size; + for (i = 0; i < ARRAY_SIZE(pdb->dbi_substreams); i++) + { + if (pdb_reader_READ(pdb, &walker, &streamid)) streamid = 0; + pdb->dbi_substreams[i] = streamid; + } + return R_PDB_SUCCESS; +} + + static enum pdb_result pdb_reader_init_DBI(struct pdb_reader *pdb) { enum pdb_result result; @@ -1933,6 +1956,8 @@ static enum pdb_result pdb_reader_init_DBI(struct pdb_reader *pdb) qsort(pdb->action_store, pdb->num_action_globals, sizeof(pdb->action_store[0]), &my_action_global_obj_cmp);
+ if ((result = pdb_reader_init_DBI_substreams(pdb))) return result; + return R_PDB_SUCCESS; }
@@ -5141,13 +5166,13 @@ BOOL pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, BOOL ret = FALSE;
if (!module_init_pair(&pair, csw->hProcess, ip)) return FALSE; - if (!pdb_hack_get_main_info(pair.effective->format_info[DFI_PDB], &pdb, &fpoext_stream)) return FALSE; - + if (!pdb_hack_get_main_info(pair.effective->format_info[DFI_PDB], &pdb, NULL)) return FALSE; if (!pdb) return pdb_old_virtual_unwind(csw, ip, context, cpair); TRACE("searching %Ix => %Ix\n", ip, ip - (DWORD_PTR)pair.effective->module.BaseOfImage); ip -= (DWORD_PTR)pair.effective->module.BaseOfImage;
+ fpoext_stream = pdb->dbi_substreams[PDB_SIDX_FPOEXT]; if (!pdb_reader_walker_init(pdb, fpoext_stream, &walker) && (walker.last % sizeof(fpoext)) == 0) {
From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- dlls/dbghelp/cpu_i386.c | 10 ++---- dlls/dbghelp/dbghelp_private.h | 22 ++++++------- dlls/dbghelp/msc.c | 5 ++- dlls/dbghelp/pdb.c | 58 +++++++++++++++++++++------------- 4 files changed, 50 insertions(+), 45 deletions(-)
diff --git a/dlls/dbghelp/cpu_i386.c b/dlls/dbghelp/cpu_i386.c index a322dfcdda3..42e4c882009 100644 --- a/dlls/dbghelp/cpu_i386.c +++ b/dlls/dbghelp/cpu_i386.c @@ -95,8 +95,7 @@ static BOOL fetch_next_frame32(struct cpu_stack_walk* csw, union ctx *pcontext, DWORD_PTR curr_pc) { DWORD64 xframe; - struct pdb_cmd_pair cpair[4]; - DWORD val32; + DWORD val32; WOW64_CONTEXT *context = &pcontext->x86;
if (dwarf2_virtual_unwind(csw, curr_pc, pcontext, &xframe)) @@ -104,12 +103,9 @@ static BOOL fetch_next_frame32(struct cpu_stack_walk* csw, context->Esp = xframe; return TRUE; } - cpair[0].name = "$ebp"; cpair[0].pvalue = &context->Ebp; - cpair[1].name = "$esp"; cpair[1].pvalue = &context->Esp; - cpair[2].name = "$eip"; cpair[2].pvalue = &context->Eip; - cpair[3].name = NULL; cpair[3].pvalue = NULL;
- if (!pdb_virtual_unwind(csw, curr_pc, pcontext, cpair)) + if (!pdb_virtual_unwind(csw, curr_pc, pcontext) && + !old_pdb_virtual_unwind(csw, curr_pc, pcontext)) { /* do a simple unwind using ebp * we assume a "regular" prologue in the function has been used diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index 21a0112ea89..8ec1fb3a285 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -827,14 +827,9 @@ extern BOOL pe_load_debug_directory(const struct process* pcs, const IMAGE_DEBUG_DIRECTORY* dbg, int nDbg); extern DWORD msc_get_file_indexinfo(void* image, const IMAGE_DEBUG_DIRECTORY* dbgdir, DWORD size, SYMSRV_INDEX_INFOW* info); -struct pdb_cmd_pair { - const char* name; - DWORD* pvalue; -}; -extern BOOL pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, - union ctx *context, struct pdb_cmd_pair *cpair); -extern DWORD pdb_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info); -extern DWORD dbg_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info); +extern DWORD pdb_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info); +extern DWORD dbg_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info); +extern BOOL old_pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, union ctx *context);
/* path.c */ extern BOOL path_find_symbol_file(const struct process *pcs, const struct module *module, @@ -847,6 +842,12 @@ extern BOOL search_unix_path(const WCHAR *name, const WCHAR *path, BOOL (*match) extern const WCHAR* file_name(const WCHAR* str); extern const char* file_nameA(const char* str);
+/* pdb.c */ +extern BOOL pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, union ctx *context); +struct _PDB_FPO_DATA; +extern BOOL pdb_fpo_unwind_parse_cmd_string(struct cpu_stack_walk* csw, struct _PDB_FPO_DATA* fpoext, + const char* cmd, WOW64_CONTEXT *context); + /* pe_module.c */ extern BOOL pe_load_nt_header(HANDLE hProc, DWORD64 base, IMAGE_NT_HEADERS* nth, BOOL* is_builtin); extern struct module* @@ -1087,11 +1088,6 @@ extern struct symt_function* #define IFC_DEPTH(x) ((x) & IFC_DEPTH_MASK)
/* temporary helpers for PDB rewriting */ -struct _PDB_FPO_DATA; -extern BOOL pdb_fpo_unwind_parse_cmd_string(struct cpu_stack_walk* csw, struct _PDB_FPO_DATA* fpoext, - const char* cmd, struct pdb_cmd_pair* cpair); -extern BOOL pdb_old_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, - union ctx *context, struct pdb_cmd_pair *cpair); struct pdb_reader; extern BOOL pdb_hack_get_main_info(struct module_format *modfmt, struct pdb_reader **pdb, unsigned *fpoext_stream); extern void pdb_reader_dispose(struct pdb_reader *pdb); diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c index c5721720537..4fa1134b20c 100644 --- a/dlls/dbghelp/msc.c +++ b/dlls/dbghelp/msc.c @@ -4409,8 +4409,7 @@ DWORD dbg_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info) return msc_get_file_indexinfo(image, dbg, num_directories, info); }
-BOOL pdb_old_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, - union ctx *context, struct pdb_cmd_pair *cpair) +BOOL old_pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, union ctx *context) { struct module_pair pair; struct pdb_module_info* pdb_info; @@ -4443,7 +4442,7 @@ BOOL pdb_old_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, debugstr_a(pdb_get_string_table_entry(strbase, fpoext[i].str_offset))); ret = pdb_fpo_unwind_parse_cmd_string(csw, &fpoext[i], pdb_get_string_table_entry(strbase, fpoext[i].str_offset), - cpair); + &context->x86); break; } } diff --git a/dlls/dbghelp/pdb.c b/dlls/dbghelp/pdb.c index 19c3dc4b2f9..aa32869a256 100644 --- a/dlls/dbghelp/pdb.c +++ b/dlls/dbghelp/pdb.c @@ -5071,8 +5071,7 @@ static BOOL pev_assign(struct pevaluator* pev) }
/* initializes the postfix evaluator */ -static void pev_init(struct pevaluator* pev, struct cpu_stack_walk* csw, - const PDB_FPO_DATA* fpoext, struct pdb_cmd_pair* cpair) +static void pev_init(struct pevaluator* pev, struct cpu_stack_walk* csw) { pev->csw = csw; pool_init(&pev->pool, 512); @@ -5080,29 +5079,41 @@ static void pev_init(struct pevaluator* pev, struct cpu_stack_walk* csw, pev->stk_index = 0; hash_table_init(&pev->pool, &pev->values, 8); pev->error[0] = '\0'; - for (; cpair->name; cpair++) - pev_set_value(pev, cpair->name, *cpair->pvalue); +} + +static void pev_push_context(struct pevaluator *pev, const WOW64_CONTEXT *context) +{ + pev_set_value(pev, "$ebp", context->Ebp); + pev_set_value(pev, "$esp", context->Esp); + pev_set_value(pev, "$eip", context->Eip); +} + +static void pev_pop_context(struct pevaluator *pev, WOW64_CONTEXT *context) +{ + DWORD_PTR val; + + if (pev_get_val(pev, "$ebp", &val)) context->Ebp = val; + if (pev_get_val(pev, "$esp", &val)) context->Esp = val; + if (pev_get_val(pev, "$eip", &val)) context->Eip = val; +} + +static void pev_push_fpodata(struct pevaluator *pev, const PDB_FPO_DATA* fpoext) +{ + pev_set_value(pev, ".raSearchStart", fpoext->start); pev_set_value(pev, ".cbLocals", fpoext->locals_size); pev_set_value(pev, ".cbParams", fpoext->params_size); pev_set_value(pev, ".cbSavedRegs", fpoext->savedregs_size); }
-static BOOL pev_free(struct pevaluator* pev, struct pdb_cmd_pair* cpair) +static BOOL pev_free(struct pevaluator* pev) { - DWORD_PTR val; - - if (cpair) for (; cpair->name; cpair++) - { - if (pev_get_val(pev, cpair->name, &val)) - *cpair->pvalue = val; - } pool_destroy(&pev->pool); return TRUE; }
-BOOL pdb_fpo_unwind_parse_cmd_string(struct cpu_stack_walk* csw, PDB_FPO_DATA* fpoext, - const char* cmd, struct pdb_cmd_pair* cpair) +BOOL pdb_fpo_unwind_parse_cmd_string(struct cpu_stack_walk* csw, PDB_FPO_DATA* fpoext, + const char* cmd, WOW64_CONTEXT *context) { char token[PEV_MAX_LEN]; char* ptok = token; @@ -5111,7 +5122,9 @@ BOOL pdb_fpo_unwind_parse_cmd_string(struct cpu_stack_walk* csw, PDB_FPO_DATA* struct pevaluator pev;
if (!cmd) return FALSE; - pev_init(&pev, csw, fpoext, cpair); + pev_init(&pev, csw); + pev_push_context(&pev, context); + pev_push_fpodata(&pev, fpoext); for (ptr = cmd; !over; ptr++) { if (*ptr == ' ' || (over = *ptr == '\0')) @@ -5147,16 +5160,16 @@ BOOL pdb_fpo_unwind_parse_cmd_string(struct cpu_stack_walk* csw, PDB_FPO_DATA* *ptok++ = *ptr; } } - pev_free(&pev, cpair); + pev_pop_context(&pev, context); + pev_free(&pev); return TRUE; done: FIXME("Couldn't evaluate %s => %s\n", debugstr_a(cmd), pev.error); - pev_free(&pev, NULL); + pev_free(&pev); return FALSE; }
-BOOL pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, - union ctx *context, struct pdb_cmd_pair *cpair) +BOOL pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, union ctx *context) { struct pdb_reader *pdb; struct pdb_reader_walker walker; @@ -5166,9 +5179,10 @@ BOOL pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, BOOL ret = FALSE;
if (!module_init_pair(&pair, csw->hProcess, ip)) return FALSE; + if (!pair.effective->format_info[DFI_PDB]) return FALSE; if (!pdb_hack_get_main_info(pair.effective->format_info[DFI_PDB], &pdb, NULL)) return FALSE; - if (!pdb) - return pdb_old_virtual_unwind(csw, ip, context, cpair); + if (!pdb) return FALSE; + TRACE("searching %Ix => %Ix\n", ip, ip - (DWORD_PTR)pair.effective->module.BaseOfImage); ip -= (DWORD_PTR)pair.effective->module.BaseOfImage;
@@ -5190,7 +5204,7 @@ BOOL pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, fpoext.savedregs_size, fpoext.flags, debugstr_a(cmd));
- ret = pdb_fpo_unwind_parse_cmd_string(csw, &fpoext, cmd, cpair); + ret = pdb_fpo_unwind_parse_cmd_string(csw, &fpoext, cmd, &context->x86); pdb_reader_free(pdb, cmd); break; }
From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- dlls/dbghelp/dbghelp_private.h | 6 ++--- dlls/dbghelp/module.c | 4 +-- dlls/dbghelp/msc.c | 48 +++++++++++++++++----------------- dlls/dbghelp/pdb.c | 10 +++---- 4 files changed, 34 insertions(+), 34 deletions(-)
diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index 8ec1fb3a285..522c7ba595d 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -414,7 +414,7 @@ enum format_info DFI_PE, DFI_MACHO, DFI_DWARF, - DFI_PDB, + DFI_OLD_PDB, DFI_LAST };
@@ -477,8 +477,8 @@ struct module_format struct elf_module_info* elf_info; struct dwarf2_module_info_s* dwarf2_info; struct pe_module_info* pe_info; - struct macho_module_info* macho_info; - struct pdb_module_info* pdb_info; + struct macho_module_info* macho_info; + struct old_pdb_module_info* old_pdb_info; } u; };
diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c index 258f601bd19..f3dc9f34a62 100644 --- a/dlls/dbghelp/module.c +++ b/dlls/dbghelp/module.c @@ -351,8 +351,8 @@ BOOL module_load_debug(struct module* module) * we could always use the 3 non-zero lower bits of symref_t to match a * debug backend. */ - if (module->format_info[DFI_PDB] && module->format_info[DFI_PDB]->vtable) - module->ops_symref_modfmt = module->format_info[DFI_PDB]; + if (module->format_info[DFI_OLD_PDB] && module->format_info[DFI_OLD_PDB]->vtable) + module->ops_symref_modfmt = module->format_info[DFI_OLD_PDB];
if (!ret) module->module.SymType = SymNone; assert(module->module.SymType != SymDeferred); diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c index 4fa1134b20c..296286d5807 100644 --- a/dlls/dbghelp/msc.c +++ b/dlls/dbghelp/msc.c @@ -80,7 +80,7 @@ struct pdb_file_info
/* FIXME: don't make it static */ #define CV_MAX_MODULES 32 -struct pdb_module_info +struct old_pdb_module_info { unsigned used_subfiles; struct pdb_file_info pdb_files[CV_MAX_MODULES]; @@ -98,10 +98,10 @@ struct cv_module_snarf
BOOL pdb_hack_get_main_info(struct module_format *modfmt, struct pdb_reader **pdb, unsigned *fpoext_stream) { - struct pdb_module_info* pdb_info; + struct old_pdb_module_info* pdb_info;
if (!modfmt) return FALSE; - pdb_info = modfmt->u.pdb_info; + pdb_info = modfmt->u.old_pdb_info; *pdb = pdb_info->pdb_files[0].pdb_reader; if (fpoext_stream) *fpoext_stream = pdb_info->pdb_files[0].fpoext_stream; @@ -668,7 +668,7 @@ static symref_t codeview_fetch_symref(struct codeview_type_parse* ctp, unsigned { symref_t symref;
- if (!cv_hack_ptr_to_symref(ctp->module->format_info[DFI_PDB]->u.pdb_info->pdb_files[0].pdb_reader, typeno, &symref)) + if (!cv_hack_ptr_to_symref(ctp->module->format_info[DFI_OLD_PDB]->u.old_pdb_info->pdb_files[0].pdb_reader, typeno, &symref)) { symref = symt_ptr_to_symref(codeview_fetch_type(ctp, typeno)); } @@ -680,7 +680,7 @@ static symref_t codeview_get_symref(struct module *module, unsigned typeno) { symref_t symref;
- if (!cv_hack_ptr_to_symref(module->format_info[DFI_PDB]->u.pdb_info->pdb_files[0].pdb_reader, typeno, &symref)) + if (!cv_hack_ptr_to_symref(module->format_info[DFI_OLD_PDB]->u.old_pdb_info->pdb_files[0].pdb_reader, typeno, &symref)) { symref = symt_ptr_to_symref(codeview_get_type(typeno, TRUE)); } @@ -1548,7 +1548,7 @@ static BOOL codeview_parse_type_table(struct codeview_type_parse* ctp) unsigned int i, curr_type; const union codeview_type* type;
- cv_current_module->pdb = ctp->module->format_info[DFI_PDB]->u.pdb_info->pdb_files[0].pdb_reader; + cv_current_module->pdb = ctp->module->format_info[DFI_OLD_PDB]->u.old_pdb_info->pdb_files[0].pdb_reader; cv_current_module->first_type_index = ctp->header.first_index; cv_current_module->last_type_index = ctp->header.last_index; cv_current_module->defined_types = calloc(ctp->header.last_index - ctp->header.first_index, @@ -3306,13 +3306,13 @@ static void pdb_module_remove(struct module_format* modfmt) { unsigned i;
- for (i = 0; i < modfmt->u.pdb_info->used_subfiles; i++) + for (i = 0; i < modfmt->u.old_pdb_info->used_subfiles; i++) { - pdb_free_file(&modfmt->u.pdb_info->pdb_files[i], TRUE); - if (modfmt->u.pdb_info->pdb_files[i].image) - UnmapViewOfFile(modfmt->u.pdb_info->pdb_files[i].image); - if (modfmt->u.pdb_info->pdb_files[i].pdb_reader) - pdb_reader_dispose(modfmt->u.pdb_info->pdb_files[i].pdb_reader); + pdb_free_file(&modfmt->u.old_pdb_info->pdb_files[i], TRUE); + if (modfmt->u.old_pdb_info->pdb_files[i].image) + UnmapViewOfFile(modfmt->u.old_pdb_info->pdb_files[i].image); + if (modfmt->u.old_pdb_info->pdb_files[i].pdb_reader) + pdb_reader_dispose(modfmt->u.old_pdb_info->pdb_files[i].pdb_reader); } HeapFree(GetProcessHeap(), 0, modfmt); } @@ -3649,7 +3649,7 @@ static BOOL pdb_init(struct pdb_file_info* pdb_file, const char* image) static BOOL pdb_process_internal(const struct process *pcs, const struct msc_debug_info *msc_dbg, const WCHAR *filename, - struct pdb_module_info *pdb_module_info, + struct old_pdb_module_info *pdb_module_info, unsigned module_index, BOOL *has_linenumber_info);
@@ -3767,7 +3767,7 @@ static void pdb_process_symbol_imports(const struct process *pcs, const PDB_SYMBOLS *symbols, const void *symbols_image, const char *image, - struct pdb_module_info *pdb_module_info, + struct old_pdb_module_info *pdb_module_info, unsigned module_index) { if (module_index == -1 && symbols && symbols->pdbimport_size) @@ -3813,7 +3813,7 @@ static void pdb_process_symbol_imports(const struct process *pcs, static BOOL pdb_process_internal(const struct process *pcs, const struct msc_debug_info *msc_dbg, const WCHAR *filename, - struct pdb_module_info *pdb_module_info, + struct old_pdb_module_info *pdb_module_info, unsigned module_index, BOOL *has_linenumber_info) { @@ -4030,27 +4030,27 @@ static BOOL pdb_process_file(const struct process *pcs, const char *filename, const GUID *guid, DWORD timestamp, DWORD age) { struct module_format* modfmt; - struct pdb_module_info* pdb_module_info; + struct old_pdb_module_info* pdb_module_info; SYMSRV_INDEX_INFOW info; BOOL unmatched;
if (!msc_dbg->module->dont_load_symbols && path_find_symbol_file(pcs, msc_dbg->module, filename, TRUE, guid, timestamp, age, &info, &unmatched) && (modfmt = HeapAlloc(GetProcessHeap(), 0, - sizeof(struct module_format) + sizeof(struct pdb_module_info)))) + sizeof(struct module_format) + sizeof(struct old_pdb_module_info)))) { BOOL ret, has_linenumber_info;
pdb_module_info = (void*)(modfmt + 1); - msc_dbg->module->format_info[DFI_PDB] = modfmt; + msc_dbg->module->format_info[DFI_OLD_PDB] = modfmt; modfmt->module = msc_dbg->module; modfmt->vtable = &old_pdb_module_format_vtable; - modfmt->u.pdb_info = pdb_module_info; + modfmt->u.old_pdb_info = pdb_module_info;
memset(cv_zmodules, 0, sizeof(cv_zmodules)); codeview_init_basic_types(msc_dbg->module); ret = pdb_process_internal(pcs, msc_dbg, info.pdbfile, - msc_dbg->module->format_info[DFI_PDB]->u.pdb_info, -1, &has_linenumber_info); + msc_dbg->module->format_info[DFI_OLD_PDB]->u.old_pdb_info, -1, &has_linenumber_info); codeview_clear_type_table(); if (ret) { @@ -4070,7 +4070,7 @@ static BOOL pdb_process_file(const struct process *pcs,
return TRUE; } - msc_dbg->module->format_info[DFI_PDB] = NULL; + msc_dbg->module->format_info[DFI_OLD_PDB] = NULL; HeapFree(GetProcessHeap(), 0, modfmt); } msc_dbg->module->module.SymType = SymNone; @@ -4412,15 +4412,15 @@ DWORD dbg_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info) BOOL old_pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, union ctx *context) { struct module_pair pair; - struct pdb_module_info* pdb_info; + struct old_pdb_module_info* pdb_info; PDB_FPO_DATA* fpoext; unsigned i, size; PDB_STRING_TABLE* strbase; BOOL ret = TRUE;
if (!module_init_pair(&pair, csw->hProcess, ip)) return FALSE; - if (!pair.effective->format_info[DFI_PDB]) return FALSE; - pdb_info = pair.effective->format_info[DFI_PDB]->u.pdb_info; + if (!pair.effective->format_info[DFI_OLD_PDB]) return FALSE; + pdb_info = pair.effective->format_info[DFI_OLD_PDB]->u.old_pdb_info; TRACE("searching %Ix => %Ix\n", ip, ip - (DWORD_PTR)pair.effective->module.BaseOfImage); ip -= (DWORD_PTR)pair.effective->module.BaseOfImage;
diff --git a/dlls/dbghelp/pdb.c b/dlls/dbghelp/pdb.c index aa32869a256..911d36a344a 100644 --- a/dlls/dbghelp/pdb.c +++ b/dlls/dbghelp/pdb.c @@ -510,7 +510,7 @@ static enum pdb_result pdb_reader_init(struct pdb_reader *pdb, struct module *mo pdb->streams[i].name = NULL; } /* hack (must be set before loading debug info so it can be used therein) */ - pdb->module->ops_symref_modfmt = module->format_info[DFI_PDB]; + pdb->module->ops_symref_modfmt = module->format_info[DFI_OLD_PDB]; pdb_reader_init_DBI(pdb);
return R_PDB_SUCCESS; @@ -4841,9 +4841,9 @@ struct pdb_reader *pdb_hack_reader_init(struct module *module, HANDLE file, cons if (pdb_reader_init(pdb, module, file, new_sections, num_sections) == R_PDB_SUCCESS) { /* hack (copy old pdb methods until they are moved here) */ - pdb_module_format_vtable.remove = module->format_info[DFI_PDB]->vtable->remove; + pdb_module_format_vtable.remove = module->format_info[DFI_OLD_PDB]->vtable->remove;
- module->format_info[DFI_PDB]->vtable = &pdb_module_format_vtable; + module->format_info[DFI_OLD_PDB]->vtable = &pdb_module_format_vtable; return pdb; } } @@ -5179,8 +5179,8 @@ BOOL pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, union ctx *con BOOL ret = FALSE;
if (!module_init_pair(&pair, csw->hProcess, ip)) return FALSE; - if (!pair.effective->format_info[DFI_PDB]) return FALSE; - if (!pdb_hack_get_main_info(pair.effective->format_info[DFI_PDB], &pdb, NULL)) return FALSE; + if (!pair.effective->format_info[DFI_OLD_PDB]) return FALSE; + if (!pdb_hack_get_main_info(pair.effective->format_info[DFI_OLD_PDB], &pdb, NULL)) return FALSE; if (!pdb) return FALSE;
TRACE("searching %Ix => %Ix\n", ip, ip - (DWORD_PTR)pair.effective->module.BaseOfImage);
From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- dlls/dbghelp/dbghelp_private.h | 17 ++-- dlls/dbghelp/module.c | 8 -- dlls/dbghelp/msc.c | 149 ++++++++++++--------------------- dlls/dbghelp/pdb.c | 101 ++++++++++++++-------- 4 files changed, 130 insertions(+), 145 deletions(-)
diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index 522c7ba595d..62019889fe1 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -414,6 +414,7 @@ enum format_info DFI_PE, DFI_MACHO, DFI_DWARF, + DFI_PDB, DFI_OLD_PDB, DFI_LAST }; @@ -479,6 +480,7 @@ struct module_format struct pe_module_info* pe_info; struct macho_module_info* macho_info; struct old_pdb_module_info* old_pdb_info; + struct pdb_module_info* pdb_info; } u; };
@@ -503,7 +505,12 @@ struct module /* specific information for debug types */ struct module_format* format_info[DFI_LAST]; unsigned debug_format_bitmask; - struct module_format *ops_symref_modfmt; /* HACK for fast access to the ops table */ + /* Hack for fast symdef deref... + * Note: if ever we need another backend with dedicated symref_t support, + * we could always use the 3 non-zero lower bits of symref_t to match a + * debug backend. + */ + struct module_format *ops_symref_modfmt;
/* memory allocation pool */ struct pool pool; @@ -843,6 +850,8 @@ extern const WCHAR* file_name(const WCHAR* str); extern const char* file_nameA(const char* str);
/* pdb.c */ +extern BOOL pdb_init_modfmt(const struct process *pcs, const struct msc_debug_info *msc_dbg, + const WCHAR *filename, BOOL *has_linenumber_info); extern BOOL pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, union ctx *context); struct _PDB_FPO_DATA; extern BOOL pdb_fpo_unwind_parse_cmd_string(struct cpu_stack_walk* csw, struct _PDB_FPO_DATA* fpoext, @@ -1087,9 +1096,3 @@ extern struct symt_function* #define IFC_MODE(x) ((x) & ~IFC_DEPTH_MASK) #define IFC_DEPTH(x) ((x) & IFC_DEPTH_MASK)
-/* temporary helpers for PDB rewriting */ -struct pdb_reader; -extern BOOL pdb_hack_get_main_info(struct module_format *modfmt, struct pdb_reader **pdb, unsigned *fpoext_stream); -extern void pdb_reader_dispose(struct pdb_reader *pdb); -extern struct pdb_reader *pdb_hack_reader_init(struct module *module, HANDLE file, const IMAGE_SECTION_HEADER *sections, unsigned num_sections); -extern BOOL cv_hack_ptr_to_symref(struct pdb_reader *pdb, unsigned typeno, symref_t *symref); diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c index f3dc9f34a62..3f009b6b1ef 100644 --- a/dlls/dbghelp/module.c +++ b/dlls/dbghelp/module.c @@ -346,14 +346,6 @@ BOOL module_load_debug(struct module* module) } else ret = module->process->loader->load_debug_info(module->process, module);
- /* Hack for fast symdef deref... - * Note: if ever we need another backend with dedicated symref_t support, - * we could always use the 3 non-zero lower bits of symref_t to match a - * debug backend. - */ - if (module->format_info[DFI_OLD_PDB] && module->format_info[DFI_OLD_PDB]->vtable) - module->ops_symref_modfmt = module->format_info[DFI_OLD_PDB]; - if (!ret) module->module.SymType = SymNone; assert(module->module.SymType != SymDeferred); module->module.NumSyms = module->ht_symbols.num_elts; diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c index 296286d5807..43ee8509a0d 100644 --- a/dlls/dbghelp/msc.c +++ b/dlls/dbghelp/msc.c @@ -61,7 +61,6 @@ enum pdb_kind {PDB_JG, PDB_DS}; struct pdb_file_info { enum pdb_kind kind; - struct pdb_reader *pdb_reader; /* new pdb reader */ const char* image; struct pdb_stream_name* stream_dict; unsigned fpoext_stream; @@ -96,18 +95,6 @@ struct cv_module_snarf const PDB_STRING_TABLE* strimage; };
-BOOL pdb_hack_get_main_info(struct module_format *modfmt, struct pdb_reader **pdb, unsigned *fpoext_stream) -{ - struct old_pdb_module_info* pdb_info; - - if (!modfmt) return FALSE; - pdb_info = modfmt->u.old_pdb_info; - *pdb = pdb_info->pdb_files[0].pdb_reader; - if (fpoext_stream) - *fpoext_stream = pdb_info->pdb_files[0].fpoext_stream; - return TRUE; -} - /*======================================================================== * Debug file access helper routines */ @@ -149,7 +136,6 @@ struct cv_defined_module unsigned int first_type_index; unsigned int last_type_index; struct symt** defined_types; /* when old reader */ - struct pdb_reader *pdb; /* new reader: hack */ }; /* FIXME: don't make it static */ #define CV_MAX_MODULES 32 @@ -666,25 +652,12 @@ static struct symt* codeview_fetch_type(struct codeview_type_parse* ctp,
static symref_t codeview_fetch_symref(struct codeview_type_parse* ctp, unsigned typeno) { - symref_t symref; - - if (!cv_hack_ptr_to_symref(ctp->module->format_info[DFI_OLD_PDB]->u.old_pdb_info->pdb_files[0].pdb_reader, typeno, &symref)) - { - symref = symt_ptr_to_symref(codeview_fetch_type(ctp, typeno)); - } - - return symref; + return symt_ptr_to_symref(codeview_fetch_type(ctp, typeno)); }
static symref_t codeview_get_symref(struct module *module, unsigned typeno) { - symref_t symref; - - if (!cv_hack_ptr_to_symref(module->format_info[DFI_OLD_PDB]->u.old_pdb_info->pdb_files[0].pdb_reader, typeno, &symref)) - { - symref = symt_ptr_to_symref(codeview_get_type(typeno, TRUE)); - } - return symref; + return symt_ptr_to_symref(codeview_get_type(typeno, TRUE)); }
static UINT32 codeview_compute_hash(const char* ptr, unsigned len) @@ -1548,7 +1521,6 @@ static BOOL codeview_parse_type_table(struct codeview_type_parse* ctp) unsigned int i, curr_type; const union codeview_type* type;
- cv_current_module->pdb = ctp->module->format_info[DFI_OLD_PDB]->u.old_pdb_info->pdb_files[0].pdb_reader; cv_current_module->first_type_index = ctp->header.first_index; cv_current_module->last_type_index = ctp->header.last_index; cv_current_module->defined_types = calloc(ctp->header.last_index - ctp->header.first_index, @@ -2329,7 +2301,6 @@ static struct symt_compiland* codeview_new_compiland(const struct msc_debug_info }
static BOOL codeview_snarf(const struct msc_debug_info* msc_dbg, - unsigned stream_id, const BYTE* root, unsigned offset, unsigned size, const struct cv_module_snarf* cvmod, const char* objname) @@ -2720,15 +2691,7 @@ static BOOL codeview_snarf(const struct msc_debug_info* msc_dbg, */ if (!sym->local_v3.varflags.enreg_global && !sym->local_v3.varflags.enreg_static) { - if (stream_id) - { - loc.kind = loc_user + 1 /* loc_cv_defrange for new PDB reader (see pdb.c) */; - loc.reg = stream_id; - loc.offset = (const BYTE*)sym - root; - length += codeview_defrange_length(sym); - } - else - length += codeview_transform_defrange(msc_dbg, curr_func, sym, &loc); + length += codeview_transform_defrange(msc_dbg, curr_func, sym, &loc); symt_add_func_local(msc_dbg->module, curr_func, sym->local_v3.varflags.is_param ? DataIsParam : DataIsLocal, &loc, block, @@ -3209,7 +3172,7 @@ static void pdb_free(void* buffer) HeapFree(GetProcessHeap(), 0, buffer); }
-static void pdb_free_file(struct pdb_file_info* pdb_file, BOOL unmap) +static void pdb_free_file(struct pdb_file_info* pdb_file) { switch (pdb_file->kind) { @@ -3224,11 +3187,8 @@ static void pdb_free_file(struct pdb_file_info* pdb_file, BOOL unmap) } HeapFree(GetProcessHeap(), 0, pdb_file->stream_dict); pdb_file->stream_dict = NULL; - if (unmap) - { - UnmapViewOfFile(pdb_file->image); - pdb_file->image = NULL; - } + UnmapViewOfFile(pdb_file->image); + pdb_file->image = NULL; }
static struct pdb_stream_name* pdb_load_stream_name_table(const char* str, unsigned cb) @@ -3308,11 +3268,9 @@ static void pdb_module_remove(struct module_format* modfmt)
for (i = 0; i < modfmt->u.old_pdb_info->used_subfiles; i++) { - pdb_free_file(&modfmt->u.old_pdb_info->pdb_files[i], TRUE); + pdb_free_file(&modfmt->u.old_pdb_info->pdb_files[i]); if (modfmt->u.old_pdb_info->pdb_files[i].image) UnmapViewOfFile(modfmt->u.old_pdb_info->pdb_files[i].image); - if (modfmt->u.old_pdb_info->pdb_files[i].pdb_reader) - pdb_reader_dispose(modfmt->u.old_pdb_info->pdb_files[i].pdb_reader); } HeapFree(GetProcessHeap(), 0, modfmt); } @@ -3839,22 +3797,11 @@ static BOOL pdb_process_internal(const struct process *pcs, return FALSE; }
+ CloseHandle(hFile); CloseHandle(hMap); /* old pdb reader */ if (!pdb_init(pdb_file, image)) { - CloseHandle(hFile); - UnmapViewOfFile(image); - return FALSE; - } - if (getenv("WINE_DBGHELP_OLD_PDB")) /* keep using old pdb reader */ - { - pdb_file->pdb_reader = NULL; - CloseHandle(hFile); - } - else if (!(pdb_file->pdb_reader = pdb_hack_reader_init(msc_dbg->module, hFile, msc_dbg->sectp, msc_dbg->nsect))) - { - CloseHandle(hFile); UnmapViewOfFile(image); return FALSE; } @@ -3899,10 +3846,7 @@ static BOOL pdb_process_internal(const struct process *pcs,
pdb_process_symbol_imports(pcs, msc_dbg, &symbols, symbols_image, image, pdb_module_info, module_index); - if (!pdb_file->pdb_reader) - { - pdb_process_types(msc_dbg, pdb_file); - } + pdb_process_types(msc_dbg, pdb_file);
ipi_image = pdb_read_stream(pdb_file, 4); ipi_ok = pdb_init_type_parse(msc_dbg, pdb_file, &ipi_ctp, ipi_image); @@ -3911,7 +3855,7 @@ static BOOL pdb_process_internal(const struct process *pcs, * streams' loading can succeed them. */ globalimage = pdb_read_stream(pdb_file, symbols.gsym_stream); - if (globalimage && !pdb_file->pdb_reader) + if (globalimage) { const BYTE* data; unsigned global_size = pdb_get_stream_size(pdb_file, symbols.gsym_stream); @@ -3929,7 +3873,6 @@ static BOOL pdb_process_internal(const struct process *pcs,
/* Read per-module symbols' tables */ file = symbols_image + header_size; - if (pdb_file->pdb_reader) file += symbols.module_size; /* skip it */ while (file - symbols_image < header_size + symbols.module_size) { PDB_SYMBOL_FILE_EX sfile; @@ -3945,22 +3888,19 @@ static BOOL pdb_process_internal(const struct process *pcs, { struct cv_module_snarf cvmod = {ipi_ok ? &ipi_ctp : NULL, (const void*)(modimage + sfile.symbol_size), sfile.lineno2_size, files_image}; - codeview_snarf(msc_dbg, pdb_file->pdb_reader ? sfile.stream : 0, modimage, sizeof(DWORD), sfile.symbol_size, + codeview_snarf(msc_dbg, modimage, sizeof(DWORD), sfile.symbol_size, &cvmod, file_name);
if (sfile.lineno_size && sfile.lineno2_size) FIXME("Both line info present... preferring second\n"); if (sfile.lineno2_size) { - if (pdb_file->pdb_reader || - ((SymGetOptions() & SYMOPT_LOAD_LINES) && codeview_snarf_linetab2(msc_dbg, &cvmod))) + if (((SymGetOptions() & SYMOPT_LOAD_LINES) && codeview_snarf_linetab2(msc_dbg, &cvmod))) *has_linenumber_info = TRUE; } else if (sfile.lineno_size) { - if (pdb_file->pdb_reader) - FIXME("New PDB reader doesn't support old line format\n"); - else if ((SymGetOptions() & SYMOPT_LOAD_LINES) && + if ((SymGetOptions() & SYMOPT_LOAD_LINES) && codeview_snarf_linetab(msc_dbg, modimage + sfile.symbol_size, sfile.lineno_size, @@ -3974,7 +3914,7 @@ static BOOL pdb_process_internal(const struct process *pcs, file = (BYTE*)((DWORD_PTR)(file_name + strlen(file_name) + 1 + 3) & ~3); } /* Load the global variables and constants (if not yet loaded) and public information */ - if (globalimage && !pdb_file->pdb_reader) + if (globalimage) { const BYTE* data; unsigned global_size = pdb_get_stream_size(pdb_file, symbols.gsym_stream); @@ -4008,7 +3948,7 @@ static BOOL pdb_process_internal(const struct process *pcs, pdb_free(symbols_image); pdb_free(files_image);
- pdb_free_file(pdb_file, pdb_file->pdb_reader != NULL); + pdb_free_file(pdb_file);
return TRUE; } @@ -4025,33 +3965,52 @@ static const struct module_format_vtable old_pdb_module_format_vtable = pdb_location_compute, };
+static BOOL old_pdb_process_file(const struct process *pcs, + const struct msc_debug_info *msc_dbg, + const WCHAR *filename, BOOL *has_linenumber_info) +{ + struct module_format* modfmt; + struct old_pdb_module_info* pdb_module_info; + BOOL ret; + + if (!(modfmt = HeapAlloc(GetProcessHeap(), 0, + sizeof(struct module_format) + sizeof(struct old_pdb_module_info)))) + return FALSE; + + pdb_module_info = (void*)(modfmt + 1); + msc_dbg->module->format_info[DFI_OLD_PDB] = modfmt; + modfmt->module = msc_dbg->module; + modfmt->vtable = &old_pdb_module_format_vtable; + modfmt->u.old_pdb_info = pdb_module_info; + + memset(cv_zmodules, 0, sizeof(cv_zmodules)); + codeview_init_basic_types(msc_dbg->module); + ret = pdb_process_internal(pcs, msc_dbg, filename, + msc_dbg->module->format_info[DFI_OLD_PDB]->u.old_pdb_info, -1, has_linenumber_info); + codeview_clear_type_table(); + if (!ret) + { + msc_dbg->module->format_info[DFI_OLD_PDB] = NULL; + HeapFree(GetProcessHeap(), 0, modfmt); + } + return ret; +} + static BOOL pdb_process_file(const struct process *pcs, const struct msc_debug_info *msc_dbg, const char *filename, const GUID *guid, DWORD timestamp, DWORD age) { - struct module_format* modfmt; - struct old_pdb_module_info* pdb_module_info; SYMSRV_INDEX_INFOW info; - BOOL unmatched; + BOOL unmatched, has_linenumber_info, ret;
if (!msc_dbg->module->dont_load_symbols && - path_find_symbol_file(pcs, msc_dbg->module, filename, TRUE, guid, timestamp, age, &info, &unmatched) && - (modfmt = HeapAlloc(GetProcessHeap(), 0, - sizeof(struct module_format) + sizeof(struct old_pdb_module_info)))) + path_find_symbol_file(pcs, msc_dbg->module, filename, TRUE, guid, timestamp, age, &info, &unmatched)) { - BOOL ret, has_linenumber_info; - - pdb_module_info = (void*)(modfmt + 1); - msc_dbg->module->format_info[DFI_OLD_PDB] = modfmt; - modfmt->module = msc_dbg->module; - modfmt->vtable = &old_pdb_module_format_vtable; - modfmt->u.old_pdb_info = pdb_module_info; + if (getenv("WINE_DBGHELP_OLD_PDB")) /* keep using old pdb reader */ + ret = old_pdb_process_file(pcs, msc_dbg, info.pdbfile, &has_linenumber_info); + else + ret = pdb_init_modfmt(pcs, msc_dbg, info.pdbfile, &has_linenumber_info);
- memset(cv_zmodules, 0, sizeof(cv_zmodules)); - codeview_init_basic_types(msc_dbg->module); - ret = pdb_process_internal(pcs, msc_dbg, info.pdbfile, - msc_dbg->module->format_info[DFI_OLD_PDB]->u.old_pdb_info, -1, &has_linenumber_info); - codeview_clear_type_table(); if (ret) { msc_dbg->module->module.SymType = SymPdb; @@ -4070,8 +4029,6 @@ static BOOL pdb_process_file(const struct process *pcs,
return TRUE; } - msc_dbg->module->format_info[DFI_OLD_PDB] = NULL; - HeapFree(GetProcessHeap(), 0, modfmt); } msc_dbg->module->module.SymType = SymNone; if (guid) @@ -4151,7 +4108,7 @@ static BOOL codeview_process_info(const struct process *pcs,
if (ent->SubSection == sstAlignSym) { - codeview_snarf(msc_dbg, 0, msc_dbg->root + ent->lfo, sizeof(DWORD), ent->cb, NULL, NULL); + codeview_snarf(msc_dbg, msc_dbg->root + ent->lfo, sizeof(DWORD), ent->cb, NULL, NULL);
if (SymGetOptions() & SYMOPT_LOAD_LINES) { diff --git a/dlls/dbghelp/pdb.c b/dlls/dbghelp/pdb.c index 911d36a344a..8dab44a72ee 100644 --- a/dlls/dbghelp/pdb.c +++ b/dlls/dbghelp/pdb.c @@ -510,7 +510,7 @@ static enum pdb_result pdb_reader_init(struct pdb_reader *pdb, struct module *mo pdb->streams[i].name = NULL; } /* hack (must be set before loading debug info so it can be used therein) */ - pdb->module->ops_symref_modfmt = module->format_info[DFI_OLD_PDB]; + pdb->module->ops_symref_modfmt = module->format_info[DFI_PDB]; pdb_reader_init_DBI(pdb);
return R_PDB_SUCCESS; @@ -522,7 +522,7 @@ failure: return result; }
-void pdb_reader_dispose(struct pdb_reader *pdb) +static void pdb_reader_dispose(struct pdb_reader *pdb) { CloseHandle(pdb->file); /* note: pdb is allocated inside its pool, so this must be last line */ @@ -1051,6 +1051,16 @@ static enum pdb_result pdb_reader_get_line_from_address_internal(struct pdb_read return R_PDB_NOT_FOUND; }
+struct pdb_module_info +{ + struct pdb_reader pdb_reader; +}; + +static inline struct pdb_reader *pdb_get_current_reader(const struct module_format *modfmt) +{ + return &modfmt->u.pdb_info->pdb_reader; +} + static enum method_result pdb_method_result(enum pdb_result result) { switch (result) @@ -1068,7 +1078,7 @@ static enum method_result pdb_method_get_line_from_address(struct module_format struct pdb_reader *pdb; pdbsize_t compiland_offset;
- if (!pdb_hack_get_main_info(modfmt, &pdb, NULL)) return MR_FAILURE; + pdb = pdb_get_current_reader(modfmt); result = pdb_reader_get_line_from_address_internal(pdb, address, line_info, &compiland_offset); return pdb_method_result(result); } @@ -1142,7 +1152,7 @@ static enum method_result pdb_method_advance_line_info(struct module_format *mod { struct pdb_reader *pdb;
- if (!pdb_hack_get_main_info(modfmt, &pdb, NULL)) return MR_FAILURE; + pdb = pdb_get_current_reader(modfmt); return pdb_reader_advance_line_info(pdb, line_info, forward) == R_PDB_SUCCESS ? MR_SUCCESS : MR_FAILURE; }
@@ -1261,8 +1271,7 @@ static enum method_result pdb_method_enumerate_lines(struct module_format *modfm { struct pdb_reader *pdb;
- if (!pdb_hack_get_main_info(modfmt, &pdb, NULL)) return MR_FAILURE; - + pdb = pdb_get_current_reader(modfmt); return pdb_method_result(pdb_method_enumerate_lines_internal(pdb, compiland_regex, source_file_regex, cb, user)); }
@@ -1308,7 +1317,7 @@ static enum method_result pdb_method_enumerate_sources(struct module_format *mod { struct pdb_reader *pdb;
- if (!pdb_hack_get_main_info(modfmt, &pdb, NULL)) return MR_FAILURE; + pdb = pdb_get_current_reader(modfmt);
/* Note: in PDB, each compiland lists its used files, which are all in global string table, * but there's no global source files table AFAICT. @@ -1976,7 +1985,7 @@ static void pdb_method_location_compute(const struct module_format* modfmt, loc->kind = loc_error; loc->reg = loc_err_internal;
- if (!pdb_hack_get_main_info((struct module_format *)modfmt, &pdb, NULL)) return; + pdb = pdb_get_current_reader(modfmt); if (in_loc.kind != loc_cv_defrange || pdb_reader_walker_init(pdb, in_loc.reg, &walker)) return; walker.offset = in_loc.offset;
@@ -2583,7 +2592,7 @@ static enum method_result pdb_method_find_type(struct module_format *modfmt, con struct pdb_type_details *type_details; pdbsize_t stream_offset;
- if (!pdb_hack_get_main_info(modfmt, &pdb, NULL)) return MR_FAILURE; + pdb = pdb_get_current_reader(modfmt); if ((result = pdb_reader_init_TPI(pdb))) return pdb_method_result(result); /* search in TPI hash table */ if ((result = pdb_reader_read_codeview_type_by_name(pdb, name, &walker, &cv_type, &cv_typeid)) == R_PDB_SUCCESS) @@ -2707,7 +2716,7 @@ static enum method_result pdb_method_enumerate_types(struct module_format *modfm VARIANT v; BOOL ret;
- if (!pdb_hack_get_main_info(modfmt, &pdb, NULL)) return MR_FAILURE; + pdb = pdb_get_current_reader(modfmt); if ((result = pdb_reader_init_TPI(pdb))) return pdb_method_result(result); walker = pdb->tpi_types_walker; /* Note: walking the types through the hash table may not be the most efficient */ @@ -3599,7 +3608,7 @@ static enum method_result pdb_method_request_symref_t(struct module_format *modf { struct pdb_reader *pdb;
- if (!pdb_hack_get_main_info(modfmt, &pdb, NULL)) return MR_FAILURE; + pdb = pdb_get_current_reader(modfmt); if (pdb_reader_init_TPI(pdb)) return MR_FAILURE; return pdb_reader_request_symref_t(pdb, symref, req, data); } @@ -4048,8 +4057,7 @@ static enum method_result pdb_method_get_line_from_inlined_address(struct module { struct pdb_reader *pdb;
- if (!pdb_hack_get_main_info(modfmt, &pdb, NULL)) return MR_FAILURE; - + pdb = pdb_get_current_reader(modfmt); return pdb_method_result(pdb_method_get_line_from_inlined_address_internal(pdb, inlined, address, line_info)); }
@@ -4663,7 +4671,7 @@ static enum method_result pdb_method_lookup_symbol_by_address(struct module_form struct pdb_reader *pdb; unsigned segment, offset;
- if (!pdb_hack_get_main_info(modfmt, &pdb, NULL)) return MR_FAILURE; + pdb = pdb_get_current_reader(modfmt); if ((result = pdb_reader_get_segment_offset_from_address(pdb, address, &segment, &offset))) return MR_FAILURE; return pdb_method_result(pdb_reader_lookup_top_symbol_by_segment_offset(pdb, segment, offset, symref)); } @@ -4718,7 +4726,7 @@ static enum method_result pdb_method_lookup_symbol_by_name(struct module_format unsigned segment; unsigned offset;
- if (!pdb_hack_get_main_info(modfmt, &pdb, NULL)) return MR_FAILURE; + pdb = pdb_get_current_reader(modfmt);
if ((result = pdb_reader_read_DBI_codeview_symbol_by_name(pdb, name, &globals_offset, &cv_symbol))) return pdb_method_result(result); @@ -4757,7 +4765,7 @@ static enum method_result pdb_method_enumerate_symbols(struct module_format *mod unsigned offset; char *symbol_name;
- if (!pdb_hack_get_main_info(modfmt, &pdb, NULL)) return MR_FAILURE; + pdb = pdb_get_current_reader(modfmt);
/* FIXME could be optimized if match doesn't contain wild cards */ /* this is currently ugly, but basically we just ensure that all the compilands which contain matching symbols @@ -4814,9 +4822,15 @@ static enum method_result pdb_method_enumerate_symbols(struct module_format *mod return MR_FAILURE; }
+static void pdb_module_remove(struct module_format* modfmt) +{ + pdb_reader_dispose(&modfmt->u.pdb_info->pdb_reader); + HeapFree(GetProcessHeap(), 0, modfmt); +} + static struct module_format_vtable pdb_module_format_vtable = { - NULL,/*pdb_module_remove*/ + pdb_module_remove, pdb_method_request_symref_t, pdb_method_lookup_symbol_by_address, pdb_method_lookup_symbol_by_name, @@ -4831,24 +4845,44 @@ static struct module_format_vtable pdb_module_format_vtable = pdb_method_enumerate_sources, };
-struct pdb_reader *pdb_hack_reader_init(struct module *module, HANDLE file, const IMAGE_SECTION_HEADER *sections, unsigned num_sections) +BOOL pdb_init_modfmt(const struct process *pcs, + const struct msc_debug_info *msc_dbg, + const WCHAR *filename, BOOL *has_linenumber_info) { - struct pdb_reader *pdb = pool_alloc(&module->pool, sizeof(*pdb) + num_sections * sizeof(*sections)); - if (pdb) + struct module_format *modfmt; + struct pdb_module_info *pdb_module_info; + IMAGE_SECTION_HEADER *new_sections; + HANDLE file; + + if (!(modfmt = HeapAlloc(GetProcessHeap(), 0, + sizeof(struct module_format) + sizeof(struct pdb_module_info) + msc_dbg->nsect * sizeof(msc_dbg->sectp[0])))) + return FALSE; + + if ((file = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE) { - IMAGE_SECTION_HEADER *new_sections = (void*)(pdb + 1); - memcpy(new_sections, sections, num_sections * sizeof(*sections)); - if (pdb_reader_init(pdb, module, file, new_sections, num_sections) == R_PDB_SUCCESS) - { - /* hack (copy old pdb methods until they are moved here) */ - pdb_module_format_vtable.remove = module->format_info[DFI_OLD_PDB]->vtable->remove; + HeapFree(GetProcessHeap(), 0, modfmt); + return FALSE; + }
- module->format_info[DFI_OLD_PDB]->vtable = &pdb_module_format_vtable; - return pdb; - } + pdb_module_info = (void*)(modfmt + 1); + msc_dbg->module->format_info[DFI_PDB] = modfmt; + modfmt->module = msc_dbg->module; + modfmt->vtable = &pdb_module_format_vtable; + modfmt->u.pdb_info = pdb_module_info; + + new_sections = (void*)(pdb_module_info + 1); + memcpy(new_sections, msc_dbg->sectp, msc_dbg->nsect * sizeof(*new_sections)); + if (pdb_reader_init(&pdb_module_info->pdb_reader, msc_dbg->module, file, new_sections, msc_dbg->nsect) == R_PDB_SUCCESS) + { + /* FIXME */ + *has_linenumber_info = TRUE; + return TRUE; } - pool_free(&module->pool, pdb); - return NULL; + msc_dbg->module->format_info[DFI_PDB] = NULL; + HeapFree(GetProcessHeap(), 0, modfmt); + CloseHandle(file); + return FALSE; }
/*======================================================================== @@ -5179,9 +5213,8 @@ BOOL pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, union ctx *con BOOL ret = FALSE;
if (!module_init_pair(&pair, csw->hProcess, ip)) return FALSE; - if (!pair.effective->format_info[DFI_OLD_PDB]) return FALSE; - if (!pdb_hack_get_main_info(pair.effective->format_info[DFI_OLD_PDB], &pdb, NULL)) return FALSE; - if (!pdb) return FALSE; + if (!pair.effective->format_info[DFI_PDB]) return FALSE; + pdb = pdb_get_current_reader(pair.effective->format_info[DFI_PDB]);
TRACE("searching %Ix => %Ix\n", ip, ip - (DWORD_PTR)pair.effective->module.BaseOfImage); ip -= (DWORD_PTR)pair.effective->module.BaseOfImage;