Module: wine Branch: refs/heads/master Commit: 9d0b5f53727c783a59f31f11874584d4707f39b5 URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=9d0b5f53727c783a59f31f11...
Author: Eric Pouech eric.pouech@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