Commit 16bcc3bc authored by eric pouech's avatar eric pouech Committed by Alexandre Julliard
Browse files

winedbg: Synthetize pointer to type when not available.



This ensures that we always have a type as pointer to a known <type>
(either because it exists in <type>'s module, or it's synthetized inside
debugger).

Signed-off-by: eric pouech's avatarEric Pouech <eric.pouech@gmail.com>
parent dd977e4a
Pipeline #854 skipped
...@@ -67,6 +67,8 @@ enum dbg_line_status ...@@ -67,6 +67,8 @@ enum dbg_line_status
enum dbg_internal_types enum dbg_internal_types
{ {
/* types that we synthetize inside the debugger */
dbg_itype_synthetized = 0xf0000000,
/* order here must match types.c:basic_types_details table */ /* order here must match types.c:basic_types_details table */
dbg_itype_first = 0xffffff00, dbg_itype_first = 0xffffff00,
dbg_itype_void = dbg_itype_first, dbg_itype_void = dbg_itype_first,
...@@ -282,6 +284,8 @@ struct dbg_process ...@@ -282,6 +284,8 @@ struct dbg_process
int source_start_line; int source_start_line;
int source_end_line; int source_end_line;
const struct data_model* data_model; const struct data_model* data_model;
struct dbg_type* synthetized_types;
unsigned num_synthetized_types;
}; };
/* describes the way the debugger interacts with a given process */ /* describes the way the debugger interacts with a given process */
...@@ -499,6 +503,7 @@ extern BOOL types_is_integral_type(const struct dbg_lvalue*); ...@@ -499,6 +503,7 @@ extern BOOL types_is_integral_type(const struct dbg_lvalue*);
extern BOOL types_is_float_type(const struct dbg_lvalue*); extern BOOL types_is_float_type(const struct dbg_lvalue*);
extern BOOL types_is_pointer_type(const struct dbg_lvalue*); extern BOOL types_is_pointer_type(const struct dbg_lvalue*);
extern BOOL types_find_basic(const WCHAR*, const char*, struct dbg_type* type); extern BOOL types_find_basic(const WCHAR*, const char*, struct dbg_type* type);
extern BOOL types_unload_module(DWORD_PTR linear);
/* winedbg.c */ /* winedbg.c */
#ifdef __GNUC__ #ifdef __GNUC__
......
...@@ -500,6 +500,7 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de) ...@@ -500,6 +500,7 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de)
de->dwProcessId, de->dwThreadId, de->dwProcessId, de->dwThreadId,
de->u.UnloadDll.lpBaseOfDll); de->u.UnloadDll.lpBaseOfDll);
break_delete_xpoints_from_module((DWORD_PTR)de->u.UnloadDll.lpBaseOfDll); break_delete_xpoints_from_module((DWORD_PTR)de->u.UnloadDll.lpBaseOfDll);
types_unload_module((DWORD_PTR)de->u.UnloadDll.lpBaseOfDll);
SymUnloadModule64(dbg_curr_process->handle, (DWORD_PTR)de->u.UnloadDll.lpBaseOfDll); SymUnloadModule64(dbg_curr_process->handle, (DWORD_PTR)de->u.UnloadDll.lpBaseOfDll);
break; break;
......
...@@ -371,19 +371,56 @@ static BOOL CALLBACK types_cb(PSYMBOL_INFO sym, ULONG size, void* _user) ...@@ -371,19 +371,56 @@ static BOOL CALLBACK types_cb(PSYMBOL_INFO sym, ULONG size, void* _user)
/****************************************************************** /******************************************************************
* types_find_pointer * types_find_pointer
* *
* Should look up in module based at linear whether (typeid*) exists * There's no simple API in dbghelp for looking up the pointer type of a given type
* Otherwise, we could create it locally * - SymEnumTypes would do, but it'll enumerate all types, which could be long
* - and more impacting, there's no guarantee such a type exists
* Hence, we synthetize inside Winedbg all needed pointer types.
* That's cumbersome as we end up with dbg_type in different modules between pointer
* and pointee types.
*/ */
BOOL types_find_pointer(const struct dbg_type* type, struct dbg_type* outtype) BOOL types_find_pointer(const struct dbg_type* type, struct dbg_type* outtype)
{ {
struct type_find_t f; struct type_find_t f;
unsigned i;
struct dbg_type* new;
if (!dbg_curr_process) return FALSE;
/* first lookup if pointer to type exists in module */
f.type.id = dbg_itype_none; f.type.id = dbg_itype_none;
f.tag = SymTagPointerType; f.tag = SymTagPointerType;
f.ptr_typeid = type->id; f.ptr_typeid = type->id;
if (!SymEnumTypes(dbg_curr_process->handle, type->module, types_cb, &f) || f.type.id == dbg_itype_none) SymEnumTypes(dbg_curr_process->handle, type->module, types_cb, &f);
if (f.type.id != dbg_itype_none)
{
*outtype = f.type;
return TRUE;
}
/* then look up in synthetized types */
for (i = 0; i < dbg_curr_process->num_synthetized_types; i++)
if (!memcmp(type, &dbg_curr_process->synthetized_types[i], sizeof(*type)))
{
outtype->module = 0;
outtype->id = dbg_itype_synthetized + i;
return TRUE;
}
if (dbg_itype_synthetized + dbg_curr_process->num_synthetized_types >= dbg_itype_first)
{
/* for now, we don't reuse old slots... */
FIXME("overflow in pointer types\n");
return FALSE; return FALSE;
*outtype = f.type; }
/* otherwise, synthetize it */
new = realloc(dbg_curr_process->synthetized_types,
(dbg_curr_process->num_synthetized_types + 1) * sizeof(*new));
if (!new) return FALSE;
dbg_curr_process->synthetized_types = new;
dbg_curr_process->synthetized_types[dbg_curr_process->num_synthetized_types] = *type;
outtype->module = 0;
outtype->id = dbg_itype_synthetized + dbg_curr_process->num_synthetized_types;
dbg_curr_process->num_synthetized_types++;
return TRUE; return TRUE;
} }
...@@ -1041,6 +1078,7 @@ static BOOL lookup_base_type_in_data_model(DWORD64 module, unsigned bt, unsigned ...@@ -1041,6 +1078,7 @@ static BOOL lookup_base_type_in_data_model(DWORD64 module, unsigned bt, unsigned
* - module & type id on input are in dbg_type structure * - module & type id on input are in dbg_type structure
* - for TI_GET_TYPE a pointer to a dbg_type is expected for pInfo * - for TI_GET_TYPE a pointer to a dbg_type is expected for pInfo
* (instead of DWORD* for SymGetTypeInfo) * (instead of DWORD* for SymGetTypeInfo)
* - handles also internal types, and synthetized types.
*/ */
BOOL types_get_info(const struct dbg_type* type, IMAGEHLP_SYMBOL_TYPE_INFO ti, void* pInfo) BOOL types_get_info(const struct dbg_type* type, IMAGEHLP_SYMBOL_TYPE_INFO ti, void* pInfo)
{ {
...@@ -1074,6 +1112,24 @@ BOOL types_get_info(const struct dbg_type* type, IMAGEHLP_SYMBOL_TYPE_INFO ti, v ...@@ -1074,6 +1112,24 @@ BOOL types_get_info(const struct dbg_type* type, IMAGEHLP_SYMBOL_TYPE_INFO ti, v
return SymGetTypeInfo(dbg_curr_process->handle, type->module, type->id, ti, pInfo); return SymGetTypeInfo(dbg_curr_process->handle, type->module, type->id, ti, pInfo);
} }
if (type->id >= dbg_itype_synthetized && type->id < dbg_itype_first)
{
unsigned i = type->id - dbg_itype_synthetized;
if (i >= dbg_curr_process->num_synthetized_types) return FALSE;
switch (ti)
{
case TI_GET_SYMTAG: X(DWORD) = SymTagPointerType; break;
case TI_GET_LENGTH: X(DWORD64) = ADDRSIZE; break;
case TI_GET_TYPE: if (dbg_curr_process->synthetized_types[i].module == 0 &&
dbg_curr_process->synthetized_types[i].id == dbg_itype_none) return FALSE;
X(struct dbg_type) = dbg_curr_process->synthetized_types[i];
break;
default: WINE_FIXME("unsupported %u for pointer type %d\n", ti, i); return FALSE;
}
return TRUE;
}
assert(type->id >= dbg_itype_first); assert(type->id >= dbg_itype_first);
if (type->id >= dbg_itype_first && type->id < dbg_itype_last) if (type->id >= dbg_itype_first && type->id < dbg_itype_last)
...@@ -1143,6 +1199,21 @@ BOOL types_get_info(const struct dbg_type* type, IMAGEHLP_SYMBOL_TYPE_INFO ti, v ...@@ -1143,6 +1199,21 @@ BOOL types_get_info(const struct dbg_type* type, IMAGEHLP_SYMBOL_TYPE_INFO ti, v
return TRUE; return TRUE;
} }
BOOL types_unload_module(DWORD_PTR linear)
{
unsigned i;
if (!dbg_curr_process) return FALSE;
for (i = 0; i < dbg_curr_process->num_synthetized_types; i++)
{
if (dbg_curr_process->synthetized_types[i].module == linear)
{
dbg_curr_process->synthetized_types[i].module = 0;
dbg_curr_process->synthetized_types[i].id = dbg_itype_none;
}
}
return TRUE;
}
static BOOL types_compare_name(struct dbg_type type1, struct dbg_type type2, BOOL* equal) static BOOL types_compare_name(struct dbg_type type1, struct dbg_type type2, BOOL* equal)
{ {
LPWSTR name1, name2; LPWSTR name1, name2;
...@@ -1299,7 +1370,7 @@ BOOL types_is_integral_type(const struct dbg_lvalue* lv) ...@@ -1299,7 +1370,7 @@ BOOL types_is_integral_type(const struct dbg_lvalue* lv)
struct dbg_type type = lv->type; struct dbg_type type = lv->type;
DWORD tag, bt; DWORD tag, bt;
if (lv->bitlen) return TRUE; if (lv->bitlen) return TRUE;
if (!types_get_real_type(&type, &tag) || if (!types_get_real_type(&type, &tag) || tag != SymTagBaseType ||
!types_get_info(&type, TI_GET_BASETYPE, &bt)) return FALSE; !types_get_info(&type, TI_GET_BASETYPE, &bt)) return FALSE;
return is_basetype_integer(bt); return is_basetype_integer(bt);
} }
...@@ -1309,7 +1380,7 @@ BOOL types_is_float_type(const struct dbg_lvalue* lv) ...@@ -1309,7 +1380,7 @@ BOOL types_is_float_type(const struct dbg_lvalue* lv)
struct dbg_type type = lv->type; struct dbg_type type = lv->type;
DWORD tag, bt; DWORD tag, bt;
if (lv->bitlen) return FALSE; if (lv->bitlen) return FALSE;
if (!types_get_real_type(&type, &tag) || if (!types_get_real_type(&type, &tag) || tag != SymTagBaseType ||
!types_get_info(&type, TI_GET_BASETYPE, &bt)) return FALSE; !types_get_info(&type, TI_GET_BASETYPE, &bt)) return FALSE;
return bt == btFloat; return bt == btFloat;
} }
......
...@@ -285,6 +285,8 @@ struct dbg_process* dbg_add_process(const struct be_process_io* pio, DWORD pid, ...@@ -285,6 +285,8 @@ struct dbg_process* dbg_add_process(const struct be_process_io* pio, DWORD pid,
p->source_start_line = -1; p->source_start_line = -1;
p->source_end_line = -1; p->source_end_line = -1;
p->data_model = NULL; p->data_model = NULL;
p->synthetized_types = NULL;
p->num_synthetized_types = 0;
list_add_head(&dbg_process_list, &p->entry); list_add_head(&dbg_process_list, &p->entry);
...@@ -330,6 +332,7 @@ void dbg_del_process(struct dbg_process* p) ...@@ -330,6 +332,7 @@ void dbg_del_process(struct dbg_process* p)
if (p == dbg_curr_process) dbg_curr_process = NULL; if (p == dbg_curr_process) dbg_curr_process = NULL;
if (p->event_on_first_exception) CloseHandle(p->event_on_first_exception); if (p->event_on_first_exception) CloseHandle(p->event_on_first_exception);
free((char*)p->imageName); free((char*)p->imageName);
free(p->synthetized_types);
free(p); free(p);
} }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment