mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-31 12:54:13 +00:00
winedbg: Merge pointer deref and array index functions into a single one.
This commit is contained in:
parent
0d7a6f13a8
commit
2becd3349d
5 changed files with 40 additions and 55 deletions
|
@ -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*);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue