[PATCH 01/31] [WineDbg]: typedef
Eric Pouech
eric.pouech at wanadoo.fr
Sun Jun 18 14:30:45 CDT 2006
Please use this patch instead of the previous version (fixes a couple
more issues)
- proper hanlding of typedefs
- added types_get_real_type() to get rid of typedef information,
and access the real underlying type
A+
---
programs/winedbg/debugger.h | 1
programs/winedbg/memory.c | 38 +++++++++---------
programs/winedbg/types.c | 90 +++++++++++++++++++++++++++----------------
3 files changed, 76 insertions(+), 53 deletions(-)
diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h
index 9fee709..c51ccc6 100644
--- a/programs/winedbg/debugger.h
+++ b/programs/winedbg/debugger.h
@@ -392,6 +392,7 @@ extern BOOL types_deref(cons
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);
diff --git a/programs/winedbg/memory.c b/programs/winedbg/memory.c
index e7792ba..fca6e3d 100644
--- a/programs/winedbg/memory.c
+++ b/programs/winedbg/memory.c
@@ -280,17 +280,16 @@ static void print_typed_basic(const stru
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 stru
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 stru
*/
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 stru
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 stru
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);
diff --git a/programs/winedbg/types.c b/programs/winedbg/types.c
index 05e1e89..7ea1aa5 100644
--- a/programs/winedbg/types.c
+++ b/programs/winedbg/types.c
@@ -30,6 +30,24 @@ #include "wine/debug.h"
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
*
* Given a lvalue, try to get an integral (or pointer/address) value
@@ -41,12 +59,12 @@ long int types_extract_as_integer(const
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
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 stru
*/
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
/*
* 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
else
{
if (!memory_read_value(lvalue, sizeof(*tmpbuf), tmpbuf)) return FALSE;
-
}
return TRUE;
}
@@ -279,15 +296,15 @@ BOOL types_udt_find_element(struct dbg_l
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_
/*
* 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
*/
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
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
* 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
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
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;
More information about the wine-patches
mailing list