Eric Pouech : winedbg: Added a more decent scheme for handling segmented addresses.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Jan 23 10:35:09 CST 2006


Module: wine
Branch: refs/heads/master
Commit: 9d0b5f53727c783a59f31f11874584d4707f39b5
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=9d0b5f53727c783a59f31f11874584d4707f39b5

Author: Eric Pouech <eric.pouech at wanadoo.fr>
Date:   Mon Jan 23 16:26:40 2006 +0100

winedbg: Added a more decent scheme for handling segmented addresses.

---

 programs/winedbg/break.c    |    6 ++---
 programs/winedbg/debugger.h |    2 ++
 programs/winedbg/expr.c     |    7 ++---
 programs/winedbg/memory.c   |   34 +++++++-------------------
 programs/winedbg/stack.c    |    2 +-
 programs/winedbg/types.c    |   57 ++++++++++++++++++++++++++++++++-----------
 programs/winedbg/winedbg.c  |    2 --
 7 files changed, 60 insertions(+), 50 deletions(-)

diff --git a/programs/winedbg/break.c b/programs/winedbg/break.c
index 8f502b5..086d1e5 100644
--- a/programs/winedbg/break.c
+++ b/programs/winedbg/break.c
@@ -195,8 +195,7 @@ BOOL break_add_break_from_lvalue(const s
 {
     ADDRESS     addr;
 
-    addr.Mode = AddrModeFlat;
-    addr.Offset = types_extract_as_integer(lvalue);
+    types_extract_as_address(lvalue, &addr);
 
     if (!break_add_break(&addr, TRUE))
     {
@@ -400,8 +399,7 @@ void break_add_watch_from_lvalue(const s
 {
     struct dbg_lvalue   lval;
 
-    lval.addr.Mode = AddrModeFlat;
-    lval.addr.Offset = types_extract_as_integer(lvalue);
+    types_extract_as_address(lvalue, &lval.addr);
     lval.type.id = dbg_itype_none;
 
     break_add_watch(&lval, TRUE);
diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h
index d26bbc0..111a58a 100644
--- a/programs/winedbg/debugger.h
+++ b/programs/winedbg/debugger.h
@@ -81,6 +81,7 @@ enum dbg_internal_types
     dbg_itype_long_real,  /* aka long double */
     dbg_itype_astring,
     dbg_itype_ustring,
+    dbg_itype_segptr,     /* hack for segmented pointers */
     dbg_itype_none              = 0xffffffff
 };
 
@@ -369,6 +370,7 @@ extern void             print_value(cons
 extern int              types_print_type(const struct dbg_type*, BOOL details);
 extern int              print_types(void);
 extern long int         types_extract_as_integer(const struct dbg_lvalue*);
+extern void             types_extract_as_address(const struct dbg_lvalue*, ADDRESS*);
 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);
diff --git a/programs/winedbg/expr.c b/programs/winedbg/expr.c
index 5815298..89d23df 100644
--- a/programs/winedbg/expr.c
+++ b/programs/winedbg/expr.c
@@ -545,11 +545,10 @@ struct dbg_lvalue expr_eval(struct expr*
                                     types_extract_as_integer(&exp2) * (DWORD)scale2) / (DWORD)scale3;
             break;
 	case EXP_OP_SEG:
-            rtn.type.id = dbg_itype_none;
+            rtn.type.id = dbg_itype_segptr;
             rtn.type.module = 0;
-            rtn.addr.Mode = AddrMode1632;
-            rtn.addr.Segment = types_extract_as_integer(&exp1);
-            rtn.addr.Offset = types_extract_as_integer(&exp2);
+            be_cpu->build_addr(dbg_curr_thread->handle, &dbg_context, &rtn.addr,
+                               types_extract_as_integer(&exp1), types_extract_as_integer(&exp2));
             break;
 	case EXP_OP_LOR:
             exp->un.binop.result = (types_extract_as_integer(&exp1) || types_extract_as_integer(&exp2));
diff --git a/programs/winedbg/memory.c b/programs/winedbg/memory.c
index 3bda720..8e8b984 100644
--- a/programs/winedbg/memory.c
+++ b/programs/winedbg/memory.c
@@ -151,17 +151,8 @@ void memory_examine(const struct dbg_lva
     ADDRESS             addr;
     void               *linear;
 
-    if (lvalue->type.id == dbg_itype_none)
-    {
-        be_cpu->build_addr(dbg_curr_thread->handle, &dbg_context,
-                           &addr, lvalue->addr.Segment, lvalue->addr.Offset);
-    }
-    else
-    {
-        addr.Mode = AddrModeFlat;
-        addr.Offset = types_extract_as_integer( lvalue );
-    }
-    linear = memory_to_linear_addr( &addr );
+    types_extract_as_address(lvalue, &addr);
+    linear = memory_to_linear_addr(&addr);
 
     if (format != 'i' && count > 1)
     {
@@ -449,7 +440,8 @@ void print_basic(const struct dbg_lvalue
     switch (format)
     {
     case 'x':
-        if (lvalue->addr.Mode != AddrModeFlat)
+        if (lvalue->addr.Mode == AddrMode1616 || 
+            lvalue->addr.Mode == AddrModeReal)
             dbg_printf("0x%04lx", res);
         else
             dbg_printf("0x%08lx", res);
@@ -478,7 +470,10 @@ void print_basic(const struct dbg_lvalue
     case 'b':
         dbg_printf("Format specifier '%c' is meaningless in 'print' command\n", format);
     case 0:
-        print_typed_basic(lvalue);
+        if (lvalue->type.id == dbg_itype_segptr)
+            dbg_printf("%ld", res);
+        else 
+            print_typed_basic(lvalue);
         break;
     }
 }
@@ -567,18 +562,7 @@ void memory_disassemble(const struct dbg
     else
     {
         if (xstart)
-        {
-            if (xstart->type.id == dbg_itype_none)
-            {
-                be_cpu->build_addr(dbg_curr_thread->handle, &dbg_context,
-                                   &last, xstart->addr.Segment, xstart->addr.Offset);
-            }
-            else
-            {
-                last.Mode = AddrModeFlat;
-                last.Offset = types_extract_as_integer( xstart );
-            }
-        }
+            types_extract_as_address(xstart, &last);
         if (xend) 
             stop = types_extract_as_integer(xend);
     }
diff --git a/programs/winedbg/stack.c b/programs/winedbg/stack.c
index b33cf60..abb943a 100644
--- a/programs/winedbg/stack.c
+++ b/programs/winedbg/stack.c
@@ -177,7 +177,7 @@ static BOOL WINAPI sym_enum_cb(SYMBOL_IN
     DWORD               addr;
     unsigned            val;
 
-    if ((sym_info->Flags & (SYMFLAG_PARAMETER|SYMFLAG_FRAMEREL)) == (SYMFLAG_PARAMETER|SYMFLAG_FRAMEREL))
+    if ((sym_info->Flags & (SYMFLAG_PARAMETER|SYMFLAG_REGREL)) == (SYMFLAG_PARAMETER|SYMFLAG_REGREL))
     {
         if (se->tmp[0]) strcat(se->tmp, ", ");
         addr = se->frame + sym_info->Address;
diff --git a/programs/winedbg/types.c b/programs/winedbg/types.c
index e9b9358..bb05422 100644
--- a/programs/winedbg/types.c
+++ b/programs/winedbg/types.c
@@ -38,41 +38,43 @@ WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
 long int types_extract_as_integer(const struct dbg_lvalue* lvalue)
 {
     long int            rtn = 0;
-    DWORD               tag, size, bt;
-    DWORD64             size64;
+    long long int       val;
+    DWORD               tag, bt;
+    DWORD64             size;
 
     if (lvalue->type.id == dbg_itype_none ||
         !types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
         return 0;
 
+    if (lvalue->type.id == dbg_itype_segptr)
+    {
+        return (long int)memory_to_linear_addr(&lvalue->addr);
+    }
+
     switch (tag)
     {
     case SymTagBaseType:
-        if (!types_get_info(&lvalue->type, TI_GET_LENGTH, &size64) ||
+        if (!types_get_info(&lvalue->type, TI_GET_LENGTH, &size) ||
             !types_get_info(&lvalue->type, TI_GET_BASETYPE, &bt))
         {
             WINE_ERR("Couldn't get information\n");
             RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
         }
-        if (size64 > sizeof(rtn))
+        if (size > sizeof(rtn))
         {
-            WINE_ERR("Size too large (%s)\n", wine_dbgstr_longlong(size64));
+            WINE_ERR("Size too large (%s)\n", wine_dbgstr_longlong(size));
             return 0;
         }
-        size = (DWORD)size64;
-        /* FIXME: we have an ugly & non portable thing here !!! */
-        if (!memory_read_value(lvalue, size, &rtn)) return 0;
-
-        /* now let's do some promotions !! */
         switch (bt)
         {
+        case btChar:
         case btInt:
-            /* propagate sign information */
-            if (((size & 3) != 0) && (rtn >> (size * 8 - 1)) != 0)
-                rtn |= (-1) << (size * 8);
+            if (!be_cpu->fetch_integer(lvalue, (unsigned)size, TRUE, &val)) return 0;
+            rtn = (long)val;
             break;
         case btUInt:
-        case btChar:
+            if (!be_cpu->fetch_integer(lvalue, (unsigned)size, FALSE, &val)) return 0;
+            rtn = (DWORD)(DWORD64)val;
             break;
         case btFloat:
             RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL);
@@ -100,6 +102,24 @@ long int types_extract_as_integer(const 
 }
 
 /******************************************************************
+ *		types_extract_as_address
+ *
+ *
+ */
+void types_extract_as_address(const struct dbg_lvalue* lvalue, ADDRESS* addr)
+{
+    if (lvalue->type.id == dbg_itype_segptr && lvalue->type.module == 0)
+    {
+        *addr = lvalue->addr;
+    }
+    else
+    {
+        addr->Mode = AddrModeFlat;
+        addr->Offset = types_extract_as_integer( lvalue );
+    }
+}
+
+/******************************************************************
  *		types_deref
  *
  */
@@ -773,6 +793,15 @@ BOOL types_get_info(const struct dbg_typ
         default: WINE_FIXME("unsupported %u for a string\n", ti); return FALSE;
         }
         break;
+    case dbg_itype_segptr:
+        switch (ti)
+        {
+        case TI_GET_SYMTAG:     X(DWORD)   = SymTagBaseType; break;
+        case TI_GET_LENGTH:     X(DWORD64) = 4; break;
+        case TI_GET_BASETYPE:   X(DWORD)   = btInt; break;
+        default: WINE_FIXME("unsupported %u for seg-ptr\n", ti); return FALSE;
+        }
+        break;
     default: WINE_FIXME("unsupported type id 0x%lx\n", type->id);
     }
 
diff --git a/programs/winedbg/winedbg.c b/programs/winedbg/winedbg.c
index e891514..87f9a02 100644
--- a/programs/winedbg/winedbg.c
+++ b/programs/winedbg/winedbg.c
@@ -58,8 +58,6 @@
  *              o bitfield size is on a 4-bytes
  *      + array_index and deref should be the same function (or should share the same
  *        core)
- *      + segmented pointers are not correctly handled (and are hacked throughout the
- *        code by testing against itype_none)
  * - execution:
  *      + set a better fix for gdb (proxy mode) than the step-mode hack
  *      + implement function call in debuggee




More information about the wine-cvs mailing list