Use public_vx iststead of data_vx for public symbols.
Signed-off-by: Andreas Maier staubim@quantentunnel.de --- dlls/dbghelp/msc.c | 18 +++++++++--------- include/wine/mscvpdb.h | 10 ++++++++++ 2 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c index 493c440ea7..ae51884abc 100644 --- a/dlls/dbghelp/msc.c +++ b/dlls/dbghelp/msc.c @@ -2067,29 +2067,29 @@ static BOOL codeview_snarf_public(const struct msc_debug_info* msc_dbg, const BY
switch (sym->generic.id) { - case S_PUB_V1: /* FIXME is this really a 'data_v1' structure ?? */ + case S_PUB_V1: if (!(dbghelp_options & SYMOPT_NO_PUBLICS)) { symt_new_public(msc_dbg->module, compiland, - terminate_string(&sym->data_v1.p_name), - codeview_get_address(msc_dbg, sym->data_v1.segment, sym->data_v1.offset), 1); + terminate_string(&sym->public_v1.p_name), + codeview_get_address(msc_dbg, sym->public_v1.segment, sym->public_v1.offset), 1); } break; - case S_PUB_V2: /* FIXME is this really a 'data_v2' structure ?? */ + case S_PUB_V2: if (!(dbghelp_options & SYMOPT_NO_PUBLICS)) { symt_new_public(msc_dbg->module, compiland, - terminate_string(&sym->data_v2.p_name), - codeview_get_address(msc_dbg, sym->data_v2.segment, sym->data_v2.offset), 1); + terminate_string(&sym->public_v2.p_name), + codeview_get_address(msc_dbg, sym->public_v2.segment, sym->public_v2.offset), 1); } - break; + break;
case S_PUB_V3: if (!(dbghelp_options & SYMOPT_NO_PUBLICS)) { symt_new_public(msc_dbg->module, compiland, - sym->data_v3.name, - codeview_get_address(msc_dbg, sym->data_v3.segment, sym->data_v3.offset), 1); + sym->public_v3.name, + codeview_get_address(msc_dbg, sym->public_v3.segment, sym->public_v3.offset), 1); } break; case S_PUB_FUNC1_V3: diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h index 2f0b47998f..7a4a69beb9 100644 --- a/include/wine/mscvpdb.h +++ b/include/wine/mscvpdb.h @@ -1352,6 +1352,16 @@ union codeview_symbol { short int len; short int id; + unsigned int offset; + unsigned short segment; + unsigned short symtype; + struct p_string p_name; + } public_v1; + + struct + { + short int len; + short int id; unsigned int symtype; unsigned int offset; unsigned short segment;
Signed-off-by: Andreas Maier staubim@quantentunnel.de --- include/dbghelp.h | 7 +++++++ include/wine/mscvpdb.h | 7 +++++++ 2 files changed, 14 insertions(+)
diff --git a/include/dbghelp.h b/include/dbghelp.h index e6015ff885..6e8d375126 100644 --- a/include/dbghelp.h +++ b/include/dbghelp.h @@ -951,6 +951,13 @@ BOOL WINAPI SymUnloadModule64(HANDLE, DWORD64); #define SYMFLAG_THUNK 0x00002000 #define SYMFLAG_TLSREL 0x00004000 #define SYMFLAG_SLOT 0x00008000 +#define SYMFLAG_ILREL 0x00010000 +#define SYMFLAG_METADATA 0x00020000 +#define SYMFLAG_CLR_TOKEN 0x00040000 +#define SYMFLAG_NULL 0x00080000 +#define SYMFLAG_FUNC_NO_RETURN 0x00100000 +#define SYMFLAG_SYNTHETIC_ZEROBASE 0x00200000 +#define SYMFLAG_PUBLIC_CODE 0x00400000
#define MAX_SYM_NAME 2000
diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h index 7a4a69beb9..a44331bb5c 100644 --- a/include/wine/mscvpdb.h +++ b/include/wine/mscvpdb.h @@ -1227,6 +1227,13 @@ union codeview_fieldtype #define LF_COMPLEX128 0x800f #define LF_VARSTRING 0x8010
+/* symtype e.g. for public_vx.symtype */ +#define SYMTYPE_NONE 0x0000 +#define SYMTYPE_CODE 0x0001 +#define SYMTYPE_FUNCTION 0x0002 +#define SYMTYPE_MANAGED 0x0004 +#define SYMTYPE_MSIL 0x0008 + /* ======================================== * * Symbol information * ======================================== */
* symtype: set to SymPdb not SymCv (may be for old pdb-files pre VS 6.0) * flags: return SYMFLAG_PUBLIC_CODE for SymTagPublicSymbol if its a function. * flags: do not return SYMFLAG_FUNCTION for SymTagFuncion.
Signed-off-by: Andreas Maier staubim@quantentunnel.de --- dlls/dbghelp/dbghelp_private.h | 5 ++++- dlls/dbghelp/elf_module.c | 1 + dlls/dbghelp/msc.c | 5 ++++- dlls/dbghelp/pe_module.c | 11 ++++++----- dlls/dbghelp/symbol.c | 13 ++++++++++--- 5 files changed, 25 insertions(+), 10 deletions(-)
diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index 7b872feb44..ae8bc50213 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -227,6 +227,7 @@ struct symt_public struct symt symt; struct hash_table_elt hash_elt; struct symt* container; /* compiland */ + BOOL is_function; unsigned long address; unsigned long size; }; @@ -716,7 +717,9 @@ extern struct symt_public* symt_new_public(struct module* module, struct symt_compiland* parent, const char* typename, - unsigned long address, unsigned size) DECLSPEC_HIDDEN; + BOOL is_function, + unsigned long address, + unsigned size) DECLSPEC_HIDDEN; extern struct symt_data* symt_new_global_variable(struct module* module, struct symt_compiland* parent, diff --git a/dlls/dbghelp/elf_module.c b/dlls/dbghelp/elf_module.c index 6b8d47a1e4..96b16fd5c0 100644 --- a/dlls/dbghelp/elf_module.c +++ b/dlls/dbghelp/elf_module.c @@ -927,6 +927,7 @@ static int elf_new_public_symbols(struct module* module, const struct hash_table while ((ste = hash_table_iter_up(&hti))) { symt_new_public(module, ste->compiland, ste->ht_elt.name, + FALSE, module->reloc_delta + ste->sym.st_value, ste->sym.st_size); } diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c index ae51884abc..adb66d6880 100644 --- a/dlls/dbghelp/msc.c +++ b/dlls/dbghelp/msc.c @@ -2072,6 +2072,7 @@ static BOOL codeview_snarf_public(const struct msc_debug_info* msc_dbg, const BY { symt_new_public(msc_dbg->module, compiland, terminate_string(&sym->public_v1.p_name), + sym->public_v1.symtype == SYMTYPE_FUNCTION, codeview_get_address(msc_dbg, sym->public_v1.segment, sym->public_v1.offset), 1); } break; @@ -2080,6 +2081,7 @@ static BOOL codeview_snarf_public(const struct msc_debug_info* msc_dbg, const BY { symt_new_public(msc_dbg->module, compiland, terminate_string(&sym->public_v2.p_name), + sym->public_v2.symtype == SYMTYPE_FUNCTION, codeview_get_address(msc_dbg, sym->public_v2.segment, sym->public_v2.offset), 1); } break; @@ -2089,6 +2091,7 @@ static BOOL codeview_snarf_public(const struct msc_debug_info* msc_dbg, const BY { symt_new_public(msc_dbg->module, compiland, sym->public_v3.name, + sym->public_v3.symtype == SYMTYPE_FUNCTION, codeview_get_address(msc_dbg, sym->public_v3.segment, sym->public_v3.offset), 1); } break; @@ -2885,7 +2888,7 @@ static BOOL pdb_process_file(const struct process* pcs, if (ret) { struct pdb_module_info* pdb_info = msc_dbg->module->format_info[DFI_PDB]->u.pdb_info; - msc_dbg->module->module.SymType = SymCv; + msc_dbg->module->module.SymType = SymPdb; if (pdb_info->pdb_files[0].kind == PDB_JG) msc_dbg->module->module.PdbSig = pdb_info->pdb_files[0].u.jg.timestamp; else diff --git a/dlls/dbghelp/pe_module.c b/dlls/dbghelp/pe_module.c index 025cd60b13..c077c07147 100644 --- a/dlls/dbghelp/pe_module.c +++ b/dlls/dbghelp/pe_module.c @@ -442,7 +442,7 @@ static BOOL pe_load_coff_symbol_table(struct module* module) source_new(module, NULL, lastfilename));
if (!(dbghelp_options & SYMOPT_NO_PUBLICS)) - symt_new_public(module, compiland, name, + symt_new_public(module, compiland, name, FALSE, module->module.BaseOfImage + sect[isym->SectionNumber - 1].VirtualAddress + isym->Value, 1); @@ -635,11 +635,11 @@ static BOOL pe_load_export_debug_info(const struct process* pcs, struct module* #if 0 /* Add start of DLL (better use the (yet unimplemented) Exe SymTag for this) */ /* FIXME: module.ModuleName isn't correctly set yet if it's passed in SymLoadModule */ - symt_new_public(module, NULL, module->module.ModuleName, base, 1); + symt_new_public(module, NULL, module->module.ModuleName, FALSE, base, 1); #endif
/* Add entry point */ - symt_new_public(module, NULL, "EntryPoint", + symt_new_public(module, NULL, "EntryPoint", FALSE, base + nth->OptionalHeader.AddressOfEntryPoint, 1); #if 0 /* FIXME: we'd better store addresses linked to sections rather than @@ -650,7 +650,7 @@ static BOOL pe_load_export_debug_info(const struct process* pcs, struct module* ((char*)&nth->OptionalHeader + nth->FileHeader.SizeOfOptionalHeader); for (i = 0; i < nth->FileHeader.NumberOfSections; i++, section++) { - symt_new_public(module, NULL, section->Name, + symt_new_public(module, NULL, section->Name, FALSE, RtlImageRvaToVa(nth, mapping, section->VirtualAddress, NULL), 1); } #endif @@ -676,6 +676,7 @@ static BOOL pe_load_export_debug_info(const struct process* pcs, struct module* if (!names[i]) continue; symt_new_public(module, NULL, RtlImageRvaToVa(nth, mapping, names[i], NULL), + FALSE, base + functions[ordinals[i]], 1); }
@@ -687,7 +688,7 @@ static BOOL pe_load_export_debug_info(const struct process* pcs, struct module* if ((ordinals[j] == i) && names[j]) break; if (j < exports->NumberOfNames) continue; snprintf(buffer, sizeof(buffer), "%d", i + exports->Base); - symt_new_public(module, NULL, buffer, base + (DWORD)functions[i], 1); + symt_new_public(module, NULL, buffer, FALSE, base + (DWORD)functions[i], 1); } } } diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c index de871ecdcd..05aea05875 100644 --- a/dlls/dbghelp/symbol.c +++ b/dlls/dbghelp/symbol.c @@ -202,6 +202,7 @@ struct symt_compiland* symt_new_compiland(struct module* module, struct symt_public* symt_new_public(struct module* module, struct symt_compiland* compiland, const char* name, + BOOL is_function, unsigned long address, unsigned size) { struct symt_public* sym; @@ -217,6 +218,7 @@ struct symt_public* symt_new_public(struct module* module, sym->symt.tag = SymTagPublicSymbol; sym->hash_elt.name = pool_strdup(&module->pool, name); sym->container = compiland ? &compiland->symt : NULL; + sym->is_function = is_function; sym->address = address; sym->size = size; symt_add_module_ht(module, (struct symt_ht*)sym); @@ -673,11 +675,16 @@ static void symt_fill_sym_info(struct module_pair* pair, } break; case SymTagPublicSymbol: - sym_info->Flags |= SYMFLAG_EXPORT; - symt_get_address(sym, &sym_info->Address); + { + const struct symt_public* pub = (const struct symt_public*)sym; + if (pub->is_function) + sym_info->Flags |= SYMFLAG_PUBLIC_CODE; + else + sym_info->Flags |= SYMFLAG_EXPORT; + symt_get_address(sym, &sym_info->Address); + } break; case SymTagFunction: - sym_info->Flags |= SYMFLAG_FUNCTION; symt_get_address(sym, &sym_info->Address); break; case SymTagThunk:
Correct last error in module_find_by_addr.
Signed-off-by: Andreas Maier staubim@quantentunnel.de --- dlls/dbghelp/module.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c index 98fc10c029..cfbb58683f 100644 --- a/dlls/dbghelp/module.c +++ b/dlls/dbghelp/module.c @@ -436,7 +436,7 @@ struct module* module_find_by_addr(const struct process* pcs, DWORD64 addr, return module; } } - SetLastError(ERROR_INVALID_ADDRESS); + SetLastError(ERROR_MOD_NOT_FOUND); return module; }
* There could be more then 2 symbols at the same addr. Adjust function to handle that case correct. * Correct displacement-value. If addr is between module base and first symbol return -1.
Signed-off-by: Andreas Maier staubim@quantentunnel.de --- dlls/dbghelp/symbol.c | 54 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 19 deletions(-)
diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c index 05aea05875..c9585c5e71 100644 --- a/dlls/dbghelp/symbol.c +++ b/dlls/dbghelp/symbol.c @@ -850,6 +850,33 @@ static void symt_get_length(struct module* module, const struct symt* symt, ULON *size = 0x1000; /* arbitrary value */ }
+/* neede by symt_find_nearest */ +int symt_get_best_at(struct module* module, int idx_sorttab) +{ + ULONG64 ref_addr; + int idx_sorttab_orig = idx_sorttab; + if (module->addr_sorttab[idx_sorttab]->symt.tag == SymTagPublicSymbol) + { + symt_get_address(&module->addr_sorttab[idx_sorttab]->symt, &ref_addr); + while (idx_sorttab > 0 && + module->addr_sorttab[idx_sorttab]->symt.tag == SymTagPublicSymbol && + !cmp_sorttab_addr(module, idx_sorttab - 1, ref_addr)) + idx_sorttab--; + if (module->addr_sorttab[idx_sorttab]->symt.tag == SymTagPublicSymbol) + { + idx_sorttab = idx_sorttab_orig; + while (idx_sorttab < module->num_sorttab - 1 && + module->addr_sorttab[idx_sorttab]->symt.tag == SymTagPublicSymbol && + !cmp_sorttab_addr(module, idx_sorttab + 1, ref_addr)) + idx_sorttab++; + } + /* if no better symbol fond restore original */ + if (module->addr_sorttab[idx_sorttab]->symt.tag == SymTagPublicSymbol) + idx_sorttab = idx_sorttab_orig; + } + return idx_sorttab; +} + /* assume addr is in module */ struct symt_ht* symt_find_nearest(struct module* module, DWORD_PTR addr) { @@ -868,7 +895,12 @@ struct symt_ht* symt_find_nearest(struct module* module, DWORD_PTR addr) high = module->num_sorttab;
symt_get_address(&module->addr_sorttab[0]->symt, &ref_addr); - if (addr < ref_addr) return NULL; + if (addr <= ref_addr) + { + low = symt_get_best_at(module, 0); + return module->addr_sorttab[low]; + } + if (high) { symt_get_address(&module->addr_sorttab[high - 1]->symt, &ref_addr); @@ -891,23 +923,7 @@ struct symt_ht* symt_find_nearest(struct module* module, DWORD_PTR addr) /* If found symbol is a public symbol, check if there are any other entries that * might also have the same address, but would get better information */ - if (module->addr_sorttab[low]->symt.tag == SymTagPublicSymbol) - { - symt_get_address(&module->addr_sorttab[low]->symt, &ref_addr); - if (low > 0 && - module->addr_sorttab[low - 1]->symt.tag != SymTagPublicSymbol && - !cmp_sorttab_addr(module, low - 1, ref_addr)) - low--; - else if (low < module->num_sorttab - 1 && - module->addr_sorttab[low + 1]->symt.tag != SymTagPublicSymbol && - !cmp_sorttab_addr(module, low + 1, ref_addr)) - low++; - } - /* finally check that we fit into the found symbol */ - symt_get_address(&module->addr_sorttab[low]->symt, &ref_addr); - if (addr < ref_addr) return NULL; - symt_get_length(module, &module->addr_sorttab[low]->symt, &ref_size); - if (addr >= ref_addr + ref_size) return NULL; + low = symt_get_best_at(module, low);
return module->addr_sorttab[low]; } @@ -1236,7 +1252,7 @@ BOOL WINAPI SymFromAddr(HANDLE hProcess, DWORD64 Address,
symt_fill_sym_info(&pair, NULL, &sym->symt, Symbol); if (Displacement) - *Displacement = Address - Symbol->Address; + *Displacement = (Address >= Symbol->Address) ? (Address - Symbol->Address) : (DWORD64)-1; return TRUE; }
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=45009
Your paranoid android.
=== debian9 (32 bit report) ===
dbghelp: dbghelp.c:116: Test failed: got wrong name main
=== debian9 (32 bit Chinese:China report) ===
dbghelp: dbghelp.c:116: Test failed: got wrong name main
=== debian9 (32 bit WoW report) ===
dbghelp: dbghelp.c:116: Test failed: got wrong name main
=== debian9 (64 bit WoW report) ===
dbghelp: dbghelp.c:116: Test failed: got wrong name main