winedbg: Added a more decent scheme for handling segmented addresses.
This commit is contained in:
parent
4d3996d515
commit
9d0b5f5372
|
@ -195,8 +195,7 @@ BOOL break_add_break_from_lvalue(const struct dbg_lvalue* lvalue)
|
||||||
{
|
{
|
||||||
ADDRESS addr;
|
ADDRESS addr;
|
||||||
|
|
||||||
addr.Mode = AddrModeFlat;
|
types_extract_as_address(lvalue, &addr);
|
||||||
addr.Offset = types_extract_as_integer(lvalue);
|
|
||||||
|
|
||||||
if (!break_add_break(&addr, TRUE))
|
if (!break_add_break(&addr, TRUE))
|
||||||
{
|
{
|
||||||
|
@ -400,8 +399,7 @@ void break_add_watch_from_lvalue(const struct dbg_lvalue* lvalue)
|
||||||
{
|
{
|
||||||
struct dbg_lvalue lval;
|
struct dbg_lvalue lval;
|
||||||
|
|
||||||
lval.addr.Mode = AddrModeFlat;
|
types_extract_as_address(lvalue, &lval.addr);
|
||||||
lval.addr.Offset = types_extract_as_integer(lvalue);
|
|
||||||
lval.type.id = dbg_itype_none;
|
lval.type.id = dbg_itype_none;
|
||||||
|
|
||||||
break_add_watch(&lval, TRUE);
|
break_add_watch(&lval, TRUE);
|
||||||
|
|
|
@ -81,6 +81,7 @@ enum dbg_internal_types
|
||||||
dbg_itype_long_real, /* aka long double */
|
dbg_itype_long_real, /* aka long double */
|
||||||
dbg_itype_astring,
|
dbg_itype_astring,
|
||||||
dbg_itype_ustring,
|
dbg_itype_ustring,
|
||||||
|
dbg_itype_segptr, /* hack for segmented pointers */
|
||||||
dbg_itype_none = 0xffffffff
|
dbg_itype_none = 0xffffffff
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -369,6 +370,7 @@ extern void print_value(const struct dbg_lvalue* addr, char format,
|
||||||
extern int types_print_type(const struct dbg_type*, BOOL details);
|
extern int types_print_type(const struct dbg_type*, BOOL details);
|
||||||
extern int print_types(void);
|
extern int print_types(void);
|
||||||
extern long int types_extract_as_integer(const struct dbg_lvalue*);
|
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_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_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_array_index(const struct dbg_lvalue* value, int index, struct dbg_lvalue* result);
|
||||||
|
|
|
@ -545,11 +545,10 @@ struct dbg_lvalue expr_eval(struct expr* exp)
|
||||||
types_extract_as_integer(&exp2) * (DWORD)scale2) / (DWORD)scale3;
|
types_extract_as_integer(&exp2) * (DWORD)scale2) / (DWORD)scale3;
|
||||||
break;
|
break;
|
||||||
case EXP_OP_SEG:
|
case EXP_OP_SEG:
|
||||||
rtn.type.id = dbg_itype_none;
|
rtn.type.id = dbg_itype_segptr;
|
||||||
rtn.type.module = 0;
|
rtn.type.module = 0;
|
||||||
rtn.addr.Mode = AddrMode1632;
|
be_cpu->build_addr(dbg_curr_thread->handle, &dbg_context, &rtn.addr,
|
||||||
rtn.addr.Segment = types_extract_as_integer(&exp1);
|
types_extract_as_integer(&exp1), types_extract_as_integer(&exp2));
|
||||||
rtn.addr.Offset = types_extract_as_integer(&exp2);
|
|
||||||
break;
|
break;
|
||||||
case EXP_OP_LOR:
|
case EXP_OP_LOR:
|
||||||
exp->un.binop.result = (types_extract_as_integer(&exp1) || types_extract_as_integer(&exp2));
|
exp->un.binop.result = (types_extract_as_integer(&exp1) || types_extract_as_integer(&exp2));
|
||||||
|
|
|
@ -151,17 +151,8 @@ void memory_examine(const struct dbg_lvalue *lvalue, int count, char format)
|
||||||
ADDRESS addr;
|
ADDRESS addr;
|
||||||
void *linear;
|
void *linear;
|
||||||
|
|
||||||
if (lvalue->type.id == dbg_itype_none)
|
types_extract_as_address(lvalue, &addr);
|
||||||
{
|
linear = memory_to_linear_addr(&addr);
|
||||||
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 );
|
|
||||||
|
|
||||||
if (format != 'i' && count > 1)
|
if (format != 'i' && count > 1)
|
||||||
{
|
{
|
||||||
|
@ -449,7 +440,8 @@ void print_basic(const struct dbg_lvalue* lvalue, int count, char format)
|
||||||
switch (format)
|
switch (format)
|
||||||
{
|
{
|
||||||
case 'x':
|
case 'x':
|
||||||
if (lvalue->addr.Mode != AddrModeFlat)
|
if (lvalue->addr.Mode == AddrMode1616 ||
|
||||||
|
lvalue->addr.Mode == AddrModeReal)
|
||||||
dbg_printf("0x%04lx", res);
|
dbg_printf("0x%04lx", res);
|
||||||
else
|
else
|
||||||
dbg_printf("0x%08lx", res);
|
dbg_printf("0x%08lx", res);
|
||||||
|
@ -478,7 +470,10 @@ void print_basic(const struct dbg_lvalue* lvalue, int count, char format)
|
||||||
case 'b':
|
case 'b':
|
||||||
dbg_printf("Format specifier '%c' is meaningless in 'print' command\n", format);
|
dbg_printf("Format specifier '%c' is meaningless in 'print' command\n", format);
|
||||||
case 0:
|
case 0:
|
||||||
print_typed_basic(lvalue);
|
if (lvalue->type.id == dbg_itype_segptr)
|
||||||
|
dbg_printf("%ld", res);
|
||||||
|
else
|
||||||
|
print_typed_basic(lvalue);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -567,18 +562,7 @@ void memory_disassemble(const struct dbg_lvalue* xstart,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (xstart)
|
if (xstart)
|
||||||
{
|
types_extract_as_address(xstart, &last);
|
||||||
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 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (xend)
|
if (xend)
|
||||||
stop = types_extract_as_integer(xend);
|
stop = types_extract_as_integer(xend);
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,7 +177,7 @@ static BOOL WINAPI sym_enum_cb(SYMBOL_INFO* sym_info, ULONG size, void* user)
|
||||||
DWORD addr;
|
DWORD addr;
|
||||||
unsigned val;
|
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, ", ");
|
if (se->tmp[0]) strcat(se->tmp, ", ");
|
||||||
addr = se->frame + sym_info->Address;
|
addr = se->frame + sym_info->Address;
|
||||||
|
|
|
@ -38,41 +38,43 @@ WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
|
||||||
long int types_extract_as_integer(const struct dbg_lvalue* lvalue)
|
long int types_extract_as_integer(const struct dbg_lvalue* lvalue)
|
||||||
{
|
{
|
||||||
long int rtn = 0;
|
long int rtn = 0;
|
||||||
DWORD tag, size, bt;
|
long long int val;
|
||||||
DWORD64 size64;
|
DWORD tag, bt;
|
||||||
|
DWORD64 size;
|
||||||
|
|
||||||
if (lvalue->type.id == dbg_itype_none ||
|
if (lvalue->type.id == dbg_itype_none ||
|
||||||
!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
|
!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (lvalue->type.id == dbg_itype_segptr)
|
||||||
|
{
|
||||||
|
return (long int)memory_to_linear_addr(&lvalue->addr);
|
||||||
|
}
|
||||||
|
|
||||||
switch (tag)
|
switch (tag)
|
||||||
{
|
{
|
||||||
case SymTagBaseType:
|
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))
|
!types_get_info(&lvalue->type, TI_GET_BASETYPE, &bt))
|
||||||
{
|
{
|
||||||
WINE_ERR("Couldn't get information\n");
|
WINE_ERR("Couldn't get information\n");
|
||||||
RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
|
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;
|
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)
|
switch (bt)
|
||||||
{
|
{
|
||||||
|
case btChar:
|
||||||
case btInt:
|
case btInt:
|
||||||
/* propagate sign information */
|
if (!be_cpu->fetch_integer(lvalue, (unsigned)size, TRUE, &val)) return 0;
|
||||||
if (((size & 3) != 0) && (rtn >> (size * 8 - 1)) != 0)
|
rtn = (long)val;
|
||||||
rtn |= (-1) << (size * 8);
|
|
||||||
break;
|
break;
|
||||||
case btUInt:
|
case btUInt:
|
||||||
case btChar:
|
if (!be_cpu->fetch_integer(lvalue, (unsigned)size, FALSE, &val)) return 0;
|
||||||
|
rtn = (DWORD)(DWORD64)val;
|
||||||
break;
|
break;
|
||||||
case btFloat:
|
case btFloat:
|
||||||
RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL);
|
RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL);
|
||||||
|
@ -99,6 +101,24 @@ long int types_extract_as_integer(const struct dbg_lvalue* lvalue)
|
||||||
return rtn;
|
return rtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************
|
||||||
|
* 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
|
* types_deref
|
||||||
*
|
*
|
||||||
|
@ -773,6 +793,15 @@ BOOL types_get_info(const struct dbg_type* type, IMAGEHLP_SYMBOL_TYPE_INFO ti, v
|
||||||
default: WINE_FIXME("unsupported %u for a string\n", ti); return FALSE;
|
default: WINE_FIXME("unsupported %u for a string\n", ti); return FALSE;
|
||||||
}
|
}
|
||||||
break;
|
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);
|
default: WINE_FIXME("unsupported type id 0x%lx\n", type->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,8 +58,6 @@
|
||||||
* o bitfield size is on a 4-bytes
|
* o bitfield size is on a 4-bytes
|
||||||
* + array_index and deref should be the same function (or should share the same
|
* + array_index and deref should be the same function (or should share the same
|
||||||
* core)
|
* core)
|
||||||
* + segmented pointers are not correctly handled (and are hacked throughout the
|
|
||||||
* code by testing against itype_none)
|
|
||||||
* - execution:
|
* - execution:
|
||||||
* + set a better fix for gdb (proxy mode) than the step-mode hack
|
* + set a better fix for gdb (proxy mode) than the step-mode hack
|
||||||
* + implement function call in debuggee
|
* + implement function call in debuggee
|
||||||
|
|
Loading…
Reference in New Issue