[PATCH 4/6] [WineDbg]: merge pointer deref and array index functions into a single one

Eric Pouech eric.pouech at orange.fr
Mon Apr 12 14:18:25 CDT 2010


- fix incidentally target/host bug for array index (wasn't forcing target address space)
- fix also the number of bytes read by these two operations (now aligned on machine ptr size)

A+
---

 programs/winedbg/debugger.h |    1 -
 programs/winedbg/expr.c     |    4 +-
 programs/winedbg/memory.c   |    2 +
 programs/winedbg/types.c    |   86 +++++++++++++++++++------------------------
 programs/winedbg/winedbg.c  |    2 -
 5 files changed, 40 insertions(+), 55 deletions(-)


diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h
index 385a412..7efbaea 100644
--- a/programs/winedbg/debugger.h
+++ b/programs/winedbg/debugger.h
@@ -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*);
diff --git a/programs/winedbg/expr.c b/programs/winedbg/expr.c
index 6b8c46f..66cd701 100644
--- a/programs/winedbg/expr.c
+++ b/programs/winedbg/expr.c
@@ -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:
diff --git a/programs/winedbg/memory.c b/programs/winedbg/memory.c
index 86aa881..7aad239 100644
--- a/programs/winedbg/memory.c
+++ b/programs/winedbg/memory.c
@@ -402,7 +402,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));
diff --git a/programs/winedbg/types.c b/programs/winedbg/types.c
index 414bb9f..6d50c81 100644
--- a/programs/winedbg/types.c
+++ b/programs/winedbg/types.c
@@ -155,45 +155,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
  *
  * Implement a structure derefencement
@@ -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;
 }
 
diff --git a/programs/winedbg/winedbg.c b/programs/winedbg/winedbg.c
index 6ce6db4..7a37805 100644
--- a/programs/winedbg/winedbg.c
+++ b/programs/winedbg/winedbg.c
@@ -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






More information about the wine-patches mailing list