winedbg: Merge pointer deref and array index functions into a single one.

This commit is contained in:
Eric Pouech 2010-04-12 21:18:25 +02:00 committed by Alexandre Julliard
parent 0d7a6f13a8
commit 2becd3349d
5 changed files with 40 additions and 55 deletions

View File

@ -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*);

View File

@ -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:

View File

@ -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));

View File

@ -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;
}

View File

@ -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