winedbg: Revamp dbg_lvalue structure and add helpers for init.
Signed-off-by: Eric Pouech <eric.pouech@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
0888943e72
commit
ef3fca0c33
|
@ -357,7 +357,7 @@ void break_check_delayed_bp(void)
|
||||||
if (symbol_get_lvalue(dbp[i].u.symbol.name, dbp[i].u.symbol.lineno,
|
if (symbol_get_lvalue(dbp[i].u.symbol.name, dbp[i].u.symbol.lineno,
|
||||||
&lvalue, TRUE) != sglv_found)
|
&lvalue, TRUE) != sglv_found)
|
||||||
continue;
|
continue;
|
||||||
if (lvalue.cookie != DLV_TARGET) continue;
|
if (!lvalue.in_debuggee) continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
lvalue.addr = dbp[i].u.addr;
|
lvalue.addr = dbp[i].u.addr;
|
||||||
|
@ -385,7 +385,7 @@ static void break_add_watch(const struct dbg_lvalue* lvalue, BOOL is_write)
|
||||||
int num;
|
int num;
|
||||||
DWORD64 l = 4;
|
DWORD64 l = 4;
|
||||||
|
|
||||||
if (lvalue->cookie == DLV_HOST)
|
if (!lvalue->in_debuggee)
|
||||||
{
|
{
|
||||||
dbg_printf("Cannot set a watch point on register or register-based variable\n");
|
dbg_printf("Cannot set a watch point on register or register-based variable\n");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -117,16 +117,29 @@ struct dbg_type
|
||||||
|
|
||||||
struct dbg_lvalue /* structure to hold left-values... */
|
struct dbg_lvalue /* structure to hold left-values... */
|
||||||
{
|
{
|
||||||
int cookie; /* DLV_??? */
|
unsigned in_debuggee : 1; /* 1 = debuggee address space, 0 = debugger address space */
|
||||||
/* DLV_TARGET references an address in debuggee's address space, whereas DLV_HOST
|
|
||||||
* references the winedbg's address space
|
|
||||||
*/
|
|
||||||
# define DLV_TARGET 0xF00D
|
|
||||||
# define DLV_HOST 0x50DA
|
|
||||||
ADDRESS64 addr;
|
ADDRESS64 addr;
|
||||||
struct dbg_type type;
|
struct dbg_type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline void init_lvalue(struct dbg_lvalue* lv, BOOL in_debuggee, void* addr)
|
||||||
|
{
|
||||||
|
lv->in_debuggee = !!in_debuggee;
|
||||||
|
lv->addr.Mode = AddrModeFlat;
|
||||||
|
lv->addr.Offset = (DWORD_PTR)addr;
|
||||||
|
lv->type.module = 0;
|
||||||
|
lv->type.id = dbg_itype_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void init_lvalue_in_debugger(struct dbg_lvalue* lv, enum dbg_internal_types it, void* addr)
|
||||||
|
{
|
||||||
|
lv->in_debuggee = 0;
|
||||||
|
lv->addr.Mode = AddrModeFlat;
|
||||||
|
lv->addr.Offset = (DWORD_PTR)addr;
|
||||||
|
lv->type.module = 0;
|
||||||
|
lv->type.id = it;
|
||||||
|
}
|
||||||
|
|
||||||
enum dbg_exec_mode
|
enum dbg_exec_mode
|
||||||
{
|
{
|
||||||
dbg_exec_cont, /* Continue execution */
|
dbg_exec_cont, /* Continue execution */
|
||||||
|
|
|
@ -281,12 +281,7 @@ struct dbg_lvalue expr_eval(struct expr* exp)
|
||||||
DWORD tag;
|
DWORD tag;
|
||||||
const struct dbg_internal_var* div;
|
const struct dbg_internal_var* div;
|
||||||
|
|
||||||
rtn.cookie = 0;
|
init_lvalue_in_debugger(&rtn, dbg_itype_none, NULL);
|
||||||
rtn.type.id = dbg_itype_none;
|
|
||||||
rtn.type.module = 0;
|
|
||||||
rtn.addr.Mode = AddrModeFlat;
|
|
||||||
rtn.addr.Offset = 0;
|
|
||||||
rtn.addr.Segment = 0;
|
|
||||||
|
|
||||||
switch (exp->type)
|
switch (exp->type)
|
||||||
{
|
{
|
||||||
|
@ -340,22 +335,13 @@ struct dbg_lvalue expr_eval(struct expr* exp)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EXPR_TYPE_STRING:
|
case EXPR_TYPE_STRING:
|
||||||
rtn.cookie = DLV_HOST;
|
init_lvalue_in_debugger(&rtn, dbg_itype_astring, &exp->un.string.str);
|
||||||
rtn.type.id = dbg_itype_astring;
|
|
||||||
rtn.type.module = 0;
|
|
||||||
rtn.addr.Offset = (ULONG_PTR)&exp->un.string.str;
|
|
||||||
break;
|
break;
|
||||||
case EXPR_TYPE_U_CONST:
|
case EXPR_TYPE_U_CONST:
|
||||||
rtn.cookie = DLV_HOST;
|
init_lvalue_in_debugger(&rtn, dbg_itype_lguint, &exp->un.u_const.value);
|
||||||
rtn.type.id = dbg_itype_lguint;
|
|
||||||
rtn.type.module = 0;
|
|
||||||
rtn.addr.Offset = (ULONG_PTR)&exp->un.u_const.value;
|
|
||||||
break;
|
break;
|
||||||
case EXPR_TYPE_S_CONST:
|
case EXPR_TYPE_S_CONST:
|
||||||
rtn.cookie = DLV_HOST;
|
init_lvalue_in_debugger(&rtn, dbg_itype_lgint, &exp->un.s_const.value);
|
||||||
rtn.type.id = dbg_itype_lgint;
|
|
||||||
rtn.type.module = 0;
|
|
||||||
rtn.addr.Offset = (ULONG_PTR)&exp->un.s_const.value;
|
|
||||||
break;
|
break;
|
||||||
case EXPR_TYPE_SYMBOL:
|
case EXPR_TYPE_SYMBOL:
|
||||||
switch (symbol_get_lvalue(exp->un.symbol.name, -1, &rtn, FALSE))
|
switch (symbol_get_lvalue(exp->un.symbol.name, -1, &rtn, FALSE))
|
||||||
|
@ -457,28 +443,22 @@ struct dbg_lvalue expr_eval(struct expr* exp)
|
||||||
*/
|
*/
|
||||||
exp->un.call.result = 0;
|
exp->un.call.result = 0;
|
||||||
#endif
|
#endif
|
||||||
rtn.cookie = DLV_HOST;
|
init_lvalue_in_debugger(&rtn, dbg_itype_none, &exp->un.call.result);
|
||||||
/* get return type from function signature tupe */
|
/* get return type from function signature type */
|
||||||
|
/* FIXME rtn.type.module should be set to function's module... */
|
||||||
types_get_info(&rtn.type, TI_GET_TYPE, &rtn.type.id);
|
types_get_info(&rtn.type, TI_GET_TYPE, &rtn.type.id);
|
||||||
rtn.addr.Offset = (ULONG_PTR)&exp->un.call.result;
|
|
||||||
break;
|
break;
|
||||||
case EXPR_TYPE_INTVAR:
|
case EXPR_TYPE_INTVAR:
|
||||||
rtn.cookie = DLV_HOST;
|
|
||||||
if (!(div = dbg_get_internal_var(exp->un.intvar.name)))
|
if (!(div = dbg_get_internal_var(exp->un.intvar.name)))
|
||||||
RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
|
RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
|
||||||
rtn.type.id = div->typeid;
|
init_lvalue_in_debugger(&rtn, div->typeid, div->pval);
|
||||||
rtn.type.module = 0;
|
|
||||||
rtn.addr.Offset = (ULONG_PTR)div->pval;
|
|
||||||
break;
|
break;
|
||||||
case EXPR_TYPE_BINOP:
|
case EXPR_TYPE_BINOP:
|
||||||
rtn.cookie = DLV_HOST;
|
|
||||||
exp1 = expr_eval(exp->un.binop.exp1);
|
exp1 = expr_eval(exp->un.binop.exp1);
|
||||||
exp2 = expr_eval(exp->un.binop.exp2);
|
exp2 = expr_eval(exp->un.binop.exp2);
|
||||||
if (exp1.type.id == dbg_itype_none || exp2.type.id == dbg_itype_none)
|
if (exp1.type.id == dbg_itype_none || exp2.type.id == dbg_itype_none)
|
||||||
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
||||||
rtn.type.id = dbg_itype_lgint;
|
init_lvalue_in_debugger(&rtn, dbg_itype_lgint, &exp->un.binop.result);
|
||||||
rtn.type.module = 0;
|
|
||||||
rtn.addr.Offset = (ULONG_PTR)&exp->un.binop.result;
|
|
||||||
type1 = exp1.type;
|
type1 = exp1.type;
|
||||||
type2 = exp2.type;
|
type2 = exp2.type;
|
||||||
switch (exp->un.binop.binop_type)
|
switch (exp->un.binop.binop_type)
|
||||||
|
@ -605,12 +585,9 @@ struct dbg_lvalue expr_eval(struct expr* exp)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EXPR_TYPE_UNOP:
|
case EXPR_TYPE_UNOP:
|
||||||
rtn.cookie = DLV_HOST;
|
|
||||||
exp1 = expr_eval(exp->un.unop.exp1);
|
exp1 = expr_eval(exp->un.unop.exp1);
|
||||||
if (exp1.type.id == dbg_itype_none) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
if (exp1.type.id == dbg_itype_none) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
||||||
rtn.addr.Offset = (ULONG_PTR)&exp->un.unop.result;
|
init_lvalue_in_debugger(&rtn, dbg_itype_lgint, &exp->un.unop.result);
|
||||||
rtn.type.id = dbg_itype_lgint;
|
|
||||||
rtn.type.module = 0;
|
|
||||||
switch (exp->un.unop.unop_type)
|
switch (exp->un.unop.unop_type)
|
||||||
{
|
{
|
||||||
case EXP_OP_NEG:
|
case EXP_OP_NEG:
|
||||||
|
@ -628,7 +605,7 @@ struct dbg_lvalue expr_eval(struct expr* exp)
|
||||||
break;
|
break;
|
||||||
case EXP_OP_FORCE_DEREF:
|
case EXP_OP_FORCE_DEREF:
|
||||||
rtn = exp1;
|
rtn = exp1;
|
||||||
if (exp1.cookie == DLV_TARGET)
|
if (exp1.in_debuggee)
|
||||||
dbg_read_memory(memory_to_linear_addr(&exp1.addr), &rtn.addr.Offset, sizeof(rtn.addr.Offset));
|
dbg_read_memory(memory_to_linear_addr(&exp1.addr), &rtn.addr.Offset, sizeof(rtn.addr.Offset));
|
||||||
break;
|
break;
|
||||||
case EXP_OP_ADDR:
|
case EXP_OP_ADDR:
|
||||||
|
|
|
@ -84,7 +84,7 @@ BOOL memory_read_value(const struct dbg_lvalue* lvalue, DWORD size, void* result
|
||||||
{
|
{
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
|
|
||||||
if (lvalue->cookie == DLV_TARGET)
|
if (lvalue->in_debuggee)
|
||||||
{
|
{
|
||||||
void* linear = memory_to_linear_addr(&lvalue->addr);
|
void* linear = memory_to_linear_addr(&lvalue->addr);
|
||||||
if (!(ret = dbg_read_memory(linear, result, size)))
|
if (!(ret = dbg_read_memory(linear, result, size)))
|
||||||
|
@ -120,7 +120,7 @@ BOOL memory_write_value(const struct dbg_lvalue* lvalue, DWORD size, void* value
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: only works on little endian systems */
|
/* FIXME: only works on little endian systems */
|
||||||
if (lvalue->cookie == DLV_TARGET)
|
if (lvalue->in_debuggee)
|
||||||
{
|
{
|
||||||
void* linear = memory_to_linear_addr(&lvalue->addr);
|
void* linear = memory_to_linear_addr(&lvalue->addr);
|
||||||
if (!(ret = dbg_write_memory(linear, value, size)))
|
if (!(ret = dbg_write_memory(linear, value, size)))
|
||||||
|
@ -440,7 +440,7 @@ static void print_typed_basic(const struct dbg_lvalue* lvalue)
|
||||||
if (!val_ptr) dbg_printf("0x0");
|
if (!val_ptr) dbg_printf("0x0");
|
||||||
else if (((bt == btChar || bt == btInt) && size64 == 1) || (bt == btUInt && size64 == 2))
|
else if (((bt == btChar || bt == btInt) && size64 == 1) || (bt == btUInt && size64 == 2))
|
||||||
{
|
{
|
||||||
if (memory_get_string(dbg_curr_process, val_ptr, sub_lvalue.cookie == DLV_TARGET,
|
if (memory_get_string(dbg_curr_process, val_ptr, sub_lvalue.in_debuggee,
|
||||||
size64 == 2, buffer, sizeof(buffer)))
|
size64 == 2, buffer, sizeof(buffer)))
|
||||||
dbg_printf("\"%s\"", buffer);
|
dbg_printf("\"%s\"", buffer);
|
||||||
else
|
else
|
||||||
|
|
|
@ -39,10 +39,8 @@ void stack_info(int len)
|
||||||
|
|
||||||
if(len <= 0)
|
if(len <= 0)
|
||||||
len = 24;
|
len = 24;
|
||||||
|
init_lvalue(&lvalue, TRUE, 0);
|
||||||
lvalue.cookie = 0;
|
|
||||||
lvalue.type.id = dbg_itype_segptr;
|
lvalue.type.id = dbg_itype_segptr;
|
||||||
lvalue.type.module = 0;
|
|
||||||
|
|
||||||
/* FIXME: we assume stack grows the same way as on i386 */
|
/* FIXME: we assume stack grows the same way as on i386 */
|
||||||
if (!memory_get_current_stack(&lvalue.addr))
|
if (!memory_get_current_stack(&lvalue.addr))
|
||||||
|
|
|
@ -71,8 +71,7 @@ static BOOL fill_sym_lvalue(const SYMBOL_INFO* sym, ULONG_PTR base,
|
||||||
|
|
||||||
if (!memory_get_register(sym->Register, &pval, buffer, sz))
|
if (!memory_get_register(sym->Register, &pval, buffer, sz))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
lvalue->cookie = DLV_HOST;
|
init_lvalue(lvalue, FALSE, pval);
|
||||||
lvalue->addr.Offset = (DWORD_PTR)pval;
|
|
||||||
}
|
}
|
||||||
else if (sym->Flags & SYMFLAG_REGREL)
|
else if (sym->Flags & SYMFLAG_REGREL)
|
||||||
{
|
{
|
||||||
|
@ -85,8 +84,7 @@ static BOOL fill_sym_lvalue(const SYMBOL_INFO* sym, ULONG_PTR base,
|
||||||
l = strlen(buffer);
|
l = strlen(buffer);
|
||||||
sz -= l;
|
sz -= l;
|
||||||
buffer += l;
|
buffer += l;
|
||||||
lvalue->cookie = DLV_TARGET;
|
init_lvalue(lvalue, TRUE, (void*)(DWORD_PTR)(*pval + sym->Address));
|
||||||
lvalue->addr.Offset = (ULONG64)*pval + sym->Address;
|
|
||||||
if ((LONG64)sym->Address >= 0)
|
if ((LONG64)sym->Address >= 0)
|
||||||
snprintf(buffer, sz, "+%I64d]", sym->Address);
|
snprintf(buffer, sz, "+%I64d]", sym->Address);
|
||||||
else
|
else
|
||||||
|
@ -119,21 +117,18 @@ static BOOL fill_sym_lvalue(const SYMBOL_INFO* sym, ULONG_PTR base,
|
||||||
/* this is likely Wine's dbghelp which passes const values by reference
|
/* this is likely Wine's dbghelp which passes const values by reference
|
||||||
* (object is managed by dbghelp, hence in debugger address space)
|
* (object is managed by dbghelp, hence in debugger address space)
|
||||||
*/
|
*/
|
||||||
lvalue->cookie = DLV_HOST;
|
init_lvalue(lvalue, FALSE, (void*)(DWORD_PTR)sym->Value);
|
||||||
lvalue->addr.Offset = (DWORD_PTR)sym->Value;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DWORD* pdw = (DWORD*)lexeme_alloc_size(sizeof(*pdw));
|
DWORD* pdw = (DWORD*)lexeme_alloc_size(sizeof(*pdw));
|
||||||
lvalue->cookie = DLV_HOST;
|
init_lvalue(lvalue, FALSE, pdw);
|
||||||
lvalue->addr.Offset = (DWORD_PTR)pdw;
|
|
||||||
*pdw = sym->Value;
|
*pdw = sym->Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (sym->Flags & SYMFLAG_LOCAL)
|
else if (sym->Flags & SYMFLAG_LOCAL)
|
||||||
{
|
{
|
||||||
lvalue->cookie = DLV_TARGET;
|
init_lvalue(lvalue, TRUE, (void*)(DWORD_PTR)(base + sym->Address));
|
||||||
lvalue->addr.Offset = base + sym->Address;
|
|
||||||
}
|
}
|
||||||
else if (sym->Flags & SYMFLAG_TLSREL)
|
else if (sym->Flags & SYMFLAG_TLSREL)
|
||||||
{
|
{
|
||||||
|
@ -176,13 +171,11 @@ static BOOL fill_sym_lvalue(const SYMBOL_INFO* sym, ULONG_PTR base,
|
||||||
|
|
||||||
addr += tlsindex * sizeof(DWORD_PTR);
|
addr += tlsindex * sizeof(DWORD_PTR);
|
||||||
if (!dbg_read_memory((void*)addr, &addr, sizeof(addr))) goto tls_error;
|
if (!dbg_read_memory((void*)addr, &addr, sizeof(addr))) goto tls_error;
|
||||||
lvalue->cookie = DLV_TARGET;
|
init_lvalue(lvalue, TRUE, (void*)(DWORD_PTR)(addr + sym->Address));
|
||||||
lvalue->addr.Offset = addr + sym->Address;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lvalue->cookie = DLV_TARGET;
|
init_lvalue(lvalue, TRUE, (void*)(DWORD_PTR)sym->Address);
|
||||||
lvalue->addr.Offset = sym->Address;
|
|
||||||
}
|
}
|
||||||
lvalue->addr.Mode = AddrModeFlat;
|
lvalue->addr.Mode = AddrModeFlat;
|
||||||
lvalue->type.module = sym->ModBase;
|
lvalue->type.module = sym->ModBase;
|
||||||
|
|
|
@ -211,7 +211,7 @@ static BOOL types_get_udt_element_lvalue(struct dbg_lvalue* lvalue,
|
||||||
*tmpbuf >>= bitoffset & 7;
|
*tmpbuf >>= bitoffset & 7;
|
||||||
*tmpbuf &= ~mask;
|
*tmpbuf &= ~mask;
|
||||||
|
|
||||||
lvalue->cookie = DLV_HOST;
|
lvalue->in_debuggee = 0;
|
||||||
lvalue->addr.Offset = (ULONG_PTR)tmpbuf;
|
lvalue->addr.Offset = (ULONG_PTR)tmpbuf;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -337,7 +337,7 @@ BOOL types_array_index(const struct dbg_lvalue* lvalue, int index, struct dbg_lv
|
||||||
* internal variables is very unlikely. A correct fix would be
|
* internal variables is very unlikely. A correct fix would be
|
||||||
* rather large.
|
* rather large.
|
||||||
*/
|
*/
|
||||||
result->cookie = DLV_TARGET;
|
result->in_debuggee = 1;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -531,7 +531,7 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level)
|
||||||
unsigned len = min(count, sizeof(buffer));
|
unsigned len = min(count, sizeof(buffer));
|
||||||
memory_get_string(dbg_curr_process,
|
memory_get_string(dbg_curr_process,
|
||||||
memory_to_linear_addr(&lvalue->addr),
|
memory_to_linear_addr(&lvalue->addr),
|
||||||
lvalue->cookie == DLV_TARGET, TRUE, buffer, len);
|
lvalue->in_debuggee, TRUE, buffer, len);
|
||||||
dbg_printf("\"%s%s\"", buffer, (len < count) ? "..." : "");
|
dbg_printf("\"%s%s\"", buffer, (len < count) ? "..." : "");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue