This series: - cleanups some code (using bitfield instead of hardcoded constants) - silences some FIXMEs in SymGetTypeInfo - fixes a couple of erroneous lexical relationship among dbghelp objects (mainly attaching - as native does - some objects to SymTagExe object)
From: Eric Pouech eric.pouech@gmail.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/dbghelp/type.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/dbghelp/type.c b/dlls/dbghelp/type.c index 0cbbc4e333b..170104bef86 100644 --- a/dlls/dbghelp/type.c +++ b/dlls/dbghelp/type.c @@ -945,7 +945,7 @@ BOOL symt_get_info(struct module* module, const struct symt* type, X(ULONG) = ((const struct symt_data*)type)->u.member.offset; break; default: - FIXME("Unknown kind (%u) for get-offset\n", + WARN("Unsupported kind (%u) for get-offset\n", ((const struct symt_data*)type)->kind); return FALSE; } @@ -957,6 +957,7 @@ BOOL symt_get_info(struct module* module, const struct symt* type, case SymTagExe: case SymTagCompiland: case SymTagUDT: + case SymTagEnum: case SymTagFunctionType: case SymTagFunctionArgType: case SymTagPointerType:
From: Eric Pouech eric.pouech@gmail.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/dbghelp/msc.c | 2 +- include/wine/mscvpdb.h | 22 ++++++++++++++++++++-- tools/winedump/msc.c | 28 ++++++++++++++-------------- 3 files changed, 35 insertions(+), 17 deletions(-)
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c index ce2ad9b4e01..e34853b45e8 100644 --- a/dlls/dbghelp/msc.c +++ b/dlls/dbghelp/msc.c @@ -2569,7 +2569,7 @@ static BOOL codeview_snarf(const struct msc_debug_info* msc_dbg, case S_LOCAL: length += codeview_transform_defrange(msc_dbg, curr_func, sym, &loc); symt_add_func_local(msc_dbg->module, curr_func, - sym->local_v3.varflags & 0x0001 ? DataIsParam : DataIsLocal, + sym->local_v3.varflags.is_param ? DataIsParam : DataIsLocal, &loc, block, codeview_get_type(sym->local_v3.symtype, FALSE), sym->local_v3.name); diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h index 8fb30d25cc6..994165463f3 100644 --- a/include/wine/mscvpdb.h +++ b/include/wine/mscvpdb.h @@ -1374,6 +1374,24 @@ struct cv_addr_gap unsigned short cbRange; };
+struct cv_local_varflag +{ + unsigned short is_param : 1; + unsigned short address_taken : 1; + unsigned short from_compiler : 1; /* generated by compiler */ + unsigned short is_aggregate : 1; /* splitted in several variables by compiler */ + unsigned short from_aggregate : 1; /* marks a temporary from an aggregate */ + unsigned short is_aliased : 1; + unsigned short from_alias : 1; + unsigned short is_return_value : 1; + unsigned short optimized_out : 1; + unsigned short enreg_global : 1; /* global variable accessed from register */ + unsigned short enreg_static : 1; + + unsigned short unused : 5; + +}; + union codeview_symbol { struct @@ -1874,7 +1892,7 @@ union codeview_symbol unsigned short int len; unsigned short int id; cv_typ_t symtype; - unsigned short varflags; + struct cv_local_varflag varflags; char name[1]; } local_v3;
@@ -2003,7 +2021,7 @@ union codeview_symbol unsigned short int id; cv_typ_t typind; unsigned int modOffset; - unsigned short varflags; + struct cv_local_varflag varflags; char name[1]; } file_static_v3;
diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c index 8c38dd1819e..85bbdfc3487 100644 --- a/tools/winedump/msc.c +++ b/tools/winedump/msc.c @@ -275,27 +275,27 @@ static const char* get_funcattr(unsigned attr) return tmp; }
-static const char* get_varflags(unsigned flags) +static const char* get_varflags(struct cv_local_varflag flags) { static char tmp[1024]; unsigned pos = 0;
- if (!flags) return "none"; #define X(s) {if (pos) tmp[pos++] = ';'; strcpy(tmp + pos, s); pos += strlen(s);} - if (flags & 0x0001) X("param"); - if (flags & 0x0002) X("addr-taken"); - if (flags & 0x0004) X("compiler-gen"); - if (flags & 0x0008) X("aggregated"); - if (flags & 0x0010) X("in-aggregate"); - if (flags & 0x0020) X("aliased"); - if (flags & 0x0040) X("alias"); - if (flags & 0x0080) X("retval"); - if (flags & 0x0100) X("optimized-out"); - if (flags & 0x0200) X("enreg-global"); - if (flags & 0x0400) X("enreg-static"); - if (flags & 0xf800) pos += sprintf(tmp, "unk:%x", flags & 0xf800); + if (flags.is_param) X("param"); + if (flags.address_taken) X("addr-taken"); + if (flags.from_compiler) X("compiler-gen"); + if (flags.is_aggregate) X("aggregated"); + if (flags.from_aggregate) X("in-aggregate"); + if (flags.is_aliased) X("aliased"); + if (flags.from_alias) X("alias"); + if (flags.is_return_value) X("retval"); + if (flags.optimized_out) X("optimized-out"); + if (flags.enreg_global) X("enreg-global"); + if (flags.enreg_static) X("enreg-static"); + if (flags.unused) pos += sprintf(tmp, "unk:%x", flags.unused); #undef X
+ if (!pos) return "none"; tmp[pos] = '\0'; assert(pos < sizeof(tmp));
From: Eric Pouech eric.pouech@gmail.com
PDB supports description of a global or static variable: - accessed from a register - stored as a local variable record inside a function
This likely describes access to a global/static variable where intermediate computation is kept in a register.
We cannot store this kind of entries in local variable lists (builtin dbghelp and winedbg are not prepared to handle a global variable)
Note: the global or static Codeview data record is still present (with a relocatable address), so the variable should still be available from global access (but could be not up-to-date if temporarly stored in a register).
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/dbghelp/msc.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-)
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c index e34853b45e8..bec9dec2532 100644 --- a/dlls/dbghelp/msc.c +++ b/dlls/dbghelp/msc.c @@ -1821,6 +1821,17 @@ static void codeview_xform_range(const struct msc_debug_info* msc_dbg, locinfo->rangelen = adrange->cbRange; }
+static unsigned codeview_defrange_length(const union codeview_symbol* sym) +{ + const union codeview_symbol* first_symrange = get_next_sym(sym); + const union codeview_symbol* symrange; + + for (symrange = first_symrange; + symrange->generic.id >= S_DEFRANGE && symrange->generic.id <= S_DEFRANGE_REGISTER_REL; + symrange = get_next_sym(symrange)) {} + return (const char*)symrange - (const char*)first_symrange; +} + static unsigned codeview_transform_defrange(const struct msc_debug_info* msc_dbg, struct symt_function* curr_func, const union codeview_symbol* sym, @@ -2567,12 +2578,21 @@ static BOOL codeview_snarf(const struct msc_debug_info* msc_dbg, } break; case S_LOCAL: - 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, - codeview_get_type(sym->local_v3.symtype, FALSE), - sym->local_v3.name); + /* FIXME: don't store global/static variables accessed through registers... we don't support that + * in locals... anyway, global data record should be present as well (so variable will be avaible + * through global defintion, but potentially not updated) + */ + if (!sym->local_v3.varflags.enreg_global && !sym->local_v3.varflags.enreg_static) + { + 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, + codeview_get_type(sym->local_v3.symtype, FALSE), + sym->local_v3.name); + } + else + length += codeview_defrange_length(sym); break; case S_INLINESITE: {
From: Eric Pouech eric.pouech@gmail.com
Global (non static) variables are now stored in symt_module. (static variables are stored in symt_compiland).
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/dbghelp/symbol.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c index a81feb56b8d..4bf0bbae74a 100644 --- a/dlls/dbghelp/symbol.c +++ b/dlls/dbghelp/symbol.c @@ -299,7 +299,7 @@ struct symt_data* symt_new_global_variable(struct module* module, sym->symt.tag = SymTagData; sym->hash_elt.name = pool_strdup(&module->pool, name); sym->kind = is_static ? DataIsFileStatic : DataIsGlobal; - sym->container = compiland ? &compiland->symt : NULL; + sym->container = compiland ? &compiland->symt : &module->top->symt; sym->type = type; sym->u.var = loc; if (type && size && symt_get_info(module, type, TI_GET_LENGTH, &tsz)) @@ -310,11 +310,8 @@ struct symt_data* symt_new_global_variable(struct module* module, wine_dbgstr_longlong(tsz), size); } symt_add_module_ht(module, (struct symt_ht*)sym); - if (compiland) - { - p = vector_add(&compiland->vchildren, &module->pool); - *p = &sym->symt; - } + p = vector_add(compiland ? &compiland->vchildren : &module->top->vchildren, &module->pool); + *p = &sym->symt; } return sym; }
From: Eric Pouech eric.pouech@gmail.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/dbghelp/type.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/dlls/dbghelp/type.c b/dlls/dbghelp/type.c index 170104bef86..53ba85f9e77 100644 --- a/dlls/dbghelp/type.c +++ b/dlls/dbghelp/type.c @@ -939,7 +939,13 @@ BOOL symt_get_info(struct module* module, const struct symt* type, { case DataIsParam: case DataIsLocal: - X(ULONG) = ((const struct symt_data*)type)->u.var.offset; + { + struct location loc = ((const struct symt_data*)type)->u.var; + if (loc.kind == loc_register || loc.kind == loc_regrel) + X(ULONG) = ((const struct symt_data*)type)->u.var.offset; + else + return FALSE; /* FIXME perhaps do better with local context? */ + } break; case DataIsMember: X(ULONG) = ((const struct symt_data*)type)->u.member.offset;
From: Eric Pouech eric.pouech@gmail.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/dbghelp/type.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/dbghelp/type.c b/dlls/dbghelp/type.c index 53ba85f9e77..3a5d3caf09f 100644 --- a/dlls/dbghelp/type.c +++ b/dlls/dbghelp/type.c @@ -321,7 +321,7 @@ BOOL symt_add_udt_element(struct module* module, struct symt_udt* udt_type, m->hash_elt.next = NULL;
m->kind = DataIsMember; - m->container = &udt_type->symt; + m->container = &module->top->symt; /* native defines lexical parent as module, not udt... */ m->type = elt_type; m->u.member.offset = offset; m->u.member.bit_offset = bit_offset;
From: Eric Pouech eric.pouech@gmail.com
(especially needed for enumeration's values)
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/dbghelp/symbol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c index 4bf0bbae74a..abf6054d0ee 100644 --- a/dlls/dbghelp/symbol.c +++ b/dlls/dbghelp/symbol.c @@ -662,7 +662,7 @@ struct symt_data* symt_new_constant(struct module* module, sym->symt.tag = SymTagData; sym->hash_elt.name = pool_strdup(&module->pool, name); sym->kind = DataIsConstant; - sym->container = compiland ? &compiland->symt : NULL; + sym->container = compiland ? &compiland->symt : &module->top->symt; sym->type = type; sym->u.value = *v; symt_add_module_ht(module, (struct symt_ht*)sym);