mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-14 20:45:47 +00:00
winedbg: Merge pointer deref and array index functions into a single one.
This commit is contained in:
parent
0d7a6f13a8
commit
2becd3349d
|
@ -434,7 +434,6 @@ extern int print_types(void);
|
||||||
extern long int types_extract_as_integer(const struct dbg_lvalue*);
|
extern long int types_extract_as_integer(const struct dbg_lvalue*);
|
||||||
extern LONGLONG types_extract_as_longlong(const struct dbg_lvalue*, unsigned* psize);
|
extern LONGLONG types_extract_as_longlong(const struct dbg_lvalue*, unsigned* psize);
|
||||||
extern void types_extract_as_address(const struct dbg_lvalue*, ADDRESS64*);
|
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_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_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*);
|
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;
|
break;
|
||||||
case EXPR_TYPE_PSTRUCT:
|
case EXPR_TYPE_PSTRUCT:
|
||||||
exp1 = expr_eval(exp->un.structure.exp1);
|
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)
|
rtn.type.id == dbg_itype_none)
|
||||||
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
||||||
if (!types_udt_find_element(&rtn, exp->un.structure.element_name,
|
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);
|
exp->un.unop.result = ~types_extract_as_integer(&exp1);
|
||||||
break;
|
break;
|
||||||
case EXP_OP_DEREF:
|
case EXP_OP_DEREF:
|
||||||
if (!types_deref(&exp1, &rtn))
|
if (!types_array_index(&exp1, 0, &rtn))
|
||||||
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
||||||
break;
|
break;
|
||||||
case EXP_OP_FORCE_DEREF:
|
case EXP_OP_FORCE_DEREF:
|
||||||
|
|
|
@ -416,7 +416,7 @@ static void print_typed_basic(const struct dbg_lvalue* lvalue)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SymTagPointerType:
|
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",
|
dbg_printf("Internal symbol error: unable to access memory location %p",
|
||||||
memory_to_linear_addr(&lvalue->addr));
|
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
|
* 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
|
* Grab an element from an array
|
||||||
*/
|
*/
|
||||||
BOOL types_array_index(const struct dbg_lvalue* lvalue, int index,
|
BOOL types_array_index(const struct dbg_lvalue* lvalue, int index, struct dbg_lvalue* result)
|
||||||
struct dbg_lvalue* result)
|
|
||||||
{
|
{
|
||||||
struct dbg_type type = lvalue->type;
|
struct dbg_type type = lvalue->type;
|
||||||
DWORD tag, count;
|
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;
|
if (!types_get_real_type(&type, &tag)) return FALSE;
|
||||||
/* Contents of array share same data (addr mode, module...) */
|
|
||||||
*result = *lvalue;
|
|
||||||
switch (tag)
|
switch (tag)
|
||||||
{
|
{
|
||||||
case SymTagArrayType:
|
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;
|
if (index < 0 || index >= count) return FALSE;
|
||||||
|
result->addr = lvalue->addr;
|
||||||
break;
|
break;
|
||||||
case SymTagPointerType:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(FALSE);
|
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.
|
* Get the base type, so we know how much to index by.
|
||||||
*/
|
*/
|
||||||
types_get_info(&type, TI_GET_TYPE, &result->type.id);
|
if (!types_get_info(&type, TI_GET_TYPE, &result->type.id)) return FALSE;
|
||||||
types_get_info(&result->type, TI_GET_LENGTH, &length);
|
result->type.module = type.module;
|
||||||
result->addr.Offset += index * (DWORD)length;
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,8 +55,6 @@
|
||||||
* + all computations should be made on long long
|
* + all computations should be made on long long
|
||||||
* o expr computations are in int:s
|
* o expr computations are in int:s
|
||||||
* o bitfield size is on a 4-bytes
|
* o bitfield size is on a 4-bytes
|
||||||
* + array_index and deref should be the same function (or should share the same
|
|
||||||
* core)
|
|
||||||
* - execution:
|
* - execution:
|
||||||
* + set a better fix for gdb (proxy mode) than the step-mode hack
|
* + set a better fix for gdb (proxy mode) than the step-mode hack
|
||||||
* + implement function call in debuggee
|
* + implement function call in debuggee
|
||||||
|
|
Loading…
Reference in a new issue