Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
November 2021
- 83 participants
- 2620 messages
[PATCH 07/13] dbghelp/pdb: properly handle S_LOCAL codeview entries
by Eric Pouech
Signed-off-by: Eric Pouech <eric.pouech(a)gmail.com>
---
dlls/dbghelp/msc.c | 180 +++++++++++++++++++++++++++++++++++++++++++++++-
include/wine/mscvpdb.h | 6 +-
2 files changed, 181 insertions(+), 5 deletions(-)
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c
index 3a62736e7ed..0c58e5fc14f 100644
--- a/dlls/dbghelp/msc.c
+++ b/dlls/dbghelp/msc.c
@@ -88,6 +88,8 @@ struct pdb_module_info
struct pdb_file_info pdb_files[CV_MAX_MODULES];
};
+#define loc_cv_local_range (loc_user + 0) /* loc.offset contain the copy of all defrange* Codeview records following S_LOCAL */
+
/*========================================================================
* Debug file access helper routines
*/
@@ -1581,6 +1583,24 @@ static ULONG_PTR codeview_get_address(const struct msc_debug_info* msc_dbg,
codeview_map_offset(msc_dbg, sectp[seg-1].VirtualAddress + offset);
}
+static BOOL func_has_local(struct symt_function* func, const char* name)
+{
+ int i;
+
+ for (i = 0; i < func->vchildren.num_elts; ++i)
+ {
+ struct symt* p = *(struct symt**)vector_at(&func->vchildren, i);
+ if (symt_check_tag(p, SymTagData) && !strcmp(((struct symt_data*)p)->hash_elt.name, name))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static const union codeview_symbol* get_next_sym(const union codeview_symbol* sym)
+{
+ return (const union codeview_symbol*)((const char*)sym + sym->generic.len + 2);
+}
+
static inline void codeview_add_variable(const struct msc_debug_info* msc_dbg,
struct symt_compiland* compiland,
const char* name,
@@ -1603,6 +1623,135 @@ static inline void codeview_add_variable(const struct msc_debug_info* msc_dbg,
}
}
+struct cv_local_info
+{
+ unsigned short kind; /* the S_DEFRANGE* */
+ unsigned short ngaps; /* number of gaps */
+ unsigned short reg;
+ unsigned short rangelen; /* after start */
+ short offset;
+ DWORD_PTR start;
+ struct cv_addr_gap gaps[0];
+};
+
+static const struct cv_addr_gap* codeview_get_gaps(const union codeview_symbol* symrange)
+{
+ const struct cv_addr_gap* gap;
+ switch (symrange->generic.id)
+ {
+ case S_DEFRANGE: gap = symrange->defrange_v3.gaps; break;
+ case S_DEFRANGE_SUBFIELD: gap = symrange->defrange_subfield_v3.gaps; break;
+ case S_DEFRANGE_REGISTER: gap = symrange->defrange_register_v3.gaps; break;
+ case S_DEFRANGE_FRAMEPOINTER_REL: gap = symrange->defrange_frameptrrel_v3.gaps; break;
+ case S_DEFRANGE_SUBFIELD_REGISTER: gap = symrange->defrange_subfield_register_v3.gaps; break;
+ case S_DEFRANGE_REGISTER_REL: gap = symrange->defrange_registerrel_v3.gaps; break;
+ /* no gaps for that one */
+ case S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE:
+ default: return NULL;
+ }
+ return gap != (const struct cv_addr_gap*)get_next_sym(symrange) ? gap : NULL;
+}
+
+static void codeview_xform_range(const struct msc_debug_info* msc_dbg,
+ struct cv_local_info* locinfo,
+ const struct cv_addr_range* adrange)
+{
+ locinfo->start = codeview_get_address(msc_dbg, adrange->isectStart, adrange->offStart);
+ locinfo->rangelen = adrange->cbRange;
+}
+
+static unsigned codeview_transform_defrange(const struct msc_debug_info* msc_dbg,
+ struct symt_function* curr_func,
+ const union codeview_symbol* sym,
+ struct location* loc)
+{
+ const union codeview_symbol* first_symrange = get_next_sym(sym);
+ const union codeview_symbol* symrange;
+ const struct cv_addr_gap* gap;
+ unsigned len, alloc = sizeof(DWORD); /* for terminating kind = 0 */
+ unsigned char* ptr;
+
+ /* we need to transform the cv_addr_range into cv_local_info */
+ for (symrange = first_symrange;
+ symrange->generic.id >= S_DEFRANGE && symrange->generic.id <= S_DEFRANGE_REGISTER_REL;
+ symrange = get_next_sym(symrange))
+ {
+ gap = codeview_get_gaps(symrange);
+ alloc += sizeof(struct cv_local_info) +
+ (gap ? (const char*)get_next_sym(symrange) - (const char*)gap : 0);
+ }
+ /* total length of all S_DEFRANGE* records (in bytes) following S_LOCAL */
+ len = (const char*)symrange - (const char*)first_symrange;
+
+ ptr = pool_alloc(&msc_dbg->module->pool, alloc);
+ if (ptr)
+ {
+ struct cv_local_info* locinfo = (struct cv_local_info*)ptr;
+
+ loc->kind = loc_cv_local_range;
+ loc->offset = (DWORD_PTR)ptr;
+ /* transform the cv_addr_range into cv_local_info */
+ for (symrange = first_symrange;
+ symrange->generic.id >= S_DEFRANGE && symrange->generic.id <= S_DEFRANGE_REGISTER_REL;
+ symrange = get_next_sym(symrange))
+ {
+ locinfo->kind = symrange->generic.id;
+ switch (symrange->generic.id)
+ {
+ case S_DEFRANGE:
+ case S_DEFRANGE_SUBFIELD:
+ /* FIXME: transformation unsupported; let loc_compute bark if actually needed */
+ break;
+ case S_DEFRANGE_REGISTER:
+ locinfo->reg = symrange->defrange_register_v3.reg;
+ codeview_xform_range(msc_dbg, locinfo, &symrange->defrange_register_v3.range);
+ break;
+ case S_DEFRANGE_FRAMEPOINTER_REL:
+ locinfo->offset = symrange->defrange_frameptrrel_v3.offFramePointer;
+ codeview_xform_range(msc_dbg, locinfo, &symrange->defrange_frameptrrel_v3.range);
+ break;
+ case S_DEFRANGE_SUBFIELD_REGISTER:
+ locinfo->reg = symrange->defrange_subfield_register_v3.reg;
+ locinfo->offset = symrange->defrange_subfield_register_v3.offParent;
+ codeview_xform_range(msc_dbg, locinfo, &symrange->defrange_subfield_register_v3.range);
+ break;
+ case S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE:
+ locinfo->offset = symrange->defrange_frameptr_relfullscope_v3.offFramePointer;
+ locinfo->start = curr_func->address;
+ locinfo->rangelen = curr_func->size;
+ break;
+ case S_DEFRANGE_REGISTER_REL:
+ locinfo->reg = symrange->defrange_registerrel_v3.baseReg;
+ locinfo->offset = symrange->defrange_registerrel_v3.offBasePointer;
+ codeview_xform_range(msc_dbg, locinfo, &symrange->defrange_registerrel_v3.range);
+ break;
+ default:
+ assert(0);
+ }
+ gap = codeview_get_gaps(symrange);
+ if (gap)
+ {
+ unsigned gaplen = (const char*)get_next_sym(symrange) - (const char*)gap;
+ locinfo->ngaps = gaplen / sizeof(*gap);
+ memcpy(locinfo->gaps, gap, gaplen);
+ locinfo = (struct cv_local_info*)((unsigned char*)(locinfo + 1) + gaplen);
+ }
+ else
+ {
+ locinfo->ngaps = 0;
+ locinfo++;
+ }
+ }
+ *(DWORD*)locinfo = 0; /* store terminating kind == 0 */
+ }
+ else
+ {
+ loc->kind = loc_error;
+ loc->reg = loc_err_internal;
+ }
+ return len;
+}
+
static BOOL codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* root,
int offset, int size, BOOL do_globals)
{
@@ -1774,6 +1923,8 @@ static BOOL codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* roo
terminate_string(&sym->stack_v2.p_name));
break;
case S_BPREL32:
+ /* S_BPREL32 can be present after S_LOCAL; prefer S_LOCAL when present */
+ if (func_has_local(curr_func, sym->stack_v3.name)) break;
loc.kind = loc_regrel;
/* Yes, it's i386 dependent, but that's the symbol purpose. S_REGREL is used on other CPUs */
loc.reg = CV_REG_EBP;
@@ -1785,6 +1936,8 @@ static BOOL codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* roo
sym->stack_v3.name);
break;
case S_REGREL32:
+ /* S_REGREL32 can be present after S_LOCAL; prefer S_LOCAL when present */
+ if (func_has_local(curr_func, sym->regrel_v3.name)) break;
loc.kind = loc_regrel;
loc.reg = sym->regrel_v3.reg;
loc.offset = sym->regrel_v3.offset;
@@ -1815,6 +1968,8 @@ static BOOL codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* roo
terminate_string(&sym->register_v2.p_name));
break;
case S_REGISTER:
+ /* S_REGISTER can be present after S_LOCAL; prefer S_LOCAL when present */
+ if (func_has_local(curr_func, sym->register_v3.name)) break;
loc.kind = loc_register;
loc.reg = sym->register_v3.reg;
loc.offset = 0;
@@ -1989,6 +2144,14 @@ static BOOL codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* roo
sym->udt_v3.name, sym->udt_v3.type);
}
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 & 0x0001 ? DataIsParam : DataIsLocal,
+ &loc, block,
+ codeview_get_type(sym->local_v3.symtype, FALSE),
+ sym->local_v3.name);
+ break;
/*
* These are special, in that they are always followed by an
@@ -2027,8 +2190,11 @@ static BOOL codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* roo
case S_SECTION:
case S_COFFGROUP:
case S_EXPORT:
- case S_LOCAL:
case S_CALLSITEINFO:
+ /* even if S_LOCAL groks all the S_DEFRANGE* records following itself,
+ * those kinds of records can also be present after a S_FILESTATIC record
+ * so silence them until (at least) S_FILESTATIC is supported
+ */
case S_DEFRANGE_REGISTER:
case S_DEFRANGE_FRAMEPOINTER_REL:
case S_DEFRANGE_SUBFIELD_REGISTER:
@@ -2054,6 +2220,16 @@ static BOOL codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* roo
return TRUE;
}
+static void pdb_location_compute(struct process* pcs,
+ const struct module_format* modfmt,
+ const struct symt_function* func,
+ struct location* loc)
+
+{
+ loc->kind = loc_register;
+ loc->reg = loc_err_internal;
+}
+
static BOOL codeview_snarf_public(const struct msc_debug_info* msc_dbg, const BYTE* root,
int offset, int size)
@@ -2886,7 +3062,7 @@ static BOOL pdb_process_file(const struct process* pcs,
msc_dbg->module->format_info[DFI_PDB] = modfmt;
modfmt->module = msc_dbg->module;
modfmt->remove = pdb_module_remove;
- modfmt->loc_compute = NULL;
+ modfmt->loc_compute = pdb_location_compute;
modfmt->u.pdb_info = pdb_module_info;
memset(cv_zmodules, 0, sizeof(cv_zmodules));
diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h
index 1a173c097d7..9a733333837 100644
--- a/include/wine/mscvpdb.h
+++ b/include/wine/mscvpdb.h
@@ -1879,7 +1879,7 @@ union codeview_symbol
{
unsigned short int len;
unsigned short int id;
- unsigned int offFramePointer;
+ int offFramePointer;
struct cv_addr_range range;
struct cv_addr_gap gaps[0];
} defrange_frameptrrel_v3;
@@ -1888,7 +1888,7 @@ union codeview_symbol
{
unsigned short int len;
unsigned short int id;
- unsigned int offFramePointer;
+ int offFramePointer;
} defrange_frameptr_relfullscope_v3;
struct
@@ -1911,7 +1911,7 @@ union codeview_symbol
unsigned short spilledUdtMember : 1;
unsigned short padding : 3;
unsigned short offsetParent : 12;
- unsigned int offBasePointer;
+ int offBasePointer;
struct cv_addr_range range;
struct cv_addr_gap gaps[0];
} defrange_registerrel_v3;
Nov. 8, 2021
[PATCH 06/13] dbghelp/pdb: added new basic type to represent char8_t introduced in C++20
by Eric Pouech
Signed-off-by: Eric Pouech <eric.pouech(a)gmail.com>
---
dlls/dbghelp/msc.c | 4 ++++
include/cvconst.h | 3 ++-
include/wine/mscvpdb.h | 7 +++++++
3 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c
index a2d9f0bb368..3a62736e7ed 100644
--- a/dlls/dbghelp/msc.c
+++ b/dlls/dbghelp/msc.c
@@ -166,6 +166,7 @@ static void codeview_init_basic_types(struct module* module)
cv_basic_types[T_WCHAR] = &symt_new_basic(module, btWChar, "wchar_t", 2)->symt;
cv_basic_types[T_CHAR16] = &symt_new_basic(module, btChar16,"char16_t", 2)->symt;
cv_basic_types[T_CHAR32] = &symt_new_basic(module, btChar32,"char32_t", 4)->symt;
+ cv_basic_types[T_CHAR8] = &symt_new_basic(module, btChar8, "char8_t", 1)->symt;
cv_basic_types[T_INT2] = &symt_new_basic(module, btInt, "INT2", 2)->symt;
cv_basic_types[T_UINT2] = &symt_new_basic(module, btUInt, "UINT2", 2)->symt;
cv_basic_types[T_INT4] = &symt_new_basic(module, btInt, "INT4", 4)->symt;
@@ -194,6 +195,7 @@ static void codeview_init_basic_types(struct module* module)
cv_basic_types[T_32PWCHAR] = &symt_new_pointer(module, cv_basic_types[T_WCHAR], 4)->symt;
cv_basic_types[T_32PCHAR16] = &symt_new_pointer(module, cv_basic_types[T_CHAR16], 4)->symt;
cv_basic_types[T_32PCHAR32] = &symt_new_pointer(module, cv_basic_types[T_CHAR32], 4)->symt;
+ cv_basic_types[T_32PCHAR8] = &symt_new_pointer(module, cv_basic_types[T_CHAR8], 4)->symt;
cv_basic_types[T_32PINT2] = &symt_new_pointer(module, cv_basic_types[T_INT2], 4)->symt;
cv_basic_types[T_32PUINT2] = &symt_new_pointer(module, cv_basic_types[T_UINT2], 4)->symt;
cv_basic_types[T_32PINT4] = &symt_new_pointer(module, cv_basic_types[T_INT4], 4)->symt;
@@ -222,6 +224,7 @@ static void codeview_init_basic_types(struct module* module)
cv_basic_types[T_64PWCHAR] = &symt_new_pointer(module, cv_basic_types[T_WCHAR], 8)->symt;
cv_basic_types[T_64PCHAR16] = &symt_new_pointer(module, cv_basic_types[T_CHAR16], 8)->symt;
cv_basic_types[T_64PCHAR32] = &symt_new_pointer(module, cv_basic_types[T_CHAR32], 8)->symt;
+ cv_basic_types[T_64PCHAR8] = &symt_new_pointer(module, cv_basic_types[T_CHAR8], 8)->symt;
cv_basic_types[T_64PINT2] = &symt_new_pointer(module, cv_basic_types[T_INT2], 8)->symt;
cv_basic_types[T_64PUINT2] = &symt_new_pointer(module, cv_basic_types[T_UINT2], 8)->symt;
cv_basic_types[T_64PINT4] = &symt_new_pointer(module, cv_basic_types[T_INT4], 8)->symt;
@@ -250,6 +253,7 @@ static void codeview_init_basic_types(struct module* module)
cv_basic_types[T_PWCHAR] = &symt_new_pointer(module, cv_basic_types[T_WCHAR], ptrsz)->symt;
cv_basic_types[T_PCHAR16] = &symt_new_pointer(module, cv_basic_types[T_CHAR16], ptrsz)->symt;
cv_basic_types[T_PCHAR32] = &symt_new_pointer(module, cv_basic_types[T_CHAR32], ptrsz)->symt;
+ cv_basic_types[T_PCHAR8] = &symt_new_pointer(module, cv_basic_types[T_CHAR8], ptrsz)->symt;
cv_basic_types[T_PINT2] = &symt_new_pointer(module, cv_basic_types[T_INT2], ptrsz)->symt;
cv_basic_types[T_PUINT2] = &symt_new_pointer(module, cv_basic_types[T_UINT2], ptrsz)->symt;
cv_basic_types[T_PINT4] = &symt_new_pointer(module, cv_basic_types[T_INT4], ptrsz)->symt;
diff --git a/include/cvconst.h b/include/cvconst.h
index 82929dda772..9536ee8202d 100644
--- a/include/cvconst.h
+++ b/include/cvconst.h
@@ -91,7 +91,8 @@ enum BasicType
btBSTR = 30,
btHresult = 31,
btChar16 = 32,
- btChar32 = 33
+ btChar32 = 33,
+ btChar8 = 34,
};
/* kind of UDT */
diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h
index e199aff785f..1a173c097d7 100644
--- a/include/wine/mscvpdb.h
+++ b/include/wine/mscvpdb.h
@@ -945,6 +945,7 @@ union codeview_fieldtype
#define T_UINT8 0x0077 /* 64-bit unsigned int */
#define T_CHAR16 0x007a /* 16-bit unicode char */
#define T_CHAR32 0x007b /* 32-bit unicode char */
+#define T_CHAR8 0x007c /* 8-bit unicode char (C++ 20) */
/* near pointers to basic types */
#define T_PVOID 0x0103 /* near pointer to void */
@@ -979,6 +980,7 @@ union codeview_fieldtype
#define T_PUINT8 0x0177 /* Near pointer to 64-bit unsigned int */
#define T_PCHAR16 0x017a /* Near pointer to 16-bit unicode char */
#define T_PCHAR32 0x017b /* Near pointer to 32-bit unicode char */
+#define T_PCHAR8 0x017c /* Near pointer to 8-bit unicode char */
/* far pointers to basic types */
#define T_PFVOID 0x0203 /* Far pointer to void */
@@ -1013,6 +1015,7 @@ union codeview_fieldtype
#define T_PFUINT8 0x0277 /* Far pointer to 64-bit unsigned int */
#define T_PFCHAR16 0x027a /* Far pointer to 16-bit unicode char */
#define T_PFCHAR32 0x027b /* Far pointer to 32-bit unicode char */
+#define T_PFCHAR8 0x027c /* Far pointer to 8-bit unicode char */
/* huge pointers to basic types */
#define T_PHVOID 0x0303 /* Huge pointer to void */
@@ -1047,6 +1050,7 @@ union codeview_fieldtype
#define T_PHUINT8 0x0377 /* Huge pointer to 64-bit unsigned int */
#define T_PHCHAR16 0x037a /* Huge pointer to 16-bit unicode char */
#define T_PHCHAR32 0x037b /* Huge pointer to 32-bit unicode char */
+#define T_PHCHAR8 0x037c /* Huge pointer to 8-bit unicode char */
/* 32-bit near pointers to basic types */
#define T_32PVOID 0x0403 /* 32-bit near pointer to void */
@@ -1082,6 +1086,7 @@ union codeview_fieldtype
#define T_32PUINT8 0x0477 /* 16:32 near pointer to 64-bit unsigned int */
#define T_32PCHAR16 0x047a /* 16:32 near pointer to 16-bit unicode char */
#define T_32PCHAR32 0x047b /* 16:32 near pointer to 32-bit unicode char */
+#define T_32PCHAR8 0x047c /* 16:32 near pointer to 8-bit unicode char */
/* 32-bit far pointers to basic types */
#define T_32PFVOID 0x0503 /* 32-bit far pointer to void */
@@ -1117,6 +1122,7 @@ union codeview_fieldtype
#define T_32PFUINT8 0x0577 /* 16:32 far pointer to 64-bit unsigned int */
#define T_32PFCHAR16 0x057a /* 16:32 far pointer to 16-bit unicode char */
#define T_32PFCHAR32 0x057b /* 16:32 far pointer to 32-bit unicode char */
+#define T_32PFCHAR8 0x057c /* 16:32 far pointer to 8-bit unicode char */
/* 64-bit near pointers to basic types */
#define T_64PVOID 0x0603 /* 64-bit near pointer to void */
@@ -1152,6 +1158,7 @@ union codeview_fieldtype
#define T_64PUINT8 0x0677 /* 64 near pointer to 64-bit unsigned int */
#define T_64PCHAR16 0x067a /* 64 near pointer to 16-bit unicode char */
#define T_64PCHAR32 0x067b /* 64 near pointer to 32-bit unicode char */
+#define T_64PCHAR8 0x067c /* 64 near pointer to 8-bit unicode char */
/* counts, bit masks, and shift values needed to access various parts of the built-in type numbers */
#define T_MAXPREDEFINEDTYPE 0x0580 /* maximum type index for all built-in types */
Nov. 8, 2021
[PATCH 05/13] dbghelp: rather use cpu from debuggee's modules than debugger's
by Eric Pouech
Signed-off-by: Eric Pouech <eric.pouech(a)gmail.com>
---
dlls/dbghelp/dwarf.c | 50 +++++++++++++++++++++++++++----------------------
dlls/dbghelp/module.c | 6 +++---
dlls/dbghelp/stabs.c | 4 ++--
3 files changed, 33 insertions(+), 27 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c
index 7ecd04d216e..90452d74eaf 100644
--- a/dlls/dbghelp/dwarf.c
+++ b/dlls/dbghelp/dwarf.c
@@ -812,7 +812,7 @@ static unsigned dwarf2_map_register(int regno, const struct module* module)
FIXME("What the heck map reg 0x%x\n",regno);
return 0;
}
- return dbghelp_current_cpu->map_dwarf_register(regno, module, FALSE);
+ return module->cpu->map_dwarf_register(regno, module, FALSE);
}
static enum location_error
@@ -847,8 +847,8 @@ compute_location(const struct module *module, const dwarf2_cuhead_t* head,
DWORD cvreg = dwarf2_map_register(op - DW_OP_reg0, module);
if (loc->reg != Wine_DW_no_register)
FIXME("Only supporting one reg (%s/%d -> %s/%d)\n",
- dbghelp_current_cpu->fetch_regname(loc->reg), loc->reg,
- dbghelp_current_cpu->fetch_regname(cvreg), cvreg);
+ module->cpu->fetch_regname(loc->reg), loc->reg,
+ module->cpu->fetch_regname(cvreg), cvreg);
loc->reg = cvreg;
}
loc->kind = loc_register;
@@ -864,8 +864,8 @@ compute_location(const struct module *module, const dwarf2_cuhead_t* head,
DWORD cvreg = dwarf2_map_register(op - DW_OP_breg0, module);
if (loc->reg != Wine_DW_no_register)
FIXME("Only supporting one breg (%s/%d -> %s/%d)\n",
- dbghelp_current_cpu->fetch_regname(loc->reg), loc->reg,
- dbghelp_current_cpu->fetch_regname(cvreg), cvreg);
+ module->cpu->fetch_regname(loc->reg), loc->reg,
+ module->cpu->fetch_regname(cvreg), cvreg);
loc->reg = cvreg;
}
stack[++stk] = dwarf2_leb128_as_signed(ctx);
@@ -938,7 +938,7 @@ compute_location(const struct module *module, const dwarf2_cuhead_t* head,
case DW_OP_fbreg:
if (loc->reg != Wine_DW_no_register)
FIXME("Only supporting one reg (%s/%d -> -2)\n",
- dbghelp_current_cpu->fetch_regname(loc->reg), loc->reg);
+ module->cpu->fetch_regname(loc->reg), loc->reg);
if (frame && frame->kind == loc_register)
{
loc->kind = loc_regrel;
@@ -2284,7 +2284,7 @@ static struct symt* dwarf2_parse_subprogram(dwarf2_debug_info_t* di)
{
/* on stack !! */
subpgm.frame.kind = loc_regrel;
- subpgm.frame.reg = dbghelp_current_cpu->frame_regno;
+ subpgm.frame.reg = di->unit_ctx->module_ctx->module->cpu->frame_regno;
subpgm.frame.offset = 0;
}
subpgm.non_computed_variable = FALSE;
@@ -3256,7 +3256,7 @@ static void execute_cfa_instructions(struct module* module, dwarf2_traverse_cont
if (!valid_reg(reg)) break;
TRACE("%lx: DW_CFA_offset %s, %ld\n",
info->ip,
- dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, module, TRUE)),
+ module->cpu->fetch_regname(module->cpu->map_dwarf_register(reg, module, TRUE)),
offset);
info->state.regs[reg] = offset;
info->state.rules[reg] = RULE_CFA_OFFSET;
@@ -3268,7 +3268,7 @@ static void execute_cfa_instructions(struct module* module, dwarf2_traverse_cont
if (!valid_reg(reg)) break;
TRACE("%lx: DW_CFA_restore %s\n",
info->ip,
- dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, module, TRUE)));
+ module->cpu->fetch_regname(module->cpu->map_dwarf_register(reg, module, TRUE)));
info->state.rules[reg] = RULE_UNSET;
break;
}
@@ -3316,7 +3316,7 @@ static void execute_cfa_instructions(struct module* module, dwarf2_traverse_cont
if (!valid_reg(reg)) break;
TRACE("%lx: DW_CFA_offset_extended %s, %ld\n",
info->ip,
- dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, module, TRUE)),
+ module->cpu->fetch_regname(module->cpu->map_dwarf_register(reg, module, TRUE)),
offset);
info->state.regs[reg] = offset;
info->state.rules[reg] = RULE_CFA_OFFSET;
@@ -3328,7 +3328,7 @@ static void execute_cfa_instructions(struct module* module, dwarf2_traverse_cont
if (!valid_reg(reg)) break;
TRACE("%lx: DW_CFA_restore_extended %s\n",
info->ip,
- dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, module, TRUE)));
+ module->cpu->fetch_regname(module->cpu->map_dwarf_register(reg, module, TRUE)));
info->state.rules[reg] = RULE_UNSET;
break;
}
@@ -3338,7 +3338,7 @@ static void execute_cfa_instructions(struct module* module, dwarf2_traverse_cont
if (!valid_reg(reg)) break;
TRACE("%lx: DW_CFA_undefined %s\n",
info->ip,
- dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, module, TRUE)));
+ module->cpu->fetch_regname(module->cpu->map_dwarf_register(reg, module, TRUE)));
info->state.rules[reg] = RULE_UNDEFINED;
break;
}
@@ -3348,7 +3348,7 @@ static void execute_cfa_instructions(struct module* module, dwarf2_traverse_cont
if (!valid_reg(reg)) break;
TRACE("%lx: DW_CFA_same_value %s\n",
info->ip,
- dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, module, TRUE)));
+ module->cpu->fetch_regname(module->cpu->map_dwarf_register(reg, module, TRUE)));
info->state.regs[reg] = reg;
info->state.rules[reg] = RULE_SAME;
break;
@@ -3360,8 +3360,8 @@ static void execute_cfa_instructions(struct module* module, dwarf2_traverse_cont
if (!valid_reg(reg) || !valid_reg(reg2)) break;
TRACE("%lx: DW_CFA_register %s == %s\n",
info->ip,
- dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, module, TRUE)),
- dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg2, module, TRUE)));
+ module->cpu->fetch_regname(module->cpu->map_dwarf_register(reg, module, TRUE)),
+ module->cpu->fetch_regname(module->cpu->map_dwarf_register(reg2, module, TRUE)));
info->state.regs[reg] = reg2;
info->state.rules[reg] = RULE_OTHER_REG;
break;
@@ -3389,7 +3389,7 @@ static void execute_cfa_instructions(struct module* module, dwarf2_traverse_cont
if (!valid_reg(reg)) break;
TRACE("%lx: DW_CFA_def_cfa %s, %ld\n",
info->ip,
- dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, module, TRUE)),
+ module->cpu->fetch_regname(module->cpu->map_dwarf_register(reg, module, TRUE)),
offset);
info->state.cfa_reg = reg;
info->state.cfa_offset = offset;
@@ -3402,7 +3402,7 @@ static void execute_cfa_instructions(struct module* module, dwarf2_traverse_cont
if (!valid_reg(reg)) break;
TRACE("%lx: DW_CFA_def_cfa_register %s\n",
info->ip,
- dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, module, TRUE)));
+ module->cpu->fetch_regname(module->cpu->map_dwarf_register(reg, module, TRUE)));
info->state.cfa_reg = reg;
info->state.cfa_rule = RULE_CFA_OFFSET;
break;
@@ -3436,7 +3436,7 @@ static void execute_cfa_instructions(struct module* module, dwarf2_traverse_cont
if (!valid_reg(reg)) break;
TRACE("%lx: DW_CFA_%sexpression %s %lx-%lx\n",
info->ip, (op == DW_CFA_expression) ? "" : "val_",
- dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, module, TRUE)),
+ module->cpu->fetch_regname(module->cpu->map_dwarf_register(reg, module, TRUE)),
expr, expr + len);
info->state.regs[reg] = expr;
info->state.rules[reg] = (op == DW_CFA_expression) ? RULE_EXPRESSION : RULE_VAL_EXPRESSION;
@@ -3465,6 +3465,7 @@ static DWORD64 get_context_reg(const struct module* module, struct cpu_stack_wal
unsigned regno = csw->cpu->map_dwarf_register(dw_reg, module, TRUE), sz;
void* ptr = csw->cpu->fetch_context_reg(context, regno, &sz);
+ if (csw->cpu != module->cpu) FIXME("mismatch in cpu\n");
if (sz == 8)
return *(DWORD64 *)ptr;
else if (sz == 4)
@@ -3481,6 +3482,7 @@ static void set_context_reg(const struct module* module, struct cpu_stack_walk*
unsigned regno = csw->cpu->map_dwarf_register(dw_reg, module, TRUE), sz;
ULONG_PTR* ptr = csw->cpu->fetch_context_reg(context, regno, &sz);
+ if (csw->cpu != module->cpu) FIXME("mismatch in cpu\n");
if (isdebuggee)
{
char tmp[16];
@@ -3518,6 +3520,7 @@ static void copy_context_reg(const struct module* module, struct cpu_stack_walk
ULONG_PTR* ptrdst = csw->cpu->fetch_context_reg(dstcontext, regdstno, &szdst);
ULONG_PTR* ptrsrc = csw->cpu->fetch_context_reg(srccontext, regsrcno, &szsrc);
+ if (csw->cpu != module->cpu) FIXME("mismatch in cpu\n");
if (szdst != szsrc)
{
FIXME("Cannot copy register %lu/%u => %lu/%u because of size mismatch (%u => %u)\n",
@@ -3536,6 +3539,7 @@ static ULONG_PTR eval_expression(const struct module* module, struct cpu_stack_w
int sp = -1;
ULONG_PTR len;
+ if (csw->cpu != module->cpu) FIXME("mismatch in cpu\n");
ctx.data = zp;
ctx.end_data = zp + 4;
len = dwarf2_leb128_as_unsigned(&ctx);
@@ -3647,6 +3651,7 @@ static void apply_frame_state(const struct module* module, struct cpu_stack_walk
ULONG_PTR value;
union ctx new_context = *context;
+ if (csw->cpu != module->cpu) FIXME("mismatch in cpu\n");
switch (state->cfa_rule)
{
case RULE_EXPRESSION:
@@ -3756,6 +3761,7 @@ BOOL dwarf2_virtual_unwind(struct cpu_stack_walk *csw, ULONG_PTR ip,
struct frame_info info;
if (!module_init_pair(&pair, csw->hProcess, ip)) return FALSE;
+ if (csw->cpu != pair.effective->cpu) FIXME("mismatch in cpu\n");
if (!dwarf2_fetch_frame_info(pair.effective, csw->cpu, ip, &info)) return FALSE;
/* if at very beginning of function, return and use default unwinder */
@@ -3773,15 +3779,15 @@ static BOOL compute_call_frame_cfa(struct module* module, ULONG_PTR ip, struct l
{
struct frame_info info;
- if (!dwarf2_fetch_frame_info(module, dbghelp_current_cpu, ip, &info)) return FALSE;
+ if (!dwarf2_fetch_frame_info(module, module->cpu, ip, &info)) return FALSE;
/* beginning of function, or no available dwarf information ? */
if (ip == info.ip || info.state.rules[info.retaddr_reg] == RULE_UNSET)
{
/* fake the default unwinder */
frame->kind = loc_regrel;
- frame->reg = dbghelp_current_cpu->frame_regno;
- frame->offset = dbghelp_current_cpu->word_size; /* FIXME stack direction */
+ frame->reg = module->cpu->frame_regno;
+ frame->offset = module->cpu->word_size; /* FIXME stack direction */
}
else
{
@@ -3798,7 +3804,7 @@ static BOOL compute_call_frame_cfa(struct module* module, ULONG_PTR ip, struct l
return FALSE;
default:
frame->kind = loc_regrel;
- frame->reg = dbghelp_current_cpu->map_dwarf_register(info.state.cfa_reg, module, TRUE);
+ frame->reg = module->cpu->map_dwarf_register(info.state.cfa_reg, module, TRUE);
frame->offset = info.state.cfa_offset;
break;
}
diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c
index 65bdbb38fda..302f85b0747 100644
--- a/dlls/dbghelp/module.c
+++ b/dlls/dbghelp/module.c
@@ -1480,11 +1480,11 @@ PVOID WINAPI SymFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase)
struct process* pcs = process_find_by_handle(hProcess);
struct module* module;
- if (!pcs || !dbghelp_current_cpu->find_runtime_function) return NULL;
+ if (!pcs) return NULL;
module = module_find_by_addr(pcs, AddrBase, DMT_UNKNOWN);
- if (!module) return NULL;
+ if (!module || !module->cpu->find_runtime_function) return NULL;
- return dbghelp_current_cpu->find_runtime_function(module, AddrBase);
+ return module->cpu->find_runtime_function(module, AddrBase);
}
static BOOL native_synchronize_module_list(struct process* pcs)
diff --git a/dlls/dbghelp/stabs.c b/dlls/dbghelp/stabs.c
index f2b3e6d5c7d..931102c4fb3 100644
--- a/dlls/dbghelp/stabs.c
+++ b/dlls/dbghelp/stabs.c
@@ -1396,7 +1396,7 @@ BOOL stabs_parse(struct module* module, ULONG_PTR load_offset,
continue;
}
loc.kind = loc_regrel;
- loc.reg = dbghelp_current_cpu->frame_regno;
+ loc.reg = module->cpu->frame_regno;
loc.offset = n_value;
symt_add_func_local(module, curr_func,
(int)n_value >= 0 ? DataIsParam : DataIsLocal,
@@ -1476,7 +1476,7 @@ BOOL stabs_parse(struct module* module, ULONG_PTR load_offset,
case N_LSYM:
/* These are local variables */
loc.kind = loc_regrel;
- loc.reg = dbghelp_current_cpu->frame_regno;
+ loc.reg = module->cpu->frame_regno;
loc.offset = n_value;
if (curr_func != NULL) pending_add_var(&pending_block, ptr, DataIsLocal, &loc);
break;
Nov. 8, 2021
[PATCH 04/13] dbghelp: use module's cpu word size instead of sizeof(void*) or sizeof(DWORD_PTR)
by Eric Pouech
this fixes a couple of wrong pointer size computation when debugging a WoW64 process
from a 64 bit debugger
Signed-off-by: Eric Pouech <eric.pouech(a)gmail.com>
---
dlls/dbghelp/dwarf.c | 7 ++++--
dlls/dbghelp/msc.c | 56 ++++++++++++++++++++++++++------------------------
dlls/dbghelp/stabs.c | 2 +-
3 files changed, 34 insertions(+), 31 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c
index d812e03f833..7ecd04d216e 100644
--- a/dlls/dbghelp/dwarf.c
+++ b/dlls/dbghelp/dwarf.c
@@ -1488,7 +1488,7 @@ static struct symt* dwarf2_parse_pointer_type(dwarf2_debug_info_t* di)
TRACE("%s\n", dwarf2_debug_di(di));
- if (!dwarf2_find_attribute(di, DW_AT_byte_size, &size)) size.u.uvalue = sizeof(void *);
+ if (!dwarf2_find_attribute(di, DW_AT_byte_size, &size)) size.u.uvalue = di->unit_ctx->module_ctx->module->cpu->word_size;
ref_type = dwarf2_lookup_type(di);
di->symt = &symt_new_pointer(di->unit_ctx->module_ctx->module, ref_type, size.u.uvalue)->symt;
if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n");
@@ -1645,7 +1645,7 @@ static struct symt* dwarf2_parse_unspecified_type(dwarf2_debug_info_t* di)
if (!dwarf2_find_attribute(di, DW_AT_name, &name))
name.u.string = "void";
- size.u.uvalue = sizeof(void *);
+ size.u.uvalue = di->unit_ctx->module_ctx->module->cpu->word_size;
basic = symt_new_basic(di->unit_ctx->module_ctx->module, btVoid, name.u.string, size.u.uvalue);
di->symt = &basic->symt;
@@ -1664,7 +1664,8 @@ static struct symt* dwarf2_parse_reference_type(dwarf2_debug_info_t* di)
ref_type = dwarf2_lookup_type(di);
/* FIXME: for now, we hard-wire C++ references to pointers */
- di->symt = &symt_new_pointer(di->unit_ctx->module_ctx->module, ref_type, sizeof(void *))->symt;
+ di->symt = &symt_new_pointer(di->unit_ctx->module_ctx->module, ref_type,
+ di->unit_ctx->module_ctx->module->cpu->word_size)->symt;
if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n");
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c
index 97991be057f..a2d9f0bb368 100644
--- a/dlls/dbghelp/msc.c
+++ b/dlls/dbghelp/msc.c
@@ -139,6 +139,8 @@ static struct cv_defined_module*cv_current_module;
static void codeview_init_basic_types(struct module* module)
{
+ unsigned ptrsz = module->cpu->word_size;
+
/*
* These are the common builtin types that are used by VC++.
*/
@@ -228,32 +230,32 @@ static void codeview_init_basic_types(struct module* module)
cv_basic_types[T_64PUINT8] = &symt_new_pointer(module, cv_basic_types[T_UINT8], 8)->symt;
cv_basic_types[T_64PHRESULT]= &symt_new_pointer(module, cv_basic_types[T_HRESULT], 8)->symt;
- cv_basic_types[T_PVOID] = &symt_new_pointer(module, cv_basic_types[T_VOID], sizeof(void*))->symt;
- cv_basic_types[T_PCHAR] = &symt_new_pointer(module, cv_basic_types[T_CHAR], sizeof(void*))->symt;
- cv_basic_types[T_PSHORT] = &symt_new_pointer(module, cv_basic_types[T_SHORT], sizeof(void*))->symt;
- cv_basic_types[T_PLONG] = &symt_new_pointer(module, cv_basic_types[T_LONG], sizeof(void*))->symt;
- cv_basic_types[T_PQUAD] = &symt_new_pointer(module, cv_basic_types[T_QUAD], sizeof(void*))->symt;
- cv_basic_types[T_PUCHAR] = &symt_new_pointer(module, cv_basic_types[T_UCHAR], sizeof(void*))->symt;
- cv_basic_types[T_PUSHORT] = &symt_new_pointer(module, cv_basic_types[T_USHORT], sizeof(void*))->symt;
- cv_basic_types[T_PULONG] = &symt_new_pointer(module, cv_basic_types[T_ULONG], sizeof(void*))->symt;
- cv_basic_types[T_PUQUAD] = &symt_new_pointer(module, cv_basic_types[T_UQUAD], sizeof(void*))->symt;
- cv_basic_types[T_PBOOL08] = &symt_new_pointer(module, cv_basic_types[T_BOOL08], sizeof(void*))->symt;
- cv_basic_types[T_PBOOL16] = &symt_new_pointer(module, cv_basic_types[T_BOOL16], sizeof(void*))->symt;
- cv_basic_types[T_PBOOL32] = &symt_new_pointer(module, cv_basic_types[T_BOOL32], sizeof(void*))->symt;
- cv_basic_types[T_PBOOL64] = &symt_new_pointer(module, cv_basic_types[T_BOOL64], sizeof(void*))->symt;
- cv_basic_types[T_PREAL32] = &symt_new_pointer(module, cv_basic_types[T_REAL32], sizeof(void*))->symt;
- cv_basic_types[T_PREAL64] = &symt_new_pointer(module, cv_basic_types[T_REAL64], sizeof(void*))->symt;
- cv_basic_types[T_PREAL80] = &symt_new_pointer(module, cv_basic_types[T_REAL80], sizeof(void*))->symt;
- cv_basic_types[T_PRCHAR] = &symt_new_pointer(module, cv_basic_types[T_RCHAR], sizeof(void*))->symt;
- cv_basic_types[T_PWCHAR] = &symt_new_pointer(module, cv_basic_types[T_WCHAR], sizeof(void*))->symt;
- cv_basic_types[T_PCHAR16] = &symt_new_pointer(module, cv_basic_types[T_CHAR16], sizeof(void*))->symt;
- cv_basic_types[T_PCHAR32] = &symt_new_pointer(module, cv_basic_types[T_CHAR32], sizeof(void*))->symt;
- cv_basic_types[T_PINT2] = &symt_new_pointer(module, cv_basic_types[T_INT2], sizeof(void*))->symt;
- cv_basic_types[T_PUINT2] = &symt_new_pointer(module, cv_basic_types[T_UINT2], sizeof(void*))->symt;
- cv_basic_types[T_PINT4] = &symt_new_pointer(module, cv_basic_types[T_INT4], sizeof(void*))->symt;
- cv_basic_types[T_PUINT4] = &symt_new_pointer(module, cv_basic_types[T_UINT4], sizeof(void*))->symt;
- cv_basic_types[T_PINT8] = &symt_new_pointer(module, cv_basic_types[T_INT8], sizeof(void*))->symt;
- cv_basic_types[T_PUINT8] = &symt_new_pointer(module, cv_basic_types[T_UINT8], sizeof(void*))->symt;
+ cv_basic_types[T_PVOID] = &symt_new_pointer(module, cv_basic_types[T_VOID], ptrsz)->symt;
+ cv_basic_types[T_PCHAR] = &symt_new_pointer(module, cv_basic_types[T_CHAR], ptrsz)->symt;
+ cv_basic_types[T_PSHORT] = &symt_new_pointer(module, cv_basic_types[T_SHORT], ptrsz)->symt;
+ cv_basic_types[T_PLONG] = &symt_new_pointer(module, cv_basic_types[T_LONG], ptrsz)->symt;
+ cv_basic_types[T_PQUAD] = &symt_new_pointer(module, cv_basic_types[T_QUAD], ptrsz)->symt;
+ cv_basic_types[T_PUCHAR] = &symt_new_pointer(module, cv_basic_types[T_UCHAR], ptrsz)->symt;
+ cv_basic_types[T_PUSHORT] = &symt_new_pointer(module, cv_basic_types[T_USHORT], ptrsz)->symt;
+ cv_basic_types[T_PULONG] = &symt_new_pointer(module, cv_basic_types[T_ULONG], ptrsz)->symt;
+ cv_basic_types[T_PUQUAD] = &symt_new_pointer(module, cv_basic_types[T_UQUAD], ptrsz)->symt;
+ cv_basic_types[T_PBOOL08] = &symt_new_pointer(module, cv_basic_types[T_BOOL08], ptrsz)->symt;
+ cv_basic_types[T_PBOOL16] = &symt_new_pointer(module, cv_basic_types[T_BOOL16], ptrsz)->symt;
+ cv_basic_types[T_PBOOL32] = &symt_new_pointer(module, cv_basic_types[T_BOOL32], ptrsz)->symt;
+ cv_basic_types[T_PBOOL64] = &symt_new_pointer(module, cv_basic_types[T_BOOL64], ptrsz)->symt;
+ cv_basic_types[T_PREAL32] = &symt_new_pointer(module, cv_basic_types[T_REAL32], ptrsz)->symt;
+ cv_basic_types[T_PREAL64] = &symt_new_pointer(module, cv_basic_types[T_REAL64], ptrsz)->symt;
+ cv_basic_types[T_PREAL80] = &symt_new_pointer(module, cv_basic_types[T_REAL80], ptrsz)->symt;
+ cv_basic_types[T_PRCHAR] = &symt_new_pointer(module, cv_basic_types[T_RCHAR], ptrsz)->symt;
+ cv_basic_types[T_PWCHAR] = &symt_new_pointer(module, cv_basic_types[T_WCHAR], ptrsz)->symt;
+ cv_basic_types[T_PCHAR16] = &symt_new_pointer(module, cv_basic_types[T_CHAR16], ptrsz)->symt;
+ cv_basic_types[T_PCHAR32] = &symt_new_pointer(module, cv_basic_types[T_CHAR32], ptrsz)->symt;
+ cv_basic_types[T_PINT2] = &symt_new_pointer(module, cv_basic_types[T_INT2], ptrsz)->symt;
+ cv_basic_types[T_PUINT2] = &symt_new_pointer(module, cv_basic_types[T_UINT2], ptrsz)->symt;
+ cv_basic_types[T_PINT4] = &symt_new_pointer(module, cv_basic_types[T_INT4], ptrsz)->symt;
+ cv_basic_types[T_PUINT4] = &symt_new_pointer(module, cv_basic_types[T_UINT4], ptrsz)->symt;
+ cv_basic_types[T_PINT8] = &symt_new_pointer(module, cv_basic_types[T_INT8], ptrsz)->symt;
+ cv_basic_types[T_PUINT8] = &symt_new_pointer(module, cv_basic_types[T_UINT8], ptrsz)->symt;
}
static int leaf_as_variant(VARIANT* v, const unsigned short int* leaf)
@@ -659,7 +661,7 @@ static struct symt* codeview_add_type_pointer(struct codeview_type_parse* ctp,
return existing;
}
pointee = codeview_fetch_type(ctp, pointee_type, FALSE);
- return &symt_new_pointer(ctp->module, pointee, sizeof(void *))->symt;
+ return &symt_new_pointer(ctp->module, pointee, ctp->module->cpu->word_size)->symt;
}
static struct symt* codeview_add_type_array(struct codeview_type_parse* ctp,
diff --git a/dlls/dbghelp/stabs.c b/dlls/dbghelp/stabs.c
index 647a71ec258..f2b3e6d5c7d 100644
--- a/dlls/dbghelp/stabs.c
+++ b/dlls/dbghelp/stabs.c
@@ -804,7 +804,7 @@ static int stabs_pts_read_type_def(struct ParseTypedefData* ptd, const char* typ
case '*':
case '&':
PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &ref_dt) == -1);
- new_dt = &symt_new_pointer(ptd->module, ref_dt, sizeof(void*))->symt;
+ new_dt = &symt_new_pointer(ptd->module, ref_dt, ptd->module->cpu->word_size)->symt;
break;
case 'k': /* 'const' modifier */
case 'B': /* 'volatile' modifier */
Nov. 8, 2021
[PATCH 03/13] dbghelp: attach a struct cpu* to every module
by Eric Pouech
Signed-off-by: Eric Pouech <eric.pouech(a)gmail.com>
---
dlls/dbghelp/dbghelp_private.h | 3 +++
dlls/dbghelp/module.c | 3 +++
2 files changed, 6 insertions(+)
diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h
index 61173b34b5a..1e77ed49225 100644
--- a/dlls/dbghelp/dbghelp_private.h
+++ b/dlls/dbghelp/dbghelp_private.h
@@ -430,6 +430,8 @@ struct module_format
} u;
};
+struct cpu;
+
struct module
{
struct process* process;
@@ -438,6 +440,7 @@ struct module
struct module* next;
enum module_type type : 16;
unsigned short is_virtual : 1;
+ struct cpu* cpu;
DWORD64 reloc_delta;
WCHAR* real_path;
diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c
index 8168e727c52..65bdbb38fda 100644
--- a/dlls/dbghelp/module.c
+++ b/dlls/dbghelp/module.c
@@ -230,6 +230,9 @@ struct module* module_new(struct process* pcs, const WCHAR* name,
module->addr_sorttab = NULL;
module->num_sorttab = 0;
module->num_symbols = 0;
+ module->cpu = cpu_find(machine);
+ if (!module->cpu)
+ module->cpu = dbghelp_current_cpu;
vector_init(&module->vsymt, sizeof(struct symt*), 128);
vector_init(&module->vcustom_symt, sizeof(struct symt*), 16);
Nov. 8, 2021
[PATCH 02/13] dbghelp: check that we don't add same line number twice
by Eric Pouech
This happens (at least) in dwarf debug info where there could be two entries
with same source file and line number, but different column numbers
(and we don't store columns)
Signed-off-by: Eric Pouech <eric.pouech(a)gmail.com>
---
dlls/dbghelp/symbol.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c
index 7747aaae2ae..435d94bc8eb 100644
--- a/dlls/dbghelp/symbol.c
+++ b/dlls/dbghelp/symbol.c
@@ -418,6 +418,11 @@ void symt_add_func_line(struct module* module, struct symt_function* func,
}
vlen = vector_length(&func->vlines);
prev = vlen ? vector_at(&func->vlines, vlen - 1) : NULL;
+ if (last_matches && prev && addr == prev->u.address)
+ {
+ WARN("Duplicate addition of line number in %s\n", func->hash_elt.name);
+ return;
+ }
if (!last_matches)
{
/* we shouldn't have line changes on first line of function */
Nov. 8, 2021
[PATCH 01/13] tools/winedump/pdb: fix computation of signed integers in codeview symbol's annotations
by Eric Pouech
Signed-off-by: Eric Pouech <eric.pouech(a)gmail.com>
---
tools/winedump/msc.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c
index 79dd022a088..40daf4d50d5 100644
--- a/tools/winedump/msc.c
+++ b/tools/winedump/msc.c
@@ -1221,6 +1221,11 @@ static unsigned binannot_uncompress(const unsigned char** pptr)
return res;
}
+static inline int binannot_getsigned(unsigned i)
+{
+ return (i & 1) ? -(int)(i >> 1) : (i >> 1);
+}
+
static void dump_binannot(const unsigned char* ba, const char* last, const char* pfx)
{
while (ba < (const unsigned char*)last)
@@ -1248,7 +1253,7 @@ static void dump_binannot(const unsigned char* ba, const char* last, const char*
printf("%sChangeFile %u\n", pfx, binannot_uncompress(&ba));
break;
case BA_OP_ChangeLineOffset:
- printf("%sChangeLineOffset %d\n", pfx, binannot_uncompress(&ba));
+ printf("%sChangeLineOffset %d\n", pfx, binannot_getsigned(binannot_uncompress(&ba)));
break;
case BA_OP_ChangeLineEndDelta:
printf("%sChangeLineEndDelta %u\n", pfx, binannot_uncompress(&ba));
@@ -1265,7 +1270,7 @@ static void dump_binannot(const unsigned char* ba, const char* last, const char*
case BA_OP_ChangeCodeOffsetAndLineOffset:
{
unsigned p1 = binannot_uncompress(&ba);
- printf("%sChangeCodeOffsetAndLineOffset %u %u (0x%x)\n", pfx, p1 & 0xf, p1 >> 4, p1);
+ printf("%sChangeCodeOffsetAndLineOffset %u %u (0x%x)\n", pfx, p1 & 0xf, binannot_getsigned(p1 >> 4), p1);
}
break;
case BA_OP_ChangeCodeLengthAndCodeOffset:
Nov. 8, 2021
[PATCH 00/13] Series short description
by Eric Pouech
The following series:
- replace quite a few uses of debugger's CPU with debuggee's one
(of interest for WoW64 debugging where they're different)
- support more pdb entries (inline sites, new local variable information)
A+
---
Eric Pouech (13):
tools/winedump/pdb: fix computation of signed integers in codeview symbol's annotations
dbghelp: check that we don't add same line number twice
dbghelp: attach a struct cpu* to every module
dbghelp: use module's cpu word size instead of sizeof(void*) or sizeof(DWORD_PTR)
dbghelp: rather use cpu from debuggee's modules than debugger's
dbghelp/pdb: added new basic type to represent char8_t introduced in C++20
dbghelp/pdb: properly handle S_LOCAL codeview entries
dbghelp/pdb: implement loc_compute for pdb backend
dbghelp/pdb: introduce codeview_init_type_parse() to handle init of type streams
dbghelp/pdb: let codeview_snarf() handle all module debug information
dbghelp/pdb: added support for inline sites
dbghelp/pdb: handle when a block in DEBUG_S_LINES subsection spreads across several symbols
dbghelp/pdb: add line number to inline sites
dlls/dbghelp/dbghelp_private.h | 3 +
dlls/dbghelp/dwarf.c | 57 ++-
dlls/dbghelp/module.c | 9 +-
dlls/dbghelp/msc.c | 812 ++++++++++++++++++++++++++++-----
dlls/dbghelp/stabs.c | 6 +-
dlls/dbghelp/symbol.c | 5 +
include/cvconst.h | 3 +-
include/wine/mscvpdb.h | 13 +-
tools/winedump/msc.c | 9 +-
9 files changed, 755 insertions(+), 162 deletions(-)
Nov. 8, 2021
[PATCH vkd3d 3/3] vkd3d-shader/spirv: Ignore break instructions outside active blocks.
by Henri Verbeet
From: Philip Rebohle <philip.rebohle(a)tu-dortmund.de>
Signed-off-by: Conor McCarthy <cmccarthy(a)codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
v2: Minor adjustments to the commit message and comment.
libs/vkd3d-shader/spirv.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index e5b9ef03..698c3054 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -7802,8 +7802,10 @@ static int vkd3d_dxbc_compiler_emit_control_flow_instruction(struct vkd3d_dxbc_c
}
else if (breakable_cf_info->current_block == VKD3D_BLOCK_SWITCH)
{
- assert(breakable_cf_info->inside_block);
- vkd3d_spirv_build_op_branch(builder, breakable_cf_info->u.switch_.merge_block_id);
+ /* The current case block may have already been ended by an
+ * unconditional continue instruction. */
+ if (breakable_cf_info->inside_block)
+ vkd3d_spirv_build_op_branch(builder, breakable_cf_info->u.switch_.merge_block_id);
}
cf_info->inside_block = false;
--
2.20.1
Nov. 8, 2021
[PATCH vkd3d 2/3] tests: Add a test for an unconditional break instruction at the end of a loop block.
by Henri Verbeet
From: Conor McCarthy <cmccarthy(a)codeweavers.com>
Signed-off-by: Conor McCarthy <cmccarthy(a)codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
v2: Move the test after the corresponding fix.
tests/d3d12.c | 41 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/tests/d3d12.c b/tests/d3d12.c
index d69b151a..8071faf0 100644
--- a/tests/d3d12.c
+++ b/tests/d3d12.c
@@ -7919,6 +7919,45 @@ static void test_shader_instructions(void)
0x00000000, 0x0100003e,
};
static struct named_shader ps_loop_break = {"loop_break", ps_loop_break_code, sizeof(ps_loop_break_code)};
+ static const DWORD ps_loop_end_break_code[] =
+ {
+#if 0
+ float4 src0;
+
+ void main(out float4 dst : SV_Target)
+ {
+ float tmp = 0.0f;
+ for (int i = 0; i < src0.x; ++i)
+ {
+ if (i != src0.y)
+ {
+ tmp += 1.0f;
+ continue;
+ }
+ tmp = 1.0f;
+ break;
+ }
+
+ dst = float4(tmp, 0, 0, 0);
+ }
+#endif
+ 0x43425844, 0x0239f900, 0x5b94f73f, 0x68b75aa3, 0x27d353d2, 0x00000001, 0x000001e0, 0x00000003,
+ 0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
+ 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
+ 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000168, 0x00000050, 0x0000005a,
+ 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
+ 0x02000068, 0x00000001, 0x08000036, 0x00100032, 0x00000000, 0x00004002, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x01000030, 0x0500002b, 0x00100042, 0x00000000, 0x0010001a, 0x00000000,
+ 0x0800001d, 0x00100082, 0x00000000, 0x0010002a, 0x00000000, 0x0020800a, 0x00000000, 0x00000000,
+ 0x03040003, 0x0010003a, 0x00000000, 0x08000039, 0x00100042, 0x00000000, 0x0010002a, 0x00000000,
+ 0x0020801a, 0x00000000, 0x00000000, 0x0304001f, 0x0010002a, 0x00000000, 0x07000000, 0x00100012,
+ 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x3f800000, 0x0700001e, 0x00100042, 0x00000000,
+ 0x0010001a, 0x00000000, 0x00004001, 0x00000001, 0x05000036, 0x00100032, 0x00000000, 0x00100086,
+ 0x00000000, 0x01000007, 0x01000015, 0x05000036, 0x00100012, 0x00000000, 0x00004001, 0x3f800000,
+ 0x01000002, 0x01000016, 0x05000036, 0x00102012, 0x00000000, 0x0010000a, 0x00000000, 0x08000036,
+ 0x001020e2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0100003e,
+ };
+ static struct named_shader ps_loop_end_break = {"loop_end_break", ps_loop_end_break_code, sizeof(ps_loop_end_break_code)};
static const DWORD ps_loop_ret_code[] =
{
#if 0
@@ -9730,6 +9769,8 @@ static void test_shader_instructions(void)
{&ps_loop_break, {{7.0f, 8.0f}}, {{7.0f}}},
{&ps_loop_break, {{7.0f, 9.0f}}, {{7.0f}}},
+ {&ps_loop_end_break, {{7.0f, 2.0f}}, {{1.0f}}},
+
{&ps_loop_ret, {{0.0f, 0.0f}}, {{0.0f}}},
{&ps_loop_ret, {{1.0f, 9.0f}}, {{1.0f}}},
{&ps_loop_ret, {{2.0f, 2.0f}}, {{2.0f}}},
--
2.20.1
Nov. 8, 2021