- fixed breakpoint enabled/disabled state management

- fixed recursion in type printing
- now all type-id are stored with the base address of the module which
  defines the type (struct dbg_type takes care of this pairing)
- fixed a couple of bugs in display handling
- fixed strings print and examination
This commit is contained in:
Eric Pouech 2004-08-22 22:35:36 +00:00 committed by Alexandre Julliard
parent 07a805127a
commit 926f66186f
12 changed files with 427 additions and 368 deletions

View File

@ -1683,17 +1683,19 @@ set $BreakAllThreadsStartup = 1
<tbody>
<row>
<entry>
<msgtext>
<simplelist type="inline">
<member><command>display</command></member>
<member>
<command>info&nbsp;display</command>
</member>
</simplelist>
</msgtext>
<command>info&nbsp;display</command>
</entry>
<entry>lists the active displays</entry>
</row>
<row>
<entry>
<command>display</command>
</entry>
<entry>
print the active displays' values (as done each
time the debugger stops)
</entry>
</row>
<row>
<entry>
<command>display&nbsp;&lt;expr&gt;</command>

View File

@ -59,8 +59,7 @@ void break_set_xpoints(BOOL set)
for (i = 0; i < dbg_curr_process->next_bp; i++)
{
if (!bp[i].refcount && !bp[i].enabled)
continue;
if (!bp[i].refcount || !bp[i].enabled) continue;
if (bp[i].xpoint_type == be_xpoint_break)
size = 0;
@ -78,8 +77,9 @@ void break_set_xpoints(BOOL set)
bp[i].info, size);
if (!ret)
{
dbg_printf("Invalid address (%p) for breakpoint %d, disabling it\n",
addr, i);
dbg_printf("Invalid address (");
print_address(&bp[i].addr, FALSE);
dbg_printf(") for breakpoint %d, disabling it\n", i);
bp[i].enabled = FALSE;
}
}
@ -375,10 +375,9 @@ void break_add_watch(const struct dbg_lvalue* lvalue, BOOL is_write)
&lvalue->addr);
if (num == -1) return;
if (lvalue->typeid != dbg_itype_none)
if (lvalue->type.id != dbg_itype_none)
{
if (types_get_info((DWORD)memory_to_linear_addr(&lvalue->addr),
lvalue->typeid, TI_GET_LENGTH, &l))
if (types_get_info(&lvalue->type, TI_GET_LENGTH, &l))
{
switch (l)
{
@ -679,7 +678,7 @@ static BOOL should_stop(int bpnum)
{
struct dbg_lvalue lvalue = expr_eval(bp->condition);
if (lvalue.typeid == dbg_itype_none)
if (lvalue.type.id == dbg_itype_none)
{
/*
* Something wrong - unable to evaluate this expression.

View File

@ -133,7 +133,7 @@ command:
| tSOURCE pathname { parser($2); }
| tSYMBOLFILE pathname { symbol_read_symtable($2, 0); }
| tSYMBOLFILE pathname expr_rvalue { symbol_read_symtable($2, $3); }
| tWHATIS expr_lvalue { types_print_type((DWORD)memory_to_linear_addr(&$2.addr), $2.typeid, FALSE); dbg_printf("\n"); }
| tWHATIS expr_lvalue { types_print_type(&$2.type, FALSE); dbg_printf("\n"); }
| tATTACH tNUM { dbg_attach_debuggee($2, FALSE, TRUE); }
| tDETACH { dbg_detach_debuggee(); }
| run_command
@ -202,8 +202,8 @@ set_command:
;
x_command:
tEXAM expr_lvalue { memory_examine(&$2, 1, 'x'); }
| tEXAM tFORMAT expr_lvalue { memory_examine(&$3, $2 >> 8, $2 & 0xff); }
tEXAM expr_rvalue { memory_examine((void*)$2, 1, 'x'); }
| tEXAM tFORMAT expr_rvalue { memory_examine((void*)$3, $2 >> 8, $2 & 0xff); }
;
print_command:
@ -231,7 +231,7 @@ watch_command:
;
display_command:
tDISPLAY { display_info(); }
tDISPLAY { display_print(); }
| tDISPLAY expr { display_add($2, 1, 0, FALSE); }
| tDISPLAY tFORMAT expr { display_add($3, $2 >> 8, $2 & 0xff, FALSE); }
| tLOCAL tDISPLAY expr { display_add($3, 1, 0, TRUE); }
@ -280,27 +280,27 @@ noprocess_state:
;
type_expr:
tCHAR { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_char; }
| tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_int; }
| tLONG tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_long_int; }
| tLONG { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_long_int; }
| tUNSIGNED tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_int; }
| tUNSIGNED { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_int; }
| tLONG tUNSIGNED tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_long_int; }
| tLONG tUNSIGNED { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_long_int; }
| tSHORT tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_short_int; }
| tSHORT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_short_int; }
| tSHORT tUNSIGNED tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_short_int; }
| tSHORT tUNSIGNED { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_short_int; }
| tSIGNED tCHAR { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_char_int; }
| tUNSIGNED tCHAR { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_char_int; }
| tLONG tLONG tUNSIGNED tINT{ $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_longlong_int; }
| tLONG tLONG tUNSIGNED { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_longlong_int; }
| tLONG tLONG tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_longlong_int; }
| tLONG tLONG { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_longlong_int; }
| tFLOAT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_short_real; }
| tDOUBLE { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_real; }
| tLONG tDOUBLE { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_long_real; }
tCHAR { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_char; }
| tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_signed_int; }
| tLONG tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_signed_long_int; }
| tLONG { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_signed_long_int; }
| tUNSIGNED tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_int; }
| tUNSIGNED { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_int; }
| tLONG tUNSIGNED tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_long_int; }
| tLONG tUNSIGNED { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_long_int; }
| tSHORT tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_signed_short_int; }
| tSHORT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_signed_short_int; }
| tSHORT tUNSIGNED tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_short_int; }
| tSHORT tUNSIGNED { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_short_int; }
| tSIGNED tCHAR { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_signed_char_int; }
| tUNSIGNED tCHAR { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_char_int; }
| tLONG tLONG tUNSIGNED tINT{ $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_longlong_int; }
| tLONG tLONG tUNSIGNED { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_longlong_int; }
| tLONG tLONG tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_signed_longlong_int; }
| tLONG tLONG { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_signed_longlong_int; }
| tFLOAT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_short_real; }
| tDOUBLE { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_real; }
| tLONG tDOUBLE { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_long_real; }
| type_expr '*' { $$ = $1; $$.deref_count++; }
| tCLASS identifier { $$.type = type_expr_udt_class; $$.deref_count = 0; $$.u.name = lexeme_alloc($2); }
| tSTRUCT identifier { $$.type = type_expr_udt_struct; $$.deref_count = 0; $$.u.name = lexeme_alloc($2); }

View File

@ -82,6 +82,18 @@ enum dbg_internal_types
dbg_itype_none = 0xffffffff
};
/* type description (in the following order):
* - if 'id' is dbg_itype_none (whatever 'module' value), the type isn't known
* - if 'module' is 0, it's an internal type (id is one of dbg_itype...)
* - if 'module' is non 0, then 'id' is a type ID referring to module (loaded in
* dbghelp) which (linear) contains address 'module'.
*/
struct dbg_type
{
unsigned long id;
DWORD module;
};
struct dbg_lvalue /* structure to hold left-values... */
{
int cookie; /* DLV_??? */
@ -91,7 +103,7 @@ struct dbg_lvalue /* structure to hold left-values... */
# define DLV_TARGET 0xF00D
# define DLV_HOST 0x50DA
ADDRESS addr;
unsigned long typeid;
struct dbg_type type;
};
enum dbg_exec_mode
@ -202,7 +214,7 @@ struct dbg_internal_var
DWORD val;
const char* name;
LPDWORD pval;
unsigned long typeid;
unsigned long typeid; /* always internal type */
};
enum sym_get_lval {sglv_found, sglv_unknown, sglv_aborted};
@ -222,7 +234,7 @@ struct type_expr_t
unsigned deref_count;
union
{
unsigned long typeid;
struct dbg_type type;
const char* name;
} u;
};
@ -293,15 +305,15 @@ extern void info_win32_segments(DWORD start, int length);
extern void info_wine_dbg_channel(BOOL add, const char* chnl, const char* name);
/* memory.c */
extern BOOL memory_read_value(const struct dbg_lvalue* val, DWORD size, void* result);
extern BOOL memory_read_value(const struct dbg_lvalue* lvalue, DWORD size, void* result);
extern BOOL memory_write_value(const struct dbg_lvalue* val, DWORD size, void* value);
extern void memory_examine(const struct dbg_lvalue* addr, int count, char format);
extern void memory_examine(void* linear, int count, char format);
extern void memory_report_invalid_addr(const void* addr);
extern void* memory_to_linear_addr(const ADDRESS* address);
extern BOOL memory_get_current_pc(ADDRESS* address);
extern BOOL memory_get_current_stack(ADDRESS* address);
extern BOOL memory_get_current_frame(ADDRESS* address);
extern BOOL memory_get_string(HANDLE hp, void* addr, unsigned cookie, BOOL unicode, char* buffer, int size);
extern BOOL memory_get_string(HANDLE hp, void* addr, BOOL in_debuggee, BOOL unicode, char* buffer, int size);
extern BOOL memory_get_string_indirect(HANDLE hp, void* addr, BOOL unicode, char* buffer, int size);
extern void memory_disassemble(const struct dbg_lvalue*, const struct dbg_lvalue*, int offset);
extern BOOL memory_disasm_one_insn(ADDRESS* addr);
@ -333,16 +345,15 @@ extern int symbol_info_locals(void);
/* types.c */
extern void print_value(const struct dbg_lvalue* addr, char format, int level);
extern int types_print_type(DWORD linear, DWORD typeid, BOOL details);
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 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(unsigned long, unsigned long,
IMAGEHLP_SYMBOL_TYPE_INFO, void*);
extern unsigned long types_find_pointer(unsigned long linear, unsigned long typeid);
extern unsigned long types_find_type(unsigned long linear, const char* name, enum SymTagEnum tag);
extern BOOL types_get_info(const struct dbg_type*, IMAGEHLP_SYMBOL_TYPE_INFO, void*);
extern struct dbg_type types_find_pointer(const struct dbg_type* type);
extern struct dbg_type types_find_type(unsigned long linear, const char* name, enum SymTagEnum tag);
/* winedbg.c */
extern void dbg_outputA(const char* buffer, int len);

View File

@ -43,10 +43,18 @@ struct display
static struct display *displaypoints = NULL;
static unsigned int maxdisplays = 0, ndisplays = 0;
#define OFFSET_OF(_f,_s) ((unsigned)(&(((_s*)NULL)->_f)))
static inline BOOL cmp_symbol(const SYMBOL_INFO* si1, const SYMBOL_INFO* si2)
{
if (si1->NameLen != si2->NameLen) return FALSE;
return !memcmp(si1, si2, sizeof(SYMBOL_INFO) + si1->NameLen);
/* FIXME: !memcmp(si1, si2, sizeof(SYMBOL_INFO) + si1->NameLen)
* is wrong because sizeof(SYMBOL_INFO) can be aligned on 4-byte boundary
* Note: we also need to zero out the structures before calling
* stack_get_frame, so that un-touched fields by stack_get_frame
* get the same value!!
*/
return !memcmp(si1, si2, OFFSET_OF(Name, SYMBOL_INFO)) &&
!memcmp(si1->Name, si2->Name, si1->NameLen);
}
int display_add(struct expr *exp, int count, char format, int in_frame)
@ -74,6 +82,7 @@ int display_add(struct expr *exp, int count, char format, int in_frame)
if (in_frame)
{
displaypoints[i].func = (SYMBOL_INFO*)displaypoints[i].func_buffer;
memset(displaypoints[i].func, 0, sizeof(SYMBOL_INFO));
displaypoints[i].func->SizeOfStruct = sizeof(SYMBOL_INFO);
displaypoints[i].func->MaxNameLen = sizeof(displaypoints[i].func_buffer) -
sizeof(*displaypoints[i].func);
@ -97,6 +106,7 @@ int display_info(void)
const char* info;
func = (SYMBOL_INFO*)buffer;
memset(func, 0, sizeof(SYMBOL_INFO));
func->SizeOfStruct = sizeof(SYMBOL_INFO);
func->MaxNameLen = sizeof(buffer) - sizeof(*func);
if (!stack_get_frame(func, NULL)) return FALSE;
@ -105,6 +115,9 @@ int display_info(void)
{
if (displaypoints[i].exp == NULL) continue;
dbg_printf("%d: ", i + 1);
expr_print(displaypoints[i].exp);
if (displaypoints[i].enabled)
{
if (displaypoints[i].func && !cmp_symbol(displaypoints[i].func, func))
@ -114,10 +127,9 @@ int display_info(void)
}
else
info = " (disabled)";
dbg_printf("%d in %s%s: ",
i + 1, func ? displaypoints[i].func->Name : "", info);
expr_print(displaypoints[i].exp);
dbg_printf("\n");
if (displaypoints[i].func)
dbg_printf(" in %s", displaypoints[i].func->Name);
dbg_printf("%s\n", info);
}
return TRUE;
}
@ -129,7 +141,7 @@ static void print_one_display(int i)
if (displaypoints[i].enabled)
{
lvalue = expr_eval(displaypoints[i].exp);
if (lvalue.typeid == dbg_itype_none)
if (lvalue.type.id == dbg_itype_none)
{
dbg_printf("Unable to evaluate expression ");
expr_print(displaypoints[i].exp);
@ -146,7 +158,8 @@ static void print_one_display(int i)
dbg_printf("(disabled)\n");
else
if (displaypoints[i].format == 'i')
memory_examine(&lvalue, displaypoints[i].count, displaypoints[i].format);
memory_examine((void*)types_extract_as_integer(&lvalue),
displaypoints[i].count, displaypoints[i].format);
else
print_value(&lvalue, displaypoints[i].format, 0);
}
@ -158,6 +171,7 @@ int display_print(void)
SYMBOL_INFO* func;
func = (SYMBOL_INFO*)buffer;
memset(func, 0, sizeof(SYMBOL_INFO));
func->SizeOfStruct = sizeof(SYMBOL_INFO);
func->MaxNameLen = sizeof(buffer) - sizeof(*func);
if (!stack_get_frame(func, NULL)) return FALSE;
@ -226,6 +240,7 @@ int display_enable(int displaynum, int enable)
SYMBOL_INFO* func;
func = (SYMBOL_INFO*)buffer;
memset(func, 0, sizeof(SYMBOL_INFO));
func->SizeOfStruct = sizeof(SYMBOL_INFO);
func->MaxNameLen = sizeof(buffer) - sizeof(*func);
if (!stack_get_frame(func, NULL)) return FALSE;

View File

@ -282,13 +282,13 @@ struct dbg_lvalue expr_eval(struct expr* exp)
struct dbg_lvalue exp2;
unsigned int cexp[5];
DWORD scale1, scale2, scale3;
DWORD type1, type2;
DWORD linear1, linear2;
struct dbg_type type1, type2;
DWORD tag;
const struct dbg_internal_var* div;
rtn.typeid = dbg_itype_none;
rtn.cookie = 0;
rtn.type.id = dbg_itype_none;
rtn.type.module = 0;
rtn.addr.Mode = AddrModeFlat;
rtn.addr.Offset = 0;
rtn.addr.Segment = 0;
@ -300,30 +300,31 @@ struct dbg_lvalue expr_eval(struct expr* exp)
* checking if this is right or not
*/
rtn = expr_eval(exp->un.cast.expr);
linear1 = (DWORD)memory_to_linear_addr(&rtn.addr);
switch (exp->un.cast.cast_to.type)
{
case type_expr_type_id:
if (exp->un.cast.cast_to.u.typeid == dbg_itype_none)
if (exp->un.cast.cast_to.u.type.id == dbg_itype_none)
{
dbg_printf("Can't cast to unknown type\n");
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
}
rtn.typeid = exp->un.cast.cast_to.u.typeid;
rtn.type = exp->un.cast.cast_to.u.type;
break;
case type_expr_udt_class:
case type_expr_udt_struct:
case type_expr_udt_union:
rtn.typeid = types_find_type(linear1, exp->un.cast.cast_to.u.name, SymTagUDT);
if (rtn.typeid == dbg_itype_none)
rtn.type = types_find_type((DWORD)memory_to_linear_addr(&rtn.addr),
exp->un.cast.cast_to.u.name, SymTagUDT);
if (rtn.type.id == dbg_itype_none)
{
dbg_printf("Can't cast to UDT %s\n", exp->un.cast.cast_to.u.name);
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
}
break;
case type_expr_enumeration:
rtn.typeid = types_find_type(linear1, exp->un.cast.cast_to.u.name, SymTagEnum);
if (rtn.typeid == dbg_itype_none)
rtn.type = types_find_type((DWORD)memory_to_linear_addr(&rtn.addr),
exp->un.cast.cast_to.u.name, SymTagEnum);
if (rtn.type.id == dbg_itype_none)
{
dbg_printf("Can't cast to enumeration %s\n", exp->un.cast.cast_to.u.name);
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
@ -335,8 +336,8 @@ struct dbg_lvalue expr_eval(struct expr* exp)
}
for (i = 0; i < exp->un.cast.cast_to.deref_count; i++)
{
rtn.typeid = types_find_pointer(linear1, rtn.typeid);
if (rtn.typeid == dbg_itype_none)
rtn.type = types_find_pointer(&rtn.type);
if (rtn.type.id == dbg_itype_none)
{
dbg_printf("Cannot find pointer type\n");
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
@ -344,18 +345,21 @@ struct dbg_lvalue expr_eval(struct expr* exp)
}
break;
case EXPR_TYPE_STRING:
rtn.typeid = dbg_itype_astring;
rtn.cookie = DLV_HOST;
rtn.cookie = DLV_HOST;
rtn.type.id = dbg_itype_astring;
rtn.type.module = 0;
rtn.addr.Offset = (unsigned int)&exp->un.string.str;
break;
case EXPR_TYPE_U_CONST:
rtn.typeid = dbg_itype_unsigned_int;
rtn.cookie = DLV_HOST;
rtn.type.id = dbg_itype_unsigned_int;
rtn.type.module = 0;
rtn.addr.Offset = (unsigned int)&exp->un.u_const.value;
break;
case EXPR_TYPE_S_CONST:
rtn.typeid = dbg_itype_signed_int;
rtn.cookie = DLV_HOST;
rtn.type.id = dbg_itype_signed_int;
rtn.type.module = 0;
rtn.addr.Offset = (unsigned int)&exp->un.s_const.value;
break;
case EXPR_TYPE_SYMBOL:
@ -373,8 +377,8 @@ struct dbg_lvalue expr_eval(struct expr* exp)
break;
case EXPR_TYPE_PSTRUCT:
exp1 = expr_eval(exp->un.structure.exp1);
if (exp1.typeid == dbg_itype_none || !types_deref(&exp1, &rtn) ||
rtn.typeid == dbg_itype_none)
if (exp1.type.id == dbg_itype_none || !types_deref(&exp1, &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,
&exp->un.structure.result))
@ -385,7 +389,7 @@ struct dbg_lvalue expr_eval(struct expr* exp)
break;
case EXPR_TYPE_STRUCT:
exp1 = expr_eval(exp->un.structure.exp1);
if (exp1.typeid == 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 = exp1;
if (!types_udt_find_element(&rtn, exp->un.structure.element_name,
&exp->un.structure.result))
@ -402,7 +406,7 @@ struct dbg_lvalue expr_eval(struct expr* exp)
for (i = 0; i < exp->un.call.nargs; i++)
{
exp1 = expr_eval(exp->un.call.arg[i]);
if (exp1.typeid == dbg_itype_none)
if (exp1.type.id == dbg_itype_none)
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
cexp[i] = types_extract_as_integer(&exp1);
}
@ -458,93 +462,93 @@ struct dbg_lvalue expr_eval(struct expr* exp)
*/
exp->un.call.result = 0;
#endif
linear1 = (DWORD)memory_to_linear_addr(&rtn.addr);
/* get function signature type */
types_get_info(linear1, rtn.typeid, TI_GET_TYPE, &rtn.typeid);
/* and now, return type */
types_get_info(linear1, rtn.typeid, TI_GET_TYPE, &rtn.typeid);
rtn.cookie = DLV_HOST;
rtn.addr.Mode = AddrModeFlat;
/* get function signature type */
types_get_info(&rtn.type, TI_GET_TYPE, &rtn.type);
/* and now, return type */
types_get_info(&rtn.type, TI_GET_TYPE, &rtn.type);
rtn.addr.Offset = (unsigned int)&exp->un.call.result;
break;
case EXPR_TYPE_INTVAR:
rtn.cookie = DLV_HOST;
if (!(div = dbg_get_internal_var(exp->un.intvar.name)))
RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
rtn.cookie = DLV_HOST;
rtn.typeid = div->typeid;
rtn.type.id = div->typeid;
rtn.type.module = 0;
rtn.addr.Offset = (unsigned int)div->pval;
break;
case EXPR_TYPE_BINOP:
rtn.cookie = DLV_HOST;
exp1 = expr_eval(exp->un.binop.exp1);
exp2 = expr_eval(exp->un.binop.exp2);
rtn.cookie = DLV_HOST;
if (exp1.typeid == dbg_itype_none || exp2.typeid == dbg_itype_none)
if (exp1.type.id == dbg_itype_none || exp2.type.id == dbg_itype_none)
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
linear1 = (DWORD)memory_to_linear_addr(&exp1.addr);
linear2 = (DWORD)memory_to_linear_addr(&exp2.addr);
rtn.typeid = dbg_itype_signed_int;
rtn.type.id = dbg_itype_signed_int;
rtn.type.module = 0;
rtn.addr.Offset = (unsigned int)&exp->un.binop.result;
switch (exp->un.binop.binop_type)
{
case EXP_OP_ADD:
if (!types_get_info(linear1, exp1.typeid, TI_GET_SYMTAG, &tag) ||
if (!types_get_info(&exp1.type, TI_GET_SYMTAG, &tag) ||
tag != SymTagPointerType ||
!types_get_info(linear1, exp1.typeid, TI_GET_TYPE, &type1))
type1 = dbg_itype_none;
if (!types_get_info(linear1, exp2.typeid, TI_GET_SYMTAG, &tag) ||
!types_get_info(&exp1.type, TI_GET_TYPE, &type1))
type1.id = dbg_itype_none;
if (!types_get_info(&exp2.type, TI_GET_SYMTAG, &tag) ||
tag != SymTagPointerType ||
!types_get_info(linear1, exp2.typeid, TI_GET_TYPE, &type2))
type2 = dbg_itype_none;
!types_get_info(&exp2.type, TI_GET_TYPE, &type2))
type2.id = dbg_itype_none;
scale1 = 1;
scale2 = 1;
if (type1 != dbg_itype_none && type2 != dbg_itype_none)
if (type1.id != dbg_itype_none && type2.id != dbg_itype_none)
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
if (type1 != dbg_itype_none)
if (type1.id != dbg_itype_none)
{
types_get_info(linear1, type1, TI_GET_LENGTH, &scale2);
rtn.typeid = exp1.typeid;
types_get_info(&type1, TI_GET_LENGTH, &scale2);
rtn.type = exp1.type;
}
else if (type2 != dbg_itype_none)
else if (type2.id != dbg_itype_none)
{
types_get_info(linear2, type2, TI_GET_LENGTH, &scale1);
rtn.typeid = exp2.typeid;
types_get_info(&type2, TI_GET_LENGTH, &scale1);
rtn.type = exp2.type;
}
exp->un.binop.result = (types_extract_as_integer(&exp1) * scale1 +
scale2 * types_extract_as_integer(&exp2));
break;
case EXP_OP_SUB:
if (!types_get_info(linear1, exp1.typeid, TI_GET_SYMTAG, &tag) ||
if (!types_get_info(&exp1.type, TI_GET_SYMTAG, &tag) ||
tag != SymTagPointerType ||
!types_get_info(linear1, exp1.typeid, TI_GET_TYPE, &type1))
type1 = dbg_itype_none;
if (!types_get_info(linear2, exp2.typeid, TI_GET_SYMTAG, &tag) ||
!types_get_info(&exp1.type, TI_GET_TYPE, &type1))
type1.id = dbg_itype_none;
if (!types_get_info(&exp2.type, TI_GET_SYMTAG, &tag) ||
tag != SymTagPointerType ||
!types_get_info(linear2, exp2.typeid, TI_GET_TYPE, &type2))
type2 = dbg_itype_none;
!types_get_info(&exp2.type, TI_GET_TYPE, &type2))
type2.id = dbg_itype_none;
scale1 = 1;
scale2 = 1;
scale3 = 1;
if (type1 != dbg_itype_none && type2 != dbg_itype_none)
if (type1.id != dbg_itype_none && type2.id != dbg_itype_none)
{
if (type1 != type2) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
types_get_info(linear1, type1, TI_GET_LENGTH, &scale3);
WINE_FIXME("This may fail (if module base address are wrongly calculated)\n");
if (memcmp(&type1, &type2, sizeof(struct dbg_type)))
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
types_get_info(&type1, TI_GET_LENGTH, &scale3);
}
else if (type1 != dbg_itype_none)
else if (type1.id != dbg_itype_none)
{
types_get_info(linear1, type1, TI_GET_LENGTH, &scale2);
rtn.typeid = exp1.typeid;
types_get_info(&type1, TI_GET_LENGTH, &scale2);
rtn.type = exp1.type;
}
else if (type2 != dbg_itype_none)
else if (type2.id != dbg_itype_none)
{
types_get_info(linear2, type2, TI_GET_LENGTH, &scale1);
rtn.typeid = exp2.typeid;
types_get_info(&type2, TI_GET_LENGTH, &scale1);
rtn.type = exp2.type;
}
exp->un.binop.result = (types_extract_as_integer(&exp1) * scale1 -
types_extract_as_integer(&exp2) * scale2) / scale3;
break;
case EXP_OP_SEG:
rtn.cookie = DLV_TARGET;
rtn.typeid = dbg_itype_none;
rtn.type.id = dbg_itype_none;
rtn.type.module = 0;
rtn.addr.Mode = AddrMode1632;
rtn.addr.Segment = types_extract_as_integer(&exp1);
rtn.addr.Offset = types_extract_as_integer(&exp2);
@ -607,11 +611,12 @@ struct dbg_lvalue expr_eval(struct expr* exp)
}
break;
case EXPR_TYPE_UNOP:
exp1 = expr_eval(exp->un.unop.exp1);
if (exp1.typeid == dbg_itype_none) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
rtn.cookie = DLV_HOST;
exp1 = expr_eval(exp->un.unop.exp1);
if (exp1.type.id == dbg_itype_none) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
rtn.addr.Offset = (unsigned int)&exp->un.unop.result;
rtn.typeid = dbg_itype_signed_int;
rtn.type.id = dbg_itype_signed_int;
rtn.type.module = 0;
switch (exp->un.unop.unop_type)
{
case EXP_OP_NEG:
@ -624,19 +629,6 @@ struct dbg_lvalue expr_eval(struct expr* exp)
exp->un.unop.result = ~types_extract_as_integer(&exp1);
break;
case EXP_OP_DEREF:
/* 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
* => exp1 is target, result is target
* x is a pointer to struct s, x being optimized into a reg
* => exp1 is host, result is target
* x is a pointer to internal variable x
* => exp1 is host, result is host
* so we force DLV_TARGET, because dereferencing pointers to
* internal variables is very unlikely. a correct fix would be
* rather large.
*/
if (!types_deref(&exp1, &rtn))
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
break;
@ -650,7 +642,7 @@ struct dbg_lvalue expr_eval(struct expr* exp)
if (exp1.addr.Mode != AddrModeFlat)
RaiseException(DEBUG_STATUS_CANT_DEREF, 0, 0, NULL);
exp->un.unop.result = (unsigned int)memory_to_linear_addr(&exp1.addr);
rtn.typeid = types_find_pointer(exp->un.unop.result, exp1.typeid);
rtn.type = types_find_pointer(&exp1.type);
break;
default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
}
@ -661,14 +653,13 @@ struct dbg_lvalue expr_eval(struct expr* exp)
break;
}
assert(rtn.cookie == DLV_TARGET || rtn.cookie == DLV_HOST);
return rtn;
}
int expr_print(const struct expr* exp)
{
int i;
int i;
struct dbg_type type;
switch (exp->type)
{
@ -678,7 +669,9 @@ int expr_print(const struct expr* exp)
switch (exp->un.cast.cast_to.type)
{
case type_expr_type_id:
types_print_type(0, exp->un.cast.cast_to.type, FALSE); break;
type.module = 0;
type.id = exp->un.cast.cast_to.type;
types_print_type(&type, FALSE); break;
case type_expr_udt_class:
dbg_printf("class %s", exp->un.cast.cast_to.u.name); break;
case type_expr_udt_struct:

View File

@ -468,7 +468,7 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
case OUTPUT_DEBUG_STRING_EVENT:
assert(dbg_curr_thread);
memory_get_string(gdbctx->process->handle,
de->u.DebugString.lpDebugStringData, DLV_TARGET,
de->u.DebugString.lpDebugStringData, TRUE,
de->u.DebugString.fUnicode, buffer, sizeof(buffer));
if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
fprintf(stderr, "%08lx:%08lx: output debug string (%s)\n",

View File

@ -99,7 +99,6 @@ BOOL memory_read_value(const struct dbg_lvalue* lvalue, DWORD size, void* result
}
else
{
assert(lvalue->addr.Mode == AddrModeFlat);
if (!lvalue->addr.Offset) return FALSE;
memcpy(result, (void*)lvalue->addr.Offset, size);
}
@ -118,7 +117,7 @@ BOOL memory_write_value(const struct dbg_lvalue* lvalue, DWORD size, void* value
DWORD linear = (DWORD)memory_to_linear_addr(&lvalue->addr);
os = ~size;
types_get_info(linear, lvalue->typeid, TI_GET_LENGTH, &os);
types_get_info(&lvalue->type, TI_GET_LENGTH, &os);
assert(size == os);
/* FIXME: only works on little endian systems */
@ -128,7 +127,6 @@ BOOL memory_write_value(const struct dbg_lvalue* lvalue, DWORD size, void* value
}
else
{
assert(lvalue->addr.Mode == AddrModeFlat);
memcpy((void*)lvalue->addr.Offset, value, size);
}
return ret;
@ -139,17 +137,18 @@ BOOL memory_write_value(const struct dbg_lvalue* lvalue, DWORD size, void* value
*
* Implementation of the 'x' command.
*/
void memory_examine(const struct dbg_lvalue* lvalue, int count, char format)
void memory_examine(void* linear, int count, char format)
{
int i;
ADDRESS x;
char buffer[256];
ADDRESS addr;
addr.Mode = AddrModeFlat;
addr.Offset = (unsigned long)linear;
x.Mode = AddrModeFlat;
x.Offset = types_extract_as_integer(lvalue);
if (format != 'i' && count > 1)
{
print_address(&x, FALSE);
print_address(&addr, FALSE);
dbg_printf(": ");
}
@ -157,32 +156,33 @@ void memory_examine(const struct dbg_lvalue* lvalue, int count, char format)
{
case 'u':
if (count == 1) count = 256;
memory_get_string(dbg_curr_thread->handle, (void*)x.Offset, lvalue->cookie,
TRUE, buffer, min(count, sizeof(buffer)));
memory_get_string(dbg_curr_process->handle, linear,
TRUE, TRUE, buffer, min(count, sizeof(buffer)));
dbg_printf("%s\n", buffer);
return;
case 's':
if (count == 1) count = 256;
memory_get_string(dbg_curr_thread->handle, (void*)x.Offset, lvalue->cookie,
FALSE, buffer, min(count, sizeof(buffer)));
memory_get_string(dbg_curr_process->handle, linear,
TRUE, FALSE, buffer, min(count, sizeof(buffer)));
dbg_printf("%s\n", buffer);
return;
case 'i':
while (count-- && memory_disasm_one_insn(&x));
while (count-- && memory_disasm_one_insn(&addr));
return;
case 'g':
while (count--)
{
GUID guid;
if (!dbg_read_memory_verbose((void*)x.Offset, &guid, sizeof(guid))) break;
if (!dbg_read_memory_verbose(linear, &guid, sizeof(guid))) break;
dbg_printf("{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
guid.Data1, guid.Data2, guid.Data3,
guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
x.Offset += sizeof(guid);
linear = (char*)linear + sizeof(guid);
addr.Offset += sizeof(guid);
if (count)
{
print_address(&x, FALSE);
print_address(&addr, FALSE);
dbg_printf(": ");
}
}
@ -191,13 +191,15 @@ void memory_examine(const struct dbg_lvalue* lvalue, int count, char format)
#define DO_DUMP2(_t,_l,_f,_vv) { \
_t _v; \
for (i = 0; i < count; i++) { \
if (!dbg_read_memory_verbose((void*)x.Offset, &_v, \
if (!dbg_read_memory_verbose(linear, &_v, \
sizeof(_t))) break; \
dbg_printf(_f, (_vv)); \
x.Offset += sizeof(_t); \
if ((i % (_l)) == (_l) - 1) { \
addr.Offset += sizeof(_t); \
linear = (char*)linear + sizeof(_t); \
if ((i % (_l)) == (_l) - 1 && i != count - 1) \
{ \
dbg_printf("\n"); \
print_address(&x, FALSE); \
print_address(&addr, FALSE); \
dbg_printf(": "); \
} \
} \
@ -214,7 +216,7 @@ void memory_examine(const struct dbg_lvalue* lvalue, int count, char format)
}
}
BOOL memory_get_string(HANDLE hp, void* addr, unsigned cookie, BOOL unicode,
BOOL memory_get_string(HANDLE hp, void* addr, BOOL in_debuggee, BOOL unicode,
char* buffer, int size)
{
DWORD sz;
@ -222,9 +224,8 @@ BOOL memory_get_string(HANDLE hp, void* addr, unsigned cookie, BOOL unicode,
buffer[0] = 0;
if (!addr) return FALSE;
switch (cookie)
if (in_debuggee)
{
case DLV_TARGET:
if (!unicode) return ReadProcessMemory(hp, addr, buffer, size, &sz);
buffW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
@ -232,13 +233,13 @@ BOOL memory_get_string(HANDLE hp, void* addr, unsigned cookie, BOOL unicode,
WideCharToMultiByte(CP_ACP, 0, buffW, sz / sizeof(WCHAR), buffer, size,
NULL, NULL);
HeapFree(GetProcessHeap(), 0, buffW);
return TRUE;
case DLV_HOST:
}
else
{
strncpy(buffer, addr, size);
buffer[size - 1] = 0;
return TRUE;
}
return FALSE;
return TRUE;
}
BOOL memory_get_string_indirect(HANDLE hp, void* addr, BOOL unicode, char* buffer, int size)
@ -250,7 +251,7 @@ BOOL memory_get_string_indirect(HANDLE hp, void* addr, BOOL unicode, char* buffe
if (addr &&
ReadProcessMemory(hp, addr, &ad, sizeof(ad), &sz) && sz == sizeof(ad) && ad)
{
return memory_get_string(hp, ad, DLV_TARGET, unicode, buffer, size);
return memory_get_string(hp, ad, TRUE, unicode, buffer, size);
}
return FALSE;
}
@ -260,20 +261,19 @@ static void print_typed_basic(const struct dbg_lvalue* lvalue)
long long int val_int;
void* val_ptr;
long double val_real;
DWORD tag, size, count, bt, rtype;
DWORD tag, size, count, bt;
struct dbg_type rtype;
DWORD linear = (DWORD)memory_to_linear_addr(&lvalue->addr);
assert(lvalue->cookie == DLV_TARGET || lvalue->cookie == DLV_HOST);
if (lvalue->typeid == dbg_itype_none ||
!types_get_info(linear, lvalue->typeid, TI_GET_SYMTAG, &tag))
if (lvalue->type.id == dbg_itype_none ||
!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
return;
switch (tag)
{
case SymTagBaseType:
if (!types_get_info(linear, lvalue->typeid, TI_GET_LENGTH, &size) ||
!types_get_info(linear, lvalue->typeid, TI_GET_BASETYPE, &bt))
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);
@ -309,20 +309,21 @@ static void print_typed_basic(const struct dbg_lvalue* lvalue)
case SymTagPointerType:
if (!memory_read_value(lvalue, sizeof(void*), &val_ptr)) return;
if (!types_get_info(linear, lvalue->typeid, TI_GET_TYPE, &rtype) ||
rtype == dbg_itype_none)
if (!types_get_info(&lvalue->type, TI_GET_TYPE, &rtype.id) ||
rtype.id == dbg_itype_none)
{
dbg_printf("Internal symbol error: unable to access memory location %p", val_ptr);
break;
}
if (types_get_info(linear, rtype, TI_GET_SYMTAG, &tag) && tag == SymTagBaseType &&
types_get_info(linear, rtype, TI_GET_BASETYPE, &bt) && bt == btChar &&
types_get_info(linear, rtype, TI_GET_LENGTH, &size))
rtype.module = lvalue->type.module;
if (types_get_info(&rtype, TI_GET_SYMTAG, &tag) && tag == SymTagBaseType &&
types_get_info(&rtype, TI_GET_BASETYPE, &bt) && bt == btChar &&
types_get_info(&rtype, TI_GET_LENGTH, &size))
{
char buffer[1024];
memory_get_string(dbg_curr_thread->handle, (void*)val_ptr, lvalue->cookie,
memory_get_string(dbg_curr_process->handle, val_ptr,
lvalue->cookie == DLV_TARGET,
size == 2, buffer, sizeof(buffer));
dbg_printf("\"%s\"", buffer);
}
@ -345,24 +346,27 @@ static void print_typed_basic(const struct dbg_lvalue* lvalue)
*/
if (!be_cpu->fetch_integer(lvalue, 4, TRUE, &val_int)) return;
if (types_get_info(linear, lvalue->typeid, TI_GET_CHILDRENCOUNT, &count))
if (types_get_info(&lvalue->type, TI_GET_CHILDRENCOUNT, &count))
{
char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
WCHAR* ptr;
char tmp[256];
VARIANT variant;
int i;
char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
WCHAR* ptr;
char tmp[256];
VARIANT variant;
int i;
struct dbg_type type;
fcp->Start = 0;
while (count)
{
fcp->Count = min(count, 256);
if (types_get_info(linear, lvalue->typeid, TI_FINDCHILDREN, fcp))
if (types_get_info(&lvalue->type, TI_FINDCHILDREN, fcp))
{
type.module = linear;
for (i = 0; i < min(fcp->Count, count); i++)
{
if (!types_get_info(linear, fcp->ChildId[i], TI_GET_VALUE, &variant))
type.id = fcp->ChildId[i];
if (!types_get_info(&type, TI_GET_VALUE, &variant))
continue;
switch (variant.n1.n2.vt)
{
@ -372,7 +376,7 @@ static void print_typed_basic(const struct dbg_lvalue* lvalue)
if (ok)
{
ptr = NULL;
types_get_info(linear, fcp->ChildId[i], TI_GET_SYMNAME, &ptr);
types_get_info(&type, TI_GET_SYMNAME, &ptr);
if (!ptr) continue;
WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
HeapFree(GetProcessHeap(), 0, ptr);
@ -404,8 +408,7 @@ void print_basic(const struct dbg_lvalue* lvalue, int count, char format)
{
long int res;
assert(lvalue->cookie == DLV_TARGET || lvalue->cookie == DLV_HOST);
if (lvalue->typeid == dbg_itype_none)
if (lvalue->type.id == dbg_itype_none)
{
dbg_printf("Unable to evaluate expression\n");
return;
@ -465,6 +468,9 @@ void print_bare_address(const ADDRESS* addr)
case AddrMode1632:
dbg_printf("0x%04x:0x%08lx", addr->Segment, addr->Offset);
break;
default:
dbg_printf("Unknown mode %x\n", addr->Mode);
break;
}
}
@ -499,7 +505,7 @@ void print_address(const ADDRESS* addr, BOOLEAN with_line)
}
}
struct foo
struct sym_enum
{
char* tmp;
DWORD frame;
@ -507,19 +513,23 @@ struct foo
static BOOL WINAPI sym_enum_cb(SYMBOL_INFO* sym_info, ULONG size, void* user)
{
struct foo* foo = (struct foo*)user;
DWORD addr;
unsigned val;
long offset;
struct sym_enum* se = (struct sym_enum*)user;
DWORD addr;
unsigned val;
long offset;
if ((sym_info->Flags & (SYMFLAG_PARAMETER|SYMFLAG_FRAMEREL)) == (SYMFLAG_PARAMETER|SYMFLAG_FRAMEREL))
{
if (foo->tmp[0]) strcat(foo->tmp, ", ");
addr = foo->frame;
types_get_info(sym_info->ModBase, sym_info->TypeIndex, TI_GET_OFFSET, &offset);
struct dbg_type type;
if (se->tmp[0]) strcat(se->tmp, ", ");
addr = se->frame;
type.module = sym_info->ModBase;
type.id = sym_info->TypeIndex;
types_get_info(&type, TI_GET_OFFSET, &offset);
addr += offset;
dbg_read_memory_verbose((char*)addr, &val, sizeof(val));
sprintf(foo->tmp + strlen(foo->tmp), "%s=0x%x", sym_info->Name, val);
sprintf(se->tmp + strlen(se->tmp), "%s=0x%x", sym_info->Name, val);
}
return TRUE;
}
@ -531,7 +541,7 @@ void print_addr_and_args(const ADDRESS* pc, const ADDRESS* frame)
IMAGEHLP_STACK_FRAME isf;
IMAGEHLP_LINE il;
IMAGEHLP_MODULE im;
struct foo foo;
struct sym_enum se;
char tmp[1024];
DWORD disp;
@ -552,10 +562,10 @@ void print_addr_and_args(const ADDRESS* pc, const ADDRESS* frame)
if (disp) dbg_printf("+0x%lx", disp);
SymSetContext(dbg_curr_process->handle, &isf, NULL);
foo.tmp = tmp;
foo.frame = isf.FrameOffset;
se.tmp = tmp;
se.frame = isf.FrameOffset;
tmp[0] = '\0';
SymEnumSymbols(dbg_curr_process->handle, 0, NULL, sym_enum_cb, &foo);
SymEnumSymbols(dbg_curr_process->handle, 0, NULL, sym_enum_cb, &se);
if (tmp[0]) dbg_printf("(%s)", tmp);
il.SizeOfStruct = sizeof(il);

View File

@ -42,27 +42,24 @@ static IMAGEHLP_STACK_FRAME* frames = NULL;
*/
void stack_info(void)
{
struct dbg_lvalue lvalue;
ADDRESS addr;
lvalue.typeid = dbg_itype_none;
lvalue.cookie = DLV_TARGET;
/* FIXME: we assume stack grows the same way as on i386 */
if (!memory_get_current_stack(&lvalue.addr))
dbg_printf("Bad segment (%d)\n", lvalue.addr.Segment);
if (!memory_get_current_stack(&addr))
dbg_printf("Bad segment (%d)\n", addr.Segment);
dbg_printf("Stack dump:\n");
switch (lvalue.addr.Mode)
switch (addr.Mode)
{
case AddrModeFlat: /* 32-bit mode */
case AddrMode1632: /* 32-bit mode */
memory_examine(&lvalue, 24, 'x');
memory_examine(memory_to_linear_addr(&addr), 24, 'x');
break;
case AddrModeReal: /* 16-bit mode */
case AddrMode1616:
memory_examine(&lvalue, 24, 'w');
memory_examine(memory_to_linear_addr(&addr), 24, 'w');
break;
}
dbg_printf("\n");
}
int stack_set_frame(int newframe)

View File

@ -38,19 +38,24 @@ static BOOL symbol_get_debug_start(DWORD mod_base, DWORD typeid, DWORD* start)
char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
int i;
struct dbg_type type;
if (!types_get_info(mod_base, typeid, TI_GET_CHILDRENCOUNT, &count)) return FALSE;
type.module = mod_base;
type.id = typeid;
if (!types_get_info(&type, TI_GET_CHILDRENCOUNT, &count)) return FALSE;
fcp->Start = 0;
while (count)
{
fcp->Count = min(count, 256);
if (types_get_info(mod_base, typeid, TI_FINDCHILDREN, fcp))
if (types_get_info(&type, TI_FINDCHILDREN, fcp))
{
for (i = 0; i < min(fcp->Count, count); i++)
{
types_get_info(mod_base, fcp->ChildId[i], TI_GET_SYMTAG, &tag);
type.id = fcp->ChildId[i];
types_get_info(&type, TI_GET_SYMTAG, &tag);
if (tag != SymTagFuncDebugStart) continue;
return types_get_info(mod_base, fcp->ChildId[i], TI_GET_ADDRESS, start);
return types_get_info(&type, TI_GET_ADDRESS, start);
}
count -= min(count, 256);
fcp->Start += 256;
@ -107,7 +112,11 @@ static BOOL CALLBACK sgv_cb(SYMBOL_INFO* sym, ULONG size, void* ctx)
else if (sym->Flags & SYMFLAG_FRAMEREL)
{
ULONG offset;
types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_OFFSET, &offset);
struct dbg_type type;
type.module = sym->ModBase;
type.id = sym->TypeIndex;
types_get_info(&type, TI_GET_OFFSET, &offset);
addr = sgv->ihsf.FrameOffset + offset;
}
else if (sym->Flags & SYMFLAG_THUNK)
@ -175,11 +184,13 @@ static BOOL CALLBACK sgv_cb(SYMBOL_INFO* sym, ULONG size, void* ctx)
memmove(&sgv->syms[insp + 1], &sgv->syms[insp],
sizeof(sgv->syms[0]) * sgv->num_thunks);
}
sgv->syms[insp].lvalue.cookie = cookie;
sgv->syms[insp].lvalue.addr.Mode = AddrModeFlat;
sgv->syms[insp].lvalue.addr.Offset = addr;
types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_TYPE,
&sgv->syms[insp].lvalue.typeid);
sgv->syms[insp].lvalue.cookie = cookie;
sgv->syms[insp].lvalue.type.module = sym->ModBase;
sgv->syms[insp].lvalue.type.id = sym->TypeIndex;
types_get_info(&sgv->syms[insp].lvalue.type, TI_GET_TYPE,
&sgv->syms[insp].lvalue.type.id);
sgv->syms[insp].flags = sym->Flags;
sgv->num++;
@ -314,8 +325,9 @@ enum sym_get_lval symbol_get_lvalue(const char* name, const int lineno,
}
else
{
dbg_printf("More than one symbol named %s, picking the first one\n", name);
i = 0;
/* FIXME: could display the list of non-picked up symbols */
if (sgv.num > 1)
dbg_printf("More than one symbol named %s, picking the first one\n", name);
}
*rtn = sgv.syms[i].lvalue;
return sglv_found;
@ -390,6 +402,7 @@ enum dbg_line_status symbol_get_function_line_status(const ADDRESS* addr)
DWORD lin = (DWORD)memory_to_linear_addr(addr);
char buffer[sizeof(SYMBOL_INFO) + 256];
SYMBOL_INFO* sym = (SYMBOL_INFO*)buffer;
struct dbg_type type;
il.SizeOfStruct = sizeof(il);
sym->SizeOfStruct = sizeof(SYMBOL_INFO);
@ -419,7 +432,9 @@ enum dbg_line_status symbol_get_function_line_status(const ADDRESS* addr)
if (symbol_get_debug_start(sym->ModBase, sym->TypeIndex, &start) && lin < start)
return dbg_not_on_a_line_number;
if (!types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_LENGTH, &size) || size == 0)
type.module = sym->ModBase;
type.id = sym->TypeIndex;
if (!types_get_info(&type, TI_GET_LENGTH, &size) || size == 0)
size = 0x100000;
if (il.FileName && il.FileName[0] && disp < size)
return (disp == 0) ? dbg_on_a_line_number : dbg_not_on_a_line_number;
@ -492,14 +507,16 @@ BOOL symbol_get_line(const char* filename, const char* name, IMAGEHLP_LINE* line
static BOOL CALLBACK info_locals_cb(SYMBOL_INFO* sym, ULONG size, void* ctx)
{
DWORD tid;
ULONG v, val;
const char* explain = NULL;
char buf[128];
ULONG v, val;
const char* explain = NULL;
char buf[128];
struct dbg_type type;
dbg_printf("\t");
types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_TYPE, &tid);
types_print_type(sym->ModBase, tid, FALSE);
type.module = sym->ModBase;
type.id = sym->TypeIndex;
types_get_info(&type, TI_GET_TYPE, &type.id);
types_print_type(&type, FALSE);
if (sym->Flags & SYMFLAG_LOCAL) explain = "local";
else if (sym->Flags & SYMFLAG_PARAMETER) explain = "parameter";
@ -527,7 +544,8 @@ static BOOL CALLBACK info_locals_cb(SYMBOL_INFO* sym, ULONG size, void* ctx)
}
else if (sym->Flags & SYMFLAG_FRAMEREL)
{
types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_OFFSET, &v);
type.id = sym->TypeIndex;
types_get_info(&type, TI_GET_OFFSET, &v);
v += ((IMAGEHLP_STACK_FRAME*)ctx)->FrameOffset;
dbg_read_memory_verbose((void*)v, &val, sizeof(val));
@ -556,13 +574,13 @@ int symbol_info_locals(void)
static BOOL CALLBACK symbols_info_cb(SYMBOL_INFO* sym, ULONG size, void* ctx)
{
DWORD type;
struct dbg_type type;
dbg_printf("%08lx: %s (", sym->Address, sym->Name);
if (sym->TypeIndex != dbg_itype_none && sym->TypeIndex != 0 &&
types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_TYPE, &type))
types_get_info(&type, TI_GET_TYPE, &type.id))
{
types_print_type(sym->ModBase, type, FALSE);
types_print_type(&type, FALSE);
}
dbg_printf(")\n");
return TRUE;

View File

@ -39,19 +39,16 @@ long int types_extract_as_integer(const struct dbg_lvalue* lvalue)
{
long int rtn = 0;
DWORD tag, size, bt;
DWORD linear = (DWORD)memory_to_linear_addr(&lvalue->addr);
assert(lvalue->cookie == DLV_TARGET || lvalue->cookie == DLV_HOST);
if (lvalue->typeid == dbg_itype_none ||
!types_get_info(linear, lvalue->typeid, TI_GET_SYMTAG, &tag))
if (lvalue->type.id == dbg_itype_none ||
!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
return 0;
switch (tag)
{
case SymTagBaseType:
if (!types_get_info(linear, lvalue->typeid, TI_GET_LENGTH, &size) ||
!types_get_info(linear, lvalue->typeid, TI_GET_BASETYPE, &bt))
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);
@ -107,23 +104,34 @@ long int types_extract_as_integer(const struct dbg_lvalue* lvalue)
BOOL types_deref(const struct dbg_lvalue* lvalue, struct dbg_lvalue* result)
{
DWORD tag;
DWORD linear = (DWORD)memory_to_linear_addr(&lvalue->addr);
assert(lvalue->cookie == DLV_TARGET || lvalue->cookie == DLV_HOST);
memset(result, 0, sizeof(*result));
result->typeid = dbg_itype_none;
result->type.id = dbg_itype_none;
result->type.module = 0;
/*
* Make sure that this really makes sense.
*/
if (!types_get_info(linear, lvalue->typeid, TI_GET_SYMTAG, &tag) ||
if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag) ||
tag != SymTagPointerType ||
memory_read_value(lvalue, sizeof(result->addr.Offset), &result->addr.Offset) ||
!types_get_info(linear, lvalue->typeid, TI_GET_TYPE, &result->typeid))
!types_get_info(&lvalue->type, TI_GET_TYPE, &result->type.id))
return FALSE;
result->cookie = DLV_TARGET; /* see comment on DEREF below */
result->type.module = lvalue->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;
}
@ -133,19 +141,20 @@ BOOL types_deref(const struct dbg_lvalue* lvalue, struct dbg_lvalue* result)
*
* Implement a structure derefencement
*/
static BOOL types_get_udt_element_lvalue(struct dbg_lvalue* lvalue, DWORD linear,
DWORD typeid, long int* tmpbuf)
static BOOL types_get_udt_element_lvalue(struct dbg_lvalue* lvalue,
const struct dbg_type* type, long int* tmpbuf)
{
DWORD offset, length, bitoffset;
DWORD bt;
unsigned mask;
types_get_info(linear, typeid, TI_GET_TYPE, &lvalue->typeid);
types_get_info(linear, typeid, TI_GET_OFFSET, &offset);
types_get_info(type, TI_GET_TYPE, &lvalue->type.id);
lvalue->type.module = type->module;
types_get_info(type, TI_GET_OFFSET, &offset);
if (types_get_info(linear, typeid, TI_GET_BITPOSITION, &bitoffset))
if (types_get_info(type, TI_GET_BITPOSITION, &bitoffset))
{
types_get_info(linear, typeid, TI_GET_LENGTH, &length);
types_get_info(type, TI_GET_LENGTH, &length);
if (length > sizeof(*tmpbuf)) return FALSE;
/*
* Bitfield operation. We have to extract the field and store
@ -157,8 +166,7 @@ static BOOL types_get_udt_element_lvalue(struct dbg_lvalue* lvalue, DWORD linear
*tmpbuf >>= bitoffset & 7;
*tmpbuf &= ~mask;
lvalue->cookie = DLV_HOST;
lvalue->addr.Mode = AddrModeFlat;
lvalue->cookie = DLV_HOST;
lvalue->addr.Offset = (DWORD)tmpbuf;
/*
@ -166,14 +174,14 @@ static BOOL types_get_udt_element_lvalue(struct dbg_lvalue* lvalue, DWORD linear
* Check to see whether the basic type is signed or not, and if so,
* we need to sign extend the number.
*/
if (types_get_info(linear, lvalue->typeid, TI_GET_BASETYPE, &bt) &&
if (types_get_info(&lvalue->type, TI_GET_BASETYPE, &bt) &&
bt == btInt && (*tmpbuf & (1 << (length - 1))))
{
*tmpbuf |= mask;
}
return TRUE;
}
if (types_get_info(linear, typeid, TI_GET_OFFSET, &offset))
if (types_get_info(type, TI_GET_OFFSET, &offset))
{
lvalue->addr.Offset += offset;
return TRUE;
@ -187,39 +195,38 @@ static BOOL types_get_udt_element_lvalue(struct dbg_lvalue* lvalue, DWORD linear
*/
BOOL types_udt_find_element(struct dbg_lvalue* lvalue, const char* name, long int* tmpbuf)
{
DWORD linear = (DWORD)memory_to_linear_addr(&lvalue->addr);
DWORD tag, count;
char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
WCHAR* ptr;
char tmp[256];
int i;
struct dbg_type type;
assert(lvalue->cookie == DLV_TARGET || lvalue->cookie == DLV_HOST);
if (!types_get_info(linear, lvalue->typeid, TI_GET_SYMTAG, &tag) ||
if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag) ||
tag != SymTagUDT)
return FALSE;
if (types_get_info(linear, lvalue->typeid, TI_GET_CHILDRENCOUNT, &count))
if (types_get_info(&lvalue->type, TI_GET_CHILDRENCOUNT, &count))
{
fcp->Start = 0;
while (count)
{
fcp->Count = min(count, 256);
if (types_get_info(linear, lvalue->typeid, TI_FINDCHILDREN, fcp))
if (types_get_info(&lvalue->type, TI_FINDCHILDREN, fcp))
{
type.module = lvalue->type.module;
for (i = 0; i < min(fcp->Count, count); i++)
{
ptr = NULL;
types_get_info(linear, fcp->ChildId[i], TI_GET_SYMNAME, &ptr);
type.id = fcp->ChildId[i];
types_get_info(&type, TI_GET_SYMNAME, &ptr);
if (!ptr) continue;
WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
HeapFree(GetProcessHeap(), 0, ptr);
if (strcmp(tmp, name)) continue;
return types_get_udt_element_lvalue(lvalue, linear,
fcp->ChildId[i], tmpbuf);
return types_get_udt_element_lvalue(lvalue, &type, tmpbuf);
}
}
count -= min(count, 256);
@ -238,26 +245,23 @@ BOOL types_array_index(const struct dbg_lvalue* lvalue, int index,
struct dbg_lvalue* result)
{
DWORD tag, length, count;
DWORD linear = (DWORD)memory_to_linear_addr(&lvalue->addr);
assert(lvalue->cookie == DLV_TARGET || lvalue->cookie == DLV_HOST);
if (!types_get_info(0, lvalue->typeid, TI_GET_SYMTAG, &tag))
if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
return FALSE;
switch (tag)
{
case SymTagArrayType:
types_get_info(linear, lvalue->typeid, TI_GET_COUNT, &count);
types_get_info(&lvalue->type, TI_GET_COUNT, &count);
if (index < 0 || index >= count) return FALSE;
/* fall through */
case SymTagPointerType:
/*
* Get the base type, so we know how much to index by.
*/
types_get_info(linear, lvalue->typeid, TI_GET_TYPE, &result->typeid);
types_get_info(linear, result->typeid, TI_GET_LENGTH, &length);
types_get_info(&lvalue->type, TI_GET_TYPE, &result->type.id);
result->type.module = lvalue->type.module;
types_get_info(&result->type, TI_GET_LENGTH, &length);
/* Contents of array must be on same target */
result->cookie = lvalue->cookie;
result->addr.Mode = lvalue->addr.Mode;
memory_read_value(lvalue, sizeof(result->addr.Offset), &result->addr.Offset);
result->addr.Offset += index * length;
@ -283,7 +287,7 @@ static BOOL CALLBACK types_cb(PSYMBOL_INFO sym, ULONG size, void* _user)
{
struct type_find_t* user = (struct type_find_t*)_user;
BOOL ret = TRUE;
DWORD typeid;
struct dbg_type type;
if (sym->Tag == user->tag)
{
@ -297,9 +301,9 @@ static BOOL CALLBACK types_cb(PSYMBOL_INFO sym, ULONG size, void* _user)
}
break;
case SymTagPointerType:
types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_TYPE, &typeid);
if (types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_TYPE, &typeid) &&
typeid == user->u.typeid)
type.module = sym->ModBase;
type.id = sym->TypeIndex;
if (types_get_info(&type, TI_GET_TYPE, &type.id) && type.id == user->u.typeid)
{
user->result = sym->TypeIndex;
ret = FALSE;
@ -316,14 +320,18 @@ static BOOL CALLBACK types_cb(PSYMBOL_INFO sym, ULONG size, void* _user)
* Should look up in module based at linear whether (typeid*) exists
* Otherwise, we could create it locally
*/
unsigned long types_find_pointer(unsigned long linear, unsigned long typeid)
struct dbg_type types_find_pointer(const struct dbg_type* type)
{
struct type_find_t f;
struct dbg_type ret;
f.result = dbg_itype_none;
f.tag = SymTagPointerType;
f.u.typeid = typeid;
SymEnumTypes(dbg_curr_process->handle, linear, types_cb, &f);
return f.result;
f.u.typeid = type->id;
SymEnumTypes(dbg_curr_process->handle, type->module, types_cb, &f);
ret.module = type->module;
ret.id = f.result;
return ret;
}
/******************************************************************
@ -332,15 +340,19 @@ unsigned long types_find_pointer(unsigned long linear, unsigned long typeid)
* Should look up in the module based at linear address whether a type
* named 'name' and with the correct tag exists
*/
unsigned long types_find_type(unsigned long linear, const char* name, enum SymTagEnum tag)
struct dbg_type types_find_type(unsigned long linear, const char* name, enum SymTagEnum tag)
{
struct type_find_t f;
struct dbg_type ret;
f.result = dbg_itype_none;
f.tag = tag;
f.u.name = name;
SymEnumTypes(dbg_curr_process->handle, linear, types_cb, &f);
return f.result;
ret.module = linear;
ret.id = f.result;
return ret;
}
/***********************************************************************
@ -352,15 +364,11 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level)
{
struct dbg_lvalue lvalue_field;
int i;
unsigned long linear;
DWORD tag;
DWORD count;
DWORD size;
assert(lvalue->cookie == DLV_TARGET || lvalue->cookie == DLV_HOST);
linear = (unsigned long)memory_to_linear_addr(&lvalue->addr);
if (lvalue->typeid == dbg_itype_none)
if (lvalue->type.id == dbg_itype_none)
{
/* No type, just print the addr value */
print_bare_address(&lvalue->addr);
@ -373,7 +381,7 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level)
format = '\0';
}
if (!types_get_info(linear, lvalue->typeid, TI_GET_SYMTAG, &tag))
if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
{
WINE_FIXME("---error\n");
return;
@ -386,32 +394,34 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level)
print_basic(lvalue, 1, format);
break;
case SymTagUDT:
if (types_get_info(linear, lvalue->typeid, TI_GET_CHILDRENCOUNT, &count))
if (types_get_info(&lvalue->type, TI_GET_CHILDRENCOUNT, &count))
{
char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
WCHAR* ptr;
char tmp[256];
long int tmpbuf;
struct dbg_type type;
dbg_printf("{");
fcp->Start = 0;
while (count)
{
fcp->Count = min(count, 256);
if (types_get_info(linear, lvalue->typeid, TI_FINDCHILDREN, fcp))
if (types_get_info(&lvalue->type, TI_FINDCHILDREN, fcp))
{
for (i = 0; i < min(fcp->Count, count); i++)
{
ptr = NULL;
types_get_info(linear, fcp->ChildId[i], TI_GET_SYMNAME, &ptr);
type.module = (unsigned long)memory_to_linear_addr(&lvalue->addr);
type.id = fcp->ChildId[i];
types_get_info(&type, TI_GET_SYMNAME, &ptr);
if (!ptr) continue;
WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
dbg_printf("%s=", tmp);
HeapFree(GetProcessHeap(), 0, ptr);
lvalue_field = *lvalue;
if (types_get_udt_element_lvalue(&lvalue_field, linear,
fcp->ChildId[i], &tmpbuf))
if (types_get_udt_element_lvalue(&lvalue_field, &type, &tmpbuf))
{
print_value(&lvalue_field, format, level + 1);
}
@ -429,8 +439,8 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level)
* Loop over all of the entries, printing stuff as we go.
*/
count = 1; size = 1;
types_get_info(linear, lvalue->typeid, TI_GET_COUNT, &count);
types_get_info(linear, lvalue->typeid, TI_GET_LENGTH, &size);
types_get_info(&lvalue->type, TI_GET_COUNT, &count);
types_get_info(&lvalue->type, TI_GET_LENGTH, &size);
if (size == count)
{
@ -441,14 +451,14 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level)
*/
/* FIXME should check basic type here (should be a char!!!!)... */
len = min(count, sizeof(buffer));
memory_get_string(dbg_curr_thread->handle,
memory_get_string(dbg_curr_process->handle,
memory_to_linear_addr(&lvalue->addr),
lvalue->cookie, TRUE, buffer, len);
lvalue->cookie == DLV_TARGET, TRUE, buffer, len);
dbg_printf("\"%s%s\"", buffer, (len < count) ? "..." : "");
break;
}
lvalue_field = *lvalue;
types_get_info(linear, lvalue->typeid, TI_GET_TYPE, &lvalue_field.typeid);
types_get_info(&lvalue->type, TI_GET_TYPE, &lvalue_field.type.id);
dbg_printf("{");
for (i = 0; i < count; i++)
{
@ -461,7 +471,7 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level)
dbg_printf("Function ");
print_bare_address(&lvalue->addr);
dbg_printf(": ");
types_print_type(linear, lvalue->typeid, FALSE);
types_print_type(&lvalue->type, FALSE);
break;
default:
WINE_FIXME("Unknown tag (%lu)\n", tag);
@ -476,7 +486,11 @@ leave:
static BOOL CALLBACK print_types_cb(PSYMBOL_INFO sym, ULONG size, void* ctx)
{
types_print_type(sym->ModBase, sym->TypeIndex, TRUE);
struct dbg_type type;
type.module = sym->ModBase;
type.id = sym->TypeIndex;
dbg_printf("Mod: %08lx ID: %08lx \n", type.module, type.id);
types_print_type(&type, TRUE);
dbg_printf("\n");
return TRUE;
}
@ -492,20 +506,21 @@ int print_types(void)
return 0;
}
int types_print_type(DWORD linear, DWORD typeid, BOOL details)
int types_print_type(const struct dbg_type* type, BOOL details)
{
WCHAR* ptr;
char tmp[256];
const char* name;
DWORD tag, subtype, count;
DWORD tag, udt, count;
struct dbg_type subtype;
if (typeid == dbg_itype_none || !types_get_info(linear, typeid, TI_GET_SYMTAG, &tag))
if (type->id == dbg_itype_none || !types_get_info(type, TI_GET_SYMTAG, &tag))
{
dbg_printf("--invalid--<%lxh>--", typeid);
dbg_printf("--invalid--<%lxh>--", type->id);
return FALSE;
}
if (types_get_info(linear, typeid, TI_GET_SYMNAME, &ptr) && ptr)
if (types_get_info(type, TI_GET_SYMNAME, &ptr) && ptr)
{
WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
name = tmp;
@ -519,47 +534,50 @@ int types_print_type(DWORD linear, DWORD typeid, BOOL details)
if (details) dbg_printf("Basic<%s>", name); else dbg_printf("%s", name);
break;
case SymTagPointerType:
types_get_info(linear, typeid, TI_GET_TYPE, &subtype);
types_print_type(linear, subtype, details);
types_get_info(type, TI_GET_TYPE, &subtype.id);
subtype.module = type->module;
types_print_type(&subtype, FALSE);
dbg_printf("*");
break;
case SymTagUDT:
types_get_info(linear, typeid, TI_GET_UDTKIND, &subtype);
switch (subtype)
types_get_info(type, TI_GET_UDTKIND, &udt);
switch (udt)
{
case UdtStruct: dbg_printf("struct %s", name); break;
case UdtUnion: dbg_printf("union %s", name); break;
case UdtClass: dbg_printf("class %s", name); break;
}
if (details &&
types_get_info(linear, typeid, TI_GET_CHILDRENCOUNT, &count))
types_get_info(type, TI_GET_CHILDRENCOUNT, &count))
{
char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
WCHAR* ptr;
char tmp[256];
int i;
struct dbg_type type_elt;
dbg_printf(" {");
fcp->Start = 0;
while (count)
{
fcp->Count = min(count, 256);
if (types_get_info(linear, typeid, TI_FINDCHILDREN, fcp))
if (types_get_info(type, TI_FINDCHILDREN, fcp))
{
for (i = 0; i < min(fcp->Count, count); i++)
{
ptr = NULL;
types_get_info(linear, fcp->ChildId[i], TI_GET_SYMNAME, &ptr);
type_elt.module = type->module;
type_elt.id = fcp->ChildId[i];
types_get_info(&type_elt, TI_GET_SYMNAME, &ptr);
if (!ptr) continue;
WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
HeapFree(GetProcessHeap(), 0, ptr);
dbg_printf("%s", tmp);
if (types_get_info(linear, fcp->ChildId[i], TI_GET_TYPE, &subtype))
if (types_get_info(&type_elt, TI_GET_TYPE, &type_elt.id))
{
dbg_printf(":");
types_print_type(linear, subtype, details);
types_print_type(&type_elt, details);
}
if (i < min(fcp->Count, count) - 1 || count > 256) dbg_printf(", ");
}
@ -571,18 +589,20 @@ int types_print_type(DWORD linear, DWORD typeid, BOOL details)
}
break;
case SymTagArrayType:
types_get_info(linear, typeid, TI_GET_TYPE, &subtype);
types_print_type(linear, subtype, details);
types_get_info(type, TI_GET_TYPE, &subtype.id);
subtype.module = type->module;
types_print_type(&subtype, details);
dbg_printf(" %s[]", name);
break;
case SymTagEnum:
dbg_printf("enum %s", name);
break;
case SymTagFunctionType:
types_get_info(linear, typeid, TI_GET_TYPE, &subtype);
types_print_type(linear, subtype, FALSE);
types_get_info(type, TI_GET_TYPE, &subtype.id);
subtype.module = type->module;
types_print_type(&subtype, FALSE);
dbg_printf(" (*%s)(", name);
if (types_get_info(linear, typeid, TI_GET_CHILDRENCOUNT, &count))
if (types_get_info(type, TI_GET_CHILDRENCOUNT, &count))
{
char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
@ -592,11 +612,12 @@ int types_print_type(DWORD linear, DWORD typeid, BOOL details)
while (count)
{
fcp->Count = min(count, 256);
if (types_get_info(linear, typeid, TI_FINDCHILDREN, fcp))
if (types_get_info(type, TI_FINDCHILDREN, fcp))
{
for (i = 0; i < min(fcp->Count, count); i++)
{
types_print_type(linear, fcp->ChildId[i], FALSE);
subtype.id = fcp->ChildId[i];
types_print_type(&subtype, FALSE);
if (i < min(fcp->Count, count) - 1 || count > 256) dbg_printf(", ");
}
}
@ -614,31 +635,17 @@ int types_print_type(DWORD linear, DWORD typeid, BOOL details)
return TRUE;
}
BOOL types_get_info(unsigned long modbase, unsigned long typeid,
IMAGEHLP_SYMBOL_TYPE_INFO ti, void* pInfo)
BOOL types_get_info(const struct dbg_type* type, IMAGEHLP_SYMBOL_TYPE_INFO ti, void* pInfo)
{
if (typeid == dbg_itype_none) return FALSE;
if (typeid < dbg_itype_first)
{
BOOL ret;
DWORD tag;
ret = SymGetTypeInfo(dbg_curr_process->handle, modbase, typeid, ti, pInfo);
if (!ret && ti == TI_GET_LENGTH &&
(!SymGetTypeInfo(dbg_curr_process->handle, modbase, typeid,
TI_GET_SYMTAG, &tag) || tag == SymTagData))
{
WINE_FIXME("get length on symtag data is no longer supported\n");
assert(0);
}
return ret;
}
assert(modbase);
if (type->id == dbg_itype_none) return FALSE;
if (type->module != 0)
return SymGetTypeInfo(dbg_curr_process->handle, type->module, type->id, ti, pInfo);
assert(type->id >= dbg_itype_first);
/* helper to typecast pInfo to its expected type (_t) */
#define X(_t) (*((_t*)pInfo))
switch (typeid)
switch (type->id)
{
case dbg_itype_unsigned_int:
switch (ti)
@ -712,7 +719,7 @@ BOOL types_get_info(unsigned long modbase, unsigned long typeid,
default: WINE_FIXME("unsupported %u for a string\n", ti); return FALSE;
}
break;
default: WINE_FIXME("unsupported typeid 0x%lx\n", typeid);
default: WINE_FIXME("unsupported type id 0x%lx\n", type->id);
}
#undef X

View File

@ -45,6 +45,9 @@
* + make the output as close as possible to what gdb does
* - symbol management:
* + symbol table loading is broken
* + in symbol_get_lvalue, we don't do any scoping (as C does) between local and
* global vars (we may need this to force some display for example). A solution
* would be always to return arrays with: local vars, global vars, thunks
* - type management:
* + some bits of internal types are missing (like type casts and the address
* operator)
@ -55,7 +58,10 @@
* o bitfield size is on a 4-bytes
* + some bits of internal types are missing (like type casts and the address
* operator)
* - execution
* - execution:
* + display: we shouldn't need to tell whether a display is local or not. This
* should be automatically guessed by checking whether the variables that are
* references are local or not
* + set a better fix for gdb (proxy mode) than the step-mode hack
* + implement function call in debuggee
* + trampoline management is broken when getting 16 <=> 32 thunk destination
@ -339,6 +345,8 @@ struct dbg_thread* dbg_add_thread(struct dbg_process* p, DWORD tid,
t->wait_for_first_exception = 0;
t->exec_mode = dbg_exec_cont;
t->exec_count = 0;
t->step_over_bp.enabled = FALSE;
t->step_over_bp.refcount = 0;
snprintf(t->name, sizeof(t->name), "0x%08lx", tid);
@ -354,8 +362,8 @@ static void dbg_init_current_thread(void* start)
{
if (start)
{
if (dbg_curr_thread->process->threads &&
!dbg_curr_thread->process->threads->next && /* first thread ? */
if (dbg_curr_process->threads &&
!dbg_curr_process->threads->next && /* first thread ? */
DBG_IVAR(BreakAllThreadsStartup))
{
ADDRESS addr;
@ -562,8 +570,7 @@ static DWORD dbg_handle_exception(EXCEPTION_RECORD* rec, BOOL first_chance,
else
pThread = dbg_get_thread(dbg_curr_process, pThreadName->dwThreadID);
if (ReadProcessMemory(dbg_curr_thread->process->handle, pThreadName->szName,
pThread->name, 9, NULL))
if (dbg_read_memory(pThreadName->szName, pThread->name, 9))
dbg_printf("Thread ID=0x%lx renamed using MS VC6 extension (name==\"%s\")\n",
pThread->tid, pThread->name);
return DBG_CONTINUE;
@ -636,11 +643,11 @@ static DWORD dbg_handle_exception(EXCEPTION_RECORD* rec, BOOL first_chance,
case EXCEPTION_WINE_STUB:
{
char dll[32], name[64];
memory_get_string(dbg_curr_thread->process->handle,
(void*)rec->ExceptionInformation[0], DLV_TARGET, FALSE,
memory_get_string(dbg_curr_process->handle,
(void*)rec->ExceptionInformation[0], TRUE, FALSE,
dll, sizeof(dll));
memory_get_string(dbg_curr_thread->process->handle,
(void*)rec->ExceptionInformation[1], DLV_TARGET, FALSE,
memory_get_string(dbg_curr_process->handle,
(void*)rec->ExceptionInformation[1], TRUE, FALSE,
name, sizeof(name));
dbg_printf("unimplemented function %s.%s called", dll, name);
}
@ -854,7 +861,7 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de)
WINE_ERR("Unknown thread\n");
break;
}
memory_get_string_indirect(dbg_curr_thread->process->handle,
memory_get_string_indirect(dbg_curr_process->handle,
de->u.LoadDll.lpImageName,
de->u.LoadDll.fUnicode,
buffer, sizeof(buffer));
@ -894,8 +901,8 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de)
break;
}
memory_get_string(dbg_curr_thread->process->handle,
de->u.DebugString.lpDebugStringData, DLV_TARGET,
memory_get_string(dbg_curr_process->handle,
de->u.DebugString.lpDebugStringData, TRUE,
de->u.DebugString.fUnicode, buffer, sizeof(buffer));
WINE_TRACE("%08lx:%08lx: output debug string (%s)\n",
de->dwProcessId, de->dwThreadId, buffer);