winedbg: Proper handling of typedefs.
Added types_get_real_type() to get rid of typedef information, and access the real underlying type.
This commit is contained in:
parent
cb2e21ffb4
commit
e79085258b
|
@ -392,6 +392,7 @@ extern BOOL types_deref(const struct dbg_lvalue* value, struct dbg_l
|
|||
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*);
|
||||
extern BOOL types_get_real_type(struct dbg_type* type, DWORD* tag);
|
||||
extern struct dbg_type types_find_pointer(const struct dbg_type* type);
|
||||
extern struct dbg_type types_find_type(unsigned long linear, const char* name, enum SymTagEnum tag);
|
||||
|
||||
|
|
|
@ -280,17 +280,16 @@ static void print_typed_basic(const struct dbg_lvalue* lvalue)
|
|||
long double val_real;
|
||||
DWORD64 size64;
|
||||
DWORD tag, size, count, bt;
|
||||
struct dbg_type rtype;
|
||||
struct dbg_type type = lvalue->type;
|
||||
struct dbg_type sub_type;
|
||||
|
||||
if (lvalue->type.id == dbg_itype_none ||
|
||||
!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
|
||||
return;
|
||||
if (!types_get_real_type(&type, &tag)) return;
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
case SymTagBaseType:
|
||||
if (!types_get_info(&lvalue->type, TI_GET_LENGTH, &size64) ||
|
||||
!types_get_info(&lvalue->type, TI_GET_BASETYPE, &bt))
|
||||
if (!types_get_info(&type, TI_GET_LENGTH, &size64) ||
|
||||
!types_get_info(&type, TI_GET_BASETYPE, &bt))
|
||||
{
|
||||
WINE_ERR("Couldn't get information\n");
|
||||
RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
|
||||
|
@ -326,16 +325,18 @@ static void print_typed_basic(const struct dbg_lvalue* lvalue)
|
|||
case SymTagPointerType:
|
||||
if (!memory_read_value(lvalue, sizeof(void*), &val_ptr)) return;
|
||||
|
||||
if (!types_get_info(&lvalue->type, TI_GET_TYPE, &rtype.id) ||
|
||||
rtype.id == dbg_itype_none)
|
||||
sub_type.module = lvalue->type.module;
|
||||
if (!types_get_info(&type, TI_GET_TYPE, &sub_type.id) ||
|
||||
sub_type.id == dbg_itype_none)
|
||||
{
|
||||
dbg_printf("Internal symbol error: unable to access memory location %p", val_ptr);
|
||||
break;
|
||||
}
|
||||
rtype.module = lvalue->type.module;
|
||||
if (types_get_info(&rtype, TI_GET_SYMTAG, &tag) && tag == SymTagBaseType &&
|
||||
types_get_info(&rtype, TI_GET_BASETYPE, &bt) && bt == btChar &&
|
||||
types_get_info(&rtype, TI_GET_LENGTH, &size64))
|
||||
if (!types_get_real_type(&sub_type, &tag)) return;
|
||||
|
||||
if (types_get_info(&sub_type, TI_GET_SYMTAG, &tag) && tag == SymTagBaseType &&
|
||||
types_get_info(&sub_type, TI_GET_BASETYPE, &bt) && bt == btChar &&
|
||||
types_get_info(&sub_type, TI_GET_LENGTH, &size64))
|
||||
{
|
||||
char buffer[1024];
|
||||
|
||||
|
@ -366,7 +367,7 @@ static void print_typed_basic(const struct dbg_lvalue* lvalue)
|
|||
*/
|
||||
if (!be_cpu->fetch_integer(lvalue, 4, TRUE, &val_int)) return;
|
||||
|
||||
if (types_get_info(&lvalue->type, TI_GET_CHILDRENCOUNT, &count))
|
||||
if (types_get_info(&type, TI_GET_CHILDRENCOUNT, &count))
|
||||
{
|
||||
char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
|
||||
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
|
||||
|
@ -374,19 +375,18 @@ static void print_typed_basic(const struct dbg_lvalue* lvalue)
|
|||
char tmp[256];
|
||||
VARIANT variant;
|
||||
int i;
|
||||
struct dbg_type type;
|
||||
|
||||
fcp->Start = 0;
|
||||
while (count)
|
||||
{
|
||||
fcp->Count = min(count, 256);
|
||||
if (types_get_info(&lvalue->type, TI_FINDCHILDREN, fcp))
|
||||
if (types_get_info(&type, TI_FINDCHILDREN, fcp))
|
||||
{
|
||||
type.module = lvalue->type.module;
|
||||
sub_type.module = type.module;
|
||||
for (i = 0; i < min(fcp->Count, count); i++)
|
||||
{
|
||||
type.id = fcp->ChildId[i];
|
||||
if (!types_get_info(&type, TI_GET_VALUE, &variant))
|
||||
sub_type.id = fcp->ChildId[i];
|
||||
if (!types_get_info(&sub_type, TI_GET_VALUE, &variant))
|
||||
continue;
|
||||
switch (variant.n1.n2.vt)
|
||||
{
|
||||
|
@ -396,7 +396,7 @@ static void print_typed_basic(const struct dbg_lvalue* lvalue)
|
|||
if (ok)
|
||||
{
|
||||
ptr = NULL;
|
||||
types_get_info(&type, TI_GET_SYMNAME, &ptr);
|
||||
types_get_info(&sub_type, TI_GET_SYMNAME, &ptr);
|
||||
if (!ptr) continue;
|
||||
WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
|
||||
HeapFree(GetProcessHeap(), 0, ptr);
|
||||
|
|
|
@ -29,6 +29,24 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
|
||||
|
||||
/******************************************************************
|
||||
* types_get_real_type
|
||||
*
|
||||
* Get rid of any potential typedef in the lvalue's type to get
|
||||
* to the 'real' type (the one we can work upon).
|
||||
*/
|
||||
BOOL types_get_real_type(struct dbg_type* type, DWORD* tag)
|
||||
{
|
||||
if (type->id == dbg_itype_none) return FALSE;
|
||||
do
|
||||
{
|
||||
if (!types_get_info(type, TI_GET_SYMTAG, tag))
|
||||
return FALSE;
|
||||
if (*tag != SymTagTypedef) return TRUE;
|
||||
} while (types_get_info(type, TI_GET_TYPE, &type->id));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* types_extract_as_integer
|
||||
*
|
||||
|
@ -41,12 +59,12 @@ long int types_extract_as_integer(const struct dbg_lvalue* lvalue)
|
|||
LONGLONG val;
|
||||
DWORD tag, bt;
|
||||
DWORD64 size;
|
||||
struct dbg_type type = lvalue->type;
|
||||
|
||||
if (lvalue->type.id == dbg_itype_none ||
|
||||
!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
|
||||
if (!types_get_real_type(&type, &tag))
|
||||
RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL);
|
||||
|
||||
if (lvalue->type.id == dbg_itype_segptr)
|
||||
if (type.id == dbg_itype_segptr)
|
||||
{
|
||||
return (long int)memory_to_linear_addr(&lvalue->addr);
|
||||
}
|
||||
|
@ -54,8 +72,8 @@ long int types_extract_as_integer(const struct dbg_lvalue* lvalue)
|
|||
switch (tag)
|
||||
{
|
||||
case SymTagBaseType:
|
||||
if (!types_get_info(&lvalue->type, TI_GET_LENGTH, &size) ||
|
||||
!types_get_info(&lvalue->type, TI_GET_BASETYPE, &bt))
|
||||
if (!types_get_info(&type, TI_GET_LENGTH, &size) ||
|
||||
!types_get_info(&type, TI_GET_BASETYPE, &bt))
|
||||
{
|
||||
WINE_ERR("Couldn't get information\n");
|
||||
RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
|
||||
|
@ -133,7 +151,8 @@ void types_extract_as_address(const struct dbg_lvalue* lvalue, ADDRESS* addr)
|
|||
*/
|
||||
BOOL types_deref(const struct dbg_lvalue* lvalue, struct dbg_lvalue* result)
|
||||
{
|
||||
DWORD tag;
|
||||
struct dbg_type type = lvalue->type;
|
||||
DWORD tag;
|
||||
|
||||
memset(result, 0, sizeof(*result));
|
||||
result->type.id = dbg_itype_none;
|
||||
|
@ -142,12 +161,11 @@ BOOL types_deref(const struct dbg_lvalue* lvalue, struct dbg_lvalue* result)
|
|||
/*
|
||||
* Make sure that this really makes sense.
|
||||
*/
|
||||
if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag) ||
|
||||
tag != SymTagPointerType ||
|
||||
if (!types_get_real_type(&type, &tag) || tag != SymTagPointerType ||
|
||||
!memory_read_value(lvalue, sizeof(result->addr.Offset), &result->addr.Offset) ||
|
||||
!types_get_info(&lvalue->type, TI_GET_TYPE, &result->type.id))
|
||||
!types_get_info(&type, TI_GET_TYPE, &result->type.id))
|
||||
return FALSE;
|
||||
result->type.module = lvalue->type.module;
|
||||
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...
|
||||
|
@ -219,7 +237,6 @@ static BOOL types_get_udt_element_lvalue(struct dbg_lvalue* lvalue,
|
|||
else
|
||||
{
|
||||
if (!memory_read_value(lvalue, sizeof(*tmpbuf), tmpbuf)) return FALSE;
|
||||
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -279,15 +296,15 @@ BOOL types_udt_find_element(struct dbg_lvalue* lvalue, const char* name, long in
|
|||
BOOL types_array_index(const struct dbg_lvalue* lvalue, int index,
|
||||
struct dbg_lvalue* result)
|
||||
{
|
||||
DWORD tag, count;
|
||||
DWORD64 length;
|
||||
struct dbg_type type = lvalue->type;
|
||||
DWORD tag, count;
|
||||
DWORD64 length;
|
||||
|
||||
if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
|
||||
return FALSE;
|
||||
if (!types_get_real_type(&type, &tag)) return FALSE;
|
||||
switch (tag)
|
||||
{
|
||||
case SymTagArrayType:
|
||||
types_get_info(&lvalue->type, TI_GET_COUNT, &count);
|
||||
types_get_info(&type, TI_GET_COUNT, &count);
|
||||
if (index < 0 || index >= count) return FALSE;
|
||||
/* fall through */
|
||||
case SymTagPointerType:
|
||||
|
@ -296,7 +313,7 @@ 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(&lvalue->type, TI_GET_TYPE, &result->type.id);
|
||||
types_get_info(&type, TI_GET_TYPE, &result->type.id);
|
||||
types_get_info(&result->type, TI_GET_LENGTH, &length);
|
||||
memory_read_value(lvalue, sizeof(result->addr.Offset), &result->addr.Offset);
|
||||
result->addr.Offset += index * (DWORD)length;
|
||||
|
@ -399,13 +416,20 @@ struct dbg_type types_find_type(unsigned long linear, const char* name, enum Sym
|
|||
*/
|
||||
void print_value(const struct dbg_lvalue* lvalue, char format, int level)
|
||||
{
|
||||
struct dbg_type type = lvalue->type;
|
||||
struct dbg_lvalue lvalue_field;
|
||||
int i;
|
||||
DWORD tag;
|
||||
DWORD count;
|
||||
DWORD64 size;
|
||||
|
||||
if (lvalue->type.id == dbg_itype_none)
|
||||
if (!types_get_real_type(&type, &tag))
|
||||
{
|
||||
WINE_FIXME("---error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (type.id == dbg_itype_none)
|
||||
{
|
||||
/* No type, just print the addr value */
|
||||
print_bare_address(&lvalue->addr);
|
||||
|
@ -418,47 +442,45 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level)
|
|||
format = '\0';
|
||||
}
|
||||
|
||||
if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
|
||||
{
|
||||
WINE_FIXME("---error\n");
|
||||
return;
|
||||
}
|
||||
switch (tag)
|
||||
{
|
||||
case SymTagBaseType:
|
||||
case SymTagEnum:
|
||||
case SymTagPointerType:
|
||||
/* FIXME: this in not 100% optimal (as we're going through the typedef handling
|
||||
* stuff again
|
||||
*/
|
||||
print_basic(lvalue, 1, format);
|
||||
break;
|
||||
case SymTagUDT:
|
||||
if (types_get_info(&lvalue->type, TI_GET_CHILDRENCOUNT, &count))
|
||||
if (types_get_info(&type, TI_GET_CHILDRENCOUNT, &count))
|
||||
{
|
||||
char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
|
||||
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
|
||||
WCHAR* ptr;
|
||||
char tmp[256];
|
||||
long int tmpbuf;
|
||||
struct dbg_type type;
|
||||
struct dbg_type sub_type;
|
||||
|
||||
dbg_printf("{");
|
||||
fcp->Start = 0;
|
||||
while (count)
|
||||
{
|
||||
fcp->Count = min(count, 256);
|
||||
if (types_get_info(&lvalue->type, TI_FINDCHILDREN, fcp))
|
||||
if (types_get_info(&type, TI_FINDCHILDREN, fcp))
|
||||
{
|
||||
for (i = 0; i < min(fcp->Count, count); i++)
|
||||
{
|
||||
ptr = NULL;
|
||||
type.module = lvalue->type.module;
|
||||
type.id = fcp->ChildId[i];
|
||||
types_get_info(&type, TI_GET_SYMNAME, &ptr);
|
||||
sub_type.module = type.module;
|
||||
sub_type.id = fcp->ChildId[i];
|
||||
types_get_info(&sub_type, TI_GET_SYMNAME, &ptr);
|
||||
if (!ptr) continue;
|
||||
WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
|
||||
dbg_printf("%s=", tmp);
|
||||
HeapFree(GetProcessHeap(), 0, ptr);
|
||||
lvalue_field = *lvalue;
|
||||
if (types_get_udt_element_lvalue(&lvalue_field, &type, &tmpbuf))
|
||||
if (types_get_udt_element_lvalue(&lvalue_field, &sub_type, &tmpbuf))
|
||||
{
|
||||
print_value(&lvalue_field, format, level + 1);
|
||||
}
|
||||
|
@ -476,8 +498,8 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level)
|
|||
* Loop over all of the entries, printing stuff as we go.
|
||||
*/
|
||||
count = 1; size = 1;
|
||||
types_get_info(&lvalue->type, TI_GET_COUNT, &count);
|
||||
types_get_info(&lvalue->type, TI_GET_LENGTH, &size);
|
||||
types_get_info(&type, TI_GET_COUNT, &count);
|
||||
types_get_info(&type, TI_GET_LENGTH, &size);
|
||||
|
||||
if (size == count)
|
||||
{
|
||||
|
@ -495,7 +517,7 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level)
|
|||
break;
|
||||
}
|
||||
lvalue_field = *lvalue;
|
||||
types_get_info(&lvalue->type, TI_GET_TYPE, &lvalue_field.type.id);
|
||||
types_get_info(&type, TI_GET_TYPE, &lvalue_field.type.id);
|
||||
dbg_printf("{");
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
|
@ -508,7 +530,7 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level)
|
|||
dbg_printf("Function ");
|
||||
print_bare_address(&lvalue->addr);
|
||||
dbg_printf(": ");
|
||||
types_print_type(&lvalue->type, FALSE);
|
||||
types_print_type(&type, FALSE);
|
||||
break;
|
||||
case SymTagTypedef:
|
||||
lvalue_field = *lvalue;
|
||||
|
|
Loading…
Reference in New Issue