From 2becd3349de5d7b4f1f1a428e5bc08294ba0f8a6 Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Mon, 12 Apr 2010 21:18:25 +0200 Subject: [PATCH] winedbg: Merge pointer deref and array index functions into a single one. --- programs/winedbg/debugger.h | 1 - programs/winedbg/expr.c | 4 +- programs/winedbg/memory.c | 2 +- programs/winedbg/types.c | 86 ++++++++++++++++--------------------- programs/winedbg/winedbg.c | 2 - 5 files changed, 40 insertions(+), 55 deletions(-) diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h index b38d6bdf37e..bb3c131b242 100644 --- a/programs/winedbg/debugger.h +++ b/programs/winedbg/debugger.h @@ -434,7 +434,6 @@ extern int print_types(void); extern long int types_extract_as_integer(const struct dbg_lvalue*); extern LONGLONG types_extract_as_longlong(const struct dbg_lvalue*, unsigned* psize); extern void types_extract_as_address(const struct dbg_lvalue*, ADDRESS64*); -extern BOOL types_deref(const struct dbg_lvalue* value, struct dbg_lvalue* result); extern BOOL types_udt_find_element(struct dbg_lvalue* value, const char* name, long int* tmpbuf); extern BOOL types_array_index(const struct dbg_lvalue* value, int index, struct dbg_lvalue* result); extern BOOL types_get_info(const struct dbg_type*, IMAGEHLP_SYMBOL_TYPE_INFO, void*); diff --git a/programs/winedbg/expr.c b/programs/winedbg/expr.c index 6b8c46fc173..66cd701c640 100644 --- a/programs/winedbg/expr.c +++ b/programs/winedbg/expr.c @@ -375,7 +375,7 @@ struct dbg_lvalue expr_eval(struct expr* exp) break; case EXPR_TYPE_PSTRUCT: exp1 = expr_eval(exp->un.structure.exp1); - if (exp1.type.id == dbg_itype_none || !types_deref(&exp1, &rtn) || + if (exp1.type.id == dbg_itype_none || !types_array_index(&exp1, 0, &rtn) || rtn.type.id == dbg_itype_none) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL); if (!types_udt_find_element(&rtn, exp->un.structure.element_name, @@ -626,7 +626,7 @@ struct dbg_lvalue expr_eval(struct expr* exp) exp->un.unop.result = ~types_extract_as_integer(&exp1); break; case EXP_OP_DEREF: - if (!types_deref(&exp1, &rtn)) + if (!types_array_index(&exp1, 0, &rtn)) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL); break; case EXP_OP_FORCE_DEREF: diff --git a/programs/winedbg/memory.c b/programs/winedbg/memory.c index 76a103a0c5c..65600628fbb 100644 --- a/programs/winedbg/memory.c +++ b/programs/winedbg/memory.c @@ -416,7 +416,7 @@ static void print_typed_basic(const struct dbg_lvalue* lvalue) } break; case SymTagPointerType: - if (!types_deref(lvalue, &sub_lvalue)) + if (!types_array_index(lvalue, 0, &sub_lvalue)) { dbg_printf("Internal symbol error: unable to access memory location %p", memory_to_linear_addr(&lvalue->addr)); diff --git a/programs/winedbg/types.c b/programs/winedbg/types.c index 414bb9f55c9..6d50c81598a 100644 --- a/programs/winedbg/types.c +++ b/programs/winedbg/types.c @@ -154,45 +154,6 @@ void types_extract_as_address(const struct dbg_lvalue* lvalue, ADDRESS64* addr) } } -/****************************************************************** - * types_deref - * - */ -BOOL types_deref(const struct dbg_lvalue* lvalue, struct dbg_lvalue* result) -{ - struct dbg_type type = lvalue->type; - DWORD tag; - - memset(result, 0, sizeof(*result)); - result->type.id = dbg_itype_none; - result->type.module = 0; - - /* - * Make sure that this really makes sense. - */ - if (!types_get_real_type(&type, &tag) || tag != SymTagPointerType || - !memory_read_value(lvalue, sizeof(result->addr.Offset), &result->addr.Offset) || - !types_get_info(&type, TI_GET_TYPE, &result->type.id)) - return FALSE; - result->type.module = type.module; - result->cookie = DLV_TARGET; - /* FIXME: this is currently buggy. - * there is no way to tell were the deref:ed value is... - * for example: - * x is a pointer to struct s, x being on the stack - * => lvalue is in debuggee, result is in debugger - * x is a pointer to struct s, x being optimized into a reg - * => lvalue is debugger, result is debuggee - * x is a pointer to internal variable x - * => lvalue is debugger, result is debuggee - * so we force debuggee address space, because dereferencing pointers to - * internal variables is very unlikely. A correct fix would be - * rather large. - */ - result->addr.Mode = AddrModeFlat; - return TRUE; -} - /****************************************************************** * types_get_udt_element_lvalue * @@ -301,24 +262,32 @@ BOOL types_udt_find_element(struct dbg_lvalue* lvalue, const char* name, long in * * Grab an element from an array */ -BOOL types_array_index(const struct dbg_lvalue* lvalue, int index, - struct dbg_lvalue* result) +BOOL types_array_index(const struct dbg_lvalue* lvalue, int index, struct dbg_lvalue* result) { struct dbg_type type = lvalue->type; DWORD tag, count; - DWORD64 length; + + memset(result, 0, sizeof(*result)); + result->type.id = dbg_itype_none; + result->type.module = 0; if (!types_get_real_type(&type, &tag)) return FALSE; - /* Contents of array share same data (addr mode, module...) */ - *result = *lvalue; switch (tag) { case SymTagArrayType: - types_get_info(&type, TI_GET_COUNT, &count); + if (!types_get_info(&type, TI_GET_COUNT, &count)) return FALSE; if (index < 0 || index >= count) return FALSE; + result->addr = lvalue->addr; break; case SymTagPointerType: - memory_read_value(lvalue, sizeof(result->addr.Offset), &result->addr.Offset); + if (!memory_read_value(lvalue, be_cpu->pointer_size, &result->addr.Offset)) return FALSE; + result->addr.Mode = AddrModeFlat; + switch (be_cpu->pointer_size) + { + case 4: result->addr.Offset = (DWORD)result->addr.Offset; break; + case 8: break; + default: assert(0); + } break; default: assert(FALSE); @@ -326,9 +295,28 @@ BOOL types_array_index(const struct dbg_lvalue* lvalue, int index, /* * Get the base type, so we know how much to index by. */ - types_get_info(&type, TI_GET_TYPE, &result->type.id); - types_get_info(&result->type, TI_GET_LENGTH, &length); - result->addr.Offset += index * (DWORD)length; + if (!types_get_info(&type, TI_GET_TYPE, &result->type.id)) return FALSE; + result->type.module = type.module; + if (index) + { + DWORD64 length; + if (!types_get_info(&result->type, TI_GET_LENGTH, &length)) return FALSE; + result->addr.Offset += index * (DWORD)length; + } + /* FIXME: the following statement is not always true (and can lead to buggy behavior). + * There is no way to tell were the deref:ed value is... + * For example: + * x is a pointer to struct s, x being on the stack + * => lvalue is in debuggee, result is in debugger + * x is a pointer to struct s, x being optimized into a reg + * => lvalue is debugger, result is debuggee + * x is a pointer to internal variable x + * => lvalue is debugger, result is debuggee + * So we always force debuggee address space, because dereferencing pointers to + * internal variables is very unlikely. A correct fix would be + * rather large. + */ + result->cookie = DLV_TARGET; return TRUE; } diff --git a/programs/winedbg/winedbg.c b/programs/winedbg/winedbg.c index 6ce6db447e4..7a37805f4dc 100644 --- a/programs/winedbg/winedbg.c +++ b/programs/winedbg/winedbg.c @@ -55,8 +55,6 @@ * + all computations should be made on long long * o expr computations are in int:s * o bitfield size is on a 4-bytes - * + array_index and deref should be the same function (or should share the same - * core) * - execution: * + set a better fix for gdb (proxy mode) than the step-mode hack * + implement function call in debuggee