mirror of
git://source.winehq.org/git/wine.git
synced 2024-07-21 09:34:11 +00:00
- 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:
parent
07a805127a
commit
926f66186f
|
@ -1683,17 +1683,19 @@ set $BreakAllThreadsStartup = 1
|
||||||
<tbody>
|
<tbody>
|
||||||
<row>
|
<row>
|
||||||
<entry>
|
<entry>
|
||||||
<msgtext>
|
<command>info display</command>
|
||||||
<simplelist type="inline">
|
|
||||||
<member><command>display</command></member>
|
|
||||||
<member>
|
|
||||||
<command>info display</command>
|
|
||||||
</member>
|
|
||||||
</simplelist>
|
|
||||||
</msgtext>
|
|
||||||
</entry>
|
</entry>
|
||||||
<entry>lists the active displays</entry>
|
<entry>lists the active displays</entry>
|
||||||
</row>
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>
|
||||||
|
<command>display</command>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
print the active displays' values (as done each
|
||||||
|
time the debugger stops)
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry>
|
<entry>
|
||||||
<command>display <expr></command>
|
<command>display <expr></command>
|
||||||
|
|
|
@ -59,8 +59,7 @@ void break_set_xpoints(BOOL set)
|
||||||
|
|
||||||
for (i = 0; i < dbg_curr_process->next_bp; i++)
|
for (i = 0; i < dbg_curr_process->next_bp; i++)
|
||||||
{
|
{
|
||||||
if (!bp[i].refcount && !bp[i].enabled)
|
if (!bp[i].refcount || !bp[i].enabled) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
if (bp[i].xpoint_type == be_xpoint_break)
|
if (bp[i].xpoint_type == be_xpoint_break)
|
||||||
size = 0;
|
size = 0;
|
||||||
|
@ -78,8 +77,9 @@ void break_set_xpoints(BOOL set)
|
||||||
bp[i].info, size);
|
bp[i].info, size);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
{
|
{
|
||||||
dbg_printf("Invalid address (%p) for breakpoint %d, disabling it\n",
|
dbg_printf("Invalid address (");
|
||||||
addr, i);
|
print_address(&bp[i].addr, FALSE);
|
||||||
|
dbg_printf(") for breakpoint %d, disabling it\n", i);
|
||||||
bp[i].enabled = FALSE;
|
bp[i].enabled = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -375,10 +375,9 @@ void break_add_watch(const struct dbg_lvalue* lvalue, BOOL is_write)
|
||||||
&lvalue->addr);
|
&lvalue->addr);
|
||||||
if (num == -1) return;
|
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),
|
if (types_get_info(&lvalue->type, TI_GET_LENGTH, &l))
|
||||||
lvalue->typeid, TI_GET_LENGTH, &l))
|
|
||||||
{
|
{
|
||||||
switch (l)
|
switch (l)
|
||||||
{
|
{
|
||||||
|
@ -679,7 +678,7 @@ static BOOL should_stop(int bpnum)
|
||||||
{
|
{
|
||||||
struct dbg_lvalue lvalue = expr_eval(bp->condition);
|
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.
|
* Something wrong - unable to evaluate this expression.
|
||||||
|
|
|
@ -133,7 +133,7 @@ command:
|
||||||
| tSOURCE pathname { parser($2); }
|
| tSOURCE pathname { parser($2); }
|
||||||
| tSYMBOLFILE pathname { symbol_read_symtable($2, 0); }
|
| tSYMBOLFILE pathname { symbol_read_symtable($2, 0); }
|
||||||
| tSYMBOLFILE pathname expr_rvalue { symbol_read_symtable($2, $3); }
|
| 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); }
|
| tATTACH tNUM { dbg_attach_debuggee($2, FALSE, TRUE); }
|
||||||
| tDETACH { dbg_detach_debuggee(); }
|
| tDETACH { dbg_detach_debuggee(); }
|
||||||
| run_command
|
| run_command
|
||||||
|
@ -202,8 +202,8 @@ set_command:
|
||||||
;
|
;
|
||||||
|
|
||||||
x_command:
|
x_command:
|
||||||
tEXAM expr_lvalue { memory_examine(&$2, 1, 'x'); }
|
tEXAM expr_rvalue { memory_examine((void*)$2, 1, 'x'); }
|
||||||
| tEXAM tFORMAT expr_lvalue { memory_examine(&$3, $2 >> 8, $2 & 0xff); }
|
| tEXAM tFORMAT expr_rvalue { memory_examine((void*)$3, $2 >> 8, $2 & 0xff); }
|
||||||
;
|
;
|
||||||
|
|
||||||
print_command:
|
print_command:
|
||||||
|
@ -231,7 +231,7 @@ watch_command:
|
||||||
;
|
;
|
||||||
|
|
||||||
display_command:
|
display_command:
|
||||||
tDISPLAY { display_info(); }
|
tDISPLAY { display_print(); }
|
||||||
| tDISPLAY expr { display_add($2, 1, 0, FALSE); }
|
| tDISPLAY expr { display_add($2, 1, 0, FALSE); }
|
||||||
| tDISPLAY tFORMAT expr { display_add($3, $2 >> 8, $2 & 0xff, FALSE); }
|
| tDISPLAY tFORMAT expr { display_add($3, $2 >> 8, $2 & 0xff, FALSE); }
|
||||||
| tLOCAL tDISPLAY expr { display_add($3, 1, 0, TRUE); }
|
| tLOCAL tDISPLAY expr { display_add($3, 1, 0, TRUE); }
|
||||||
|
@ -280,27 +280,27 @@ noprocess_state:
|
||||||
;
|
;
|
||||||
|
|
||||||
type_expr:
|
type_expr:
|
||||||
tCHAR { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_char; }
|
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.typeid = dbg_itype_signed_int; }
|
| 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.typeid = dbg_itype_signed_long_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.typeid = 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.typeid = dbg_itype_unsigned_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.typeid = 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.typeid = dbg_itype_unsigned_long_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.typeid = 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.typeid = dbg_itype_signed_short_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.typeid = 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.typeid = dbg_itype_unsigned_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.typeid = 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.typeid = dbg_itype_signed_char_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.typeid = dbg_itype_unsigned_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.typeid = dbg_itype_unsigned_longlong_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.typeid = 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.typeid = dbg_itype_signed_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.typeid = 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.typeid = dbg_itype_short_real; }
|
| 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.typeid = dbg_itype_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.typeid = dbg_itype_long_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++; }
|
| type_expr '*' { $$ = $1; $$.deref_count++; }
|
||||||
| tCLASS identifier { $$.type = type_expr_udt_class; $$.deref_count = 0; $$.u.name = lexeme_alloc($2); }
|
| 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); }
|
| tSTRUCT identifier { $$.type = type_expr_udt_struct; $$.deref_count = 0; $$.u.name = lexeme_alloc($2); }
|
||||||
|
|
|
@ -82,6 +82,18 @@ enum dbg_internal_types
|
||||||
dbg_itype_none = 0xffffffff
|
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... */
|
struct dbg_lvalue /* structure to hold left-values... */
|
||||||
{
|
{
|
||||||
int cookie; /* DLV_??? */
|
int cookie; /* DLV_??? */
|
||||||
|
@ -91,7 +103,7 @@ struct dbg_lvalue /* structure to hold left-values... */
|
||||||
# define DLV_TARGET 0xF00D
|
# define DLV_TARGET 0xF00D
|
||||||
# define DLV_HOST 0x50DA
|
# define DLV_HOST 0x50DA
|
||||||
ADDRESS addr;
|
ADDRESS addr;
|
||||||
unsigned long typeid;
|
struct dbg_type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum dbg_exec_mode
|
enum dbg_exec_mode
|
||||||
|
@ -202,7 +214,7 @@ struct dbg_internal_var
|
||||||
DWORD val;
|
DWORD val;
|
||||||
const char* name;
|
const char* name;
|
||||||
LPDWORD pval;
|
LPDWORD pval;
|
||||||
unsigned long typeid;
|
unsigned long typeid; /* always internal type */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum sym_get_lval {sglv_found, sglv_unknown, sglv_aborted};
|
enum sym_get_lval {sglv_found, sglv_unknown, sglv_aborted};
|
||||||
|
@ -222,7 +234,7 @@ struct type_expr_t
|
||||||
unsigned deref_count;
|
unsigned deref_count;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
unsigned long typeid;
|
struct dbg_type type;
|
||||||
const char* name;
|
const char* name;
|
||||||
} u;
|
} 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);
|
extern void info_wine_dbg_channel(BOOL add, const char* chnl, const char* name);
|
||||||
|
|
||||||
/* memory.c */
|
/* 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 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_report_invalid_addr(const void* addr);
|
||||||
extern void* memory_to_linear_addr(const ADDRESS* address);
|
extern void* memory_to_linear_addr(const ADDRESS* address);
|
||||||
extern BOOL memory_get_current_pc(ADDRESS* address);
|
extern BOOL memory_get_current_pc(ADDRESS* address);
|
||||||
extern BOOL memory_get_current_stack(ADDRESS* address);
|
extern BOOL memory_get_current_stack(ADDRESS* address);
|
||||||
extern BOOL memory_get_current_frame(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 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 void memory_disassemble(const struct dbg_lvalue*, const struct dbg_lvalue*, int offset);
|
||||||
extern BOOL memory_disasm_one_insn(ADDRESS* addr);
|
extern BOOL memory_disasm_one_insn(ADDRESS* addr);
|
||||||
|
@ -333,16 +345,15 @@ extern int symbol_info_locals(void);
|
||||||
|
|
||||||
/* types.c */
|
/* types.c */
|
||||||
extern void print_value(const struct dbg_lvalue* addr, char format, int level);
|
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 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 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);
|
||||||
extern BOOL types_get_info(unsigned long, unsigned long,
|
extern BOOL types_get_info(const struct dbg_type*, IMAGEHLP_SYMBOL_TYPE_INFO, void*);
|
||||||
IMAGEHLP_SYMBOL_TYPE_INFO, void*);
|
extern struct dbg_type types_find_pointer(const struct dbg_type* type);
|
||||||
extern unsigned long types_find_pointer(unsigned long linear, unsigned long typeid);
|
extern struct dbg_type types_find_type(unsigned long linear, const char* name, enum SymTagEnum tag);
|
||||||
extern unsigned long types_find_type(unsigned long linear, const char* name, enum SymTagEnum tag);
|
|
||||||
|
|
||||||
/* winedbg.c */
|
/* winedbg.c */
|
||||||
extern void dbg_outputA(const char* buffer, int len);
|
extern void dbg_outputA(const char* buffer, int len);
|
||||||
|
|
|
@ -43,10 +43,18 @@ struct display
|
||||||
static struct display *displaypoints = NULL;
|
static struct display *displaypoints = NULL;
|
||||||
static unsigned int maxdisplays = 0, ndisplays = 0;
|
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)
|
static inline BOOL cmp_symbol(const SYMBOL_INFO* si1, const SYMBOL_INFO* si2)
|
||||||
{
|
{
|
||||||
if (si1->NameLen != si2->NameLen) return FALSE;
|
/* FIXME: !memcmp(si1, si2, sizeof(SYMBOL_INFO) + si1->NameLen)
|
||||||
return !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)
|
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)
|
if (in_frame)
|
||||||
{
|
{
|
||||||
displaypoints[i].func = (SYMBOL_INFO*)displaypoints[i].func_buffer;
|
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->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||||
displaypoints[i].func->MaxNameLen = sizeof(displaypoints[i].func_buffer) -
|
displaypoints[i].func->MaxNameLen = sizeof(displaypoints[i].func_buffer) -
|
||||||
sizeof(*displaypoints[i].func);
|
sizeof(*displaypoints[i].func);
|
||||||
|
@ -97,6 +106,7 @@ int display_info(void)
|
||||||
const char* info;
|
const char* info;
|
||||||
|
|
||||||
func = (SYMBOL_INFO*)buffer;
|
func = (SYMBOL_INFO*)buffer;
|
||||||
|
memset(func, 0, sizeof(SYMBOL_INFO));
|
||||||
func->SizeOfStruct = sizeof(SYMBOL_INFO);
|
func->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||||
func->MaxNameLen = sizeof(buffer) - sizeof(*func);
|
func->MaxNameLen = sizeof(buffer) - sizeof(*func);
|
||||||
if (!stack_get_frame(func, NULL)) return FALSE;
|
if (!stack_get_frame(func, NULL)) return FALSE;
|
||||||
|
@ -105,6 +115,9 @@ int display_info(void)
|
||||||
{
|
{
|
||||||
if (displaypoints[i].exp == NULL) continue;
|
if (displaypoints[i].exp == NULL) continue;
|
||||||
|
|
||||||
|
dbg_printf("%d: ", i + 1);
|
||||||
|
expr_print(displaypoints[i].exp);
|
||||||
|
|
||||||
if (displaypoints[i].enabled)
|
if (displaypoints[i].enabled)
|
||||||
{
|
{
|
||||||
if (displaypoints[i].func && !cmp_symbol(displaypoints[i].func, func))
|
if (displaypoints[i].func && !cmp_symbol(displaypoints[i].func, func))
|
||||||
|
@ -114,10 +127,9 @@ int display_info(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
info = " (disabled)";
|
info = " (disabled)";
|
||||||
dbg_printf("%d in %s%s: ",
|
if (displaypoints[i].func)
|
||||||
i + 1, func ? displaypoints[i].func->Name : "", info);
|
dbg_printf(" in %s", displaypoints[i].func->Name);
|
||||||
expr_print(displaypoints[i].exp);
|
dbg_printf("%s\n", info);
|
||||||
dbg_printf("\n");
|
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -129,7 +141,7 @@ static void print_one_display(int i)
|
||||||
if (displaypoints[i].enabled)
|
if (displaypoints[i].enabled)
|
||||||
{
|
{
|
||||||
lvalue = expr_eval(displaypoints[i].exp);
|
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 ");
|
dbg_printf("Unable to evaluate expression ");
|
||||||
expr_print(displaypoints[i].exp);
|
expr_print(displaypoints[i].exp);
|
||||||
|
@ -146,7 +158,8 @@ static void print_one_display(int i)
|
||||||
dbg_printf("(disabled)\n");
|
dbg_printf("(disabled)\n");
|
||||||
else
|
else
|
||||||
if (displaypoints[i].format == 'i')
|
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
|
else
|
||||||
print_value(&lvalue, displaypoints[i].format, 0);
|
print_value(&lvalue, displaypoints[i].format, 0);
|
||||||
}
|
}
|
||||||
|
@ -158,6 +171,7 @@ int display_print(void)
|
||||||
SYMBOL_INFO* func;
|
SYMBOL_INFO* func;
|
||||||
|
|
||||||
func = (SYMBOL_INFO*)buffer;
|
func = (SYMBOL_INFO*)buffer;
|
||||||
|
memset(func, 0, sizeof(SYMBOL_INFO));
|
||||||
func->SizeOfStruct = sizeof(SYMBOL_INFO);
|
func->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||||
func->MaxNameLen = sizeof(buffer) - sizeof(*func);
|
func->MaxNameLen = sizeof(buffer) - sizeof(*func);
|
||||||
if (!stack_get_frame(func, NULL)) return FALSE;
|
if (!stack_get_frame(func, NULL)) return FALSE;
|
||||||
|
@ -226,6 +240,7 @@ int display_enable(int displaynum, int enable)
|
||||||
SYMBOL_INFO* func;
|
SYMBOL_INFO* func;
|
||||||
|
|
||||||
func = (SYMBOL_INFO*)buffer;
|
func = (SYMBOL_INFO*)buffer;
|
||||||
|
memset(func, 0, sizeof(SYMBOL_INFO));
|
||||||
func->SizeOfStruct = sizeof(SYMBOL_INFO);
|
func->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||||
func->MaxNameLen = sizeof(buffer) - sizeof(*func);
|
func->MaxNameLen = sizeof(buffer) - sizeof(*func);
|
||||||
if (!stack_get_frame(func, NULL)) return FALSE;
|
if (!stack_get_frame(func, NULL)) return FALSE;
|
||||||
|
|
|
@ -282,13 +282,13 @@ struct dbg_lvalue expr_eval(struct expr* exp)
|
||||||
struct dbg_lvalue exp2;
|
struct dbg_lvalue exp2;
|
||||||
unsigned int cexp[5];
|
unsigned int cexp[5];
|
||||||
DWORD scale1, scale2, scale3;
|
DWORD scale1, scale2, scale3;
|
||||||
DWORD type1, type2;
|
struct dbg_type type1, type2;
|
||||||
DWORD linear1, linear2;
|
|
||||||
DWORD tag;
|
DWORD tag;
|
||||||
const struct dbg_internal_var* div;
|
const struct dbg_internal_var* div;
|
||||||
|
|
||||||
rtn.typeid = dbg_itype_none;
|
|
||||||
rtn.cookie = 0;
|
rtn.cookie = 0;
|
||||||
|
rtn.type.id = dbg_itype_none;
|
||||||
|
rtn.type.module = 0;
|
||||||
rtn.addr.Mode = AddrModeFlat;
|
rtn.addr.Mode = AddrModeFlat;
|
||||||
rtn.addr.Offset = 0;
|
rtn.addr.Offset = 0;
|
||||||
rtn.addr.Segment = 0;
|
rtn.addr.Segment = 0;
|
||||||
|
@ -300,30 +300,31 @@ struct dbg_lvalue expr_eval(struct expr* exp)
|
||||||
* checking if this is right or not
|
* checking if this is right or not
|
||||||
*/
|
*/
|
||||||
rtn = expr_eval(exp->un.cast.expr);
|
rtn = expr_eval(exp->un.cast.expr);
|
||||||
linear1 = (DWORD)memory_to_linear_addr(&rtn.addr);
|
|
||||||
switch (exp->un.cast.cast_to.type)
|
switch (exp->un.cast.cast_to.type)
|
||||||
{
|
{
|
||||||
case type_expr_type_id:
|
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");
|
dbg_printf("Can't cast to unknown type\n");
|
||||||
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
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;
|
break;
|
||||||
case type_expr_udt_class:
|
case type_expr_udt_class:
|
||||||
case type_expr_udt_struct:
|
case type_expr_udt_struct:
|
||||||
case type_expr_udt_union:
|
case type_expr_udt_union:
|
||||||
rtn.typeid = types_find_type(linear1, exp->un.cast.cast_to.u.name, SymTagUDT);
|
rtn.type = types_find_type((DWORD)memory_to_linear_addr(&rtn.addr),
|
||||||
if (rtn.typeid == dbg_itype_none)
|
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);
|
dbg_printf("Can't cast to UDT %s\n", exp->un.cast.cast_to.u.name);
|
||||||
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case type_expr_enumeration:
|
case type_expr_enumeration:
|
||||||
rtn.typeid = types_find_type(linear1, exp->un.cast.cast_to.u.name, SymTagEnum);
|
rtn.type = types_find_type((DWORD)memory_to_linear_addr(&rtn.addr),
|
||||||
if (rtn.typeid == dbg_itype_none)
|
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);
|
dbg_printf("Can't cast to enumeration %s\n", exp->un.cast.cast_to.u.name);
|
||||||
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
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++)
|
for (i = 0; i < exp->un.cast.cast_to.deref_count; i++)
|
||||||
{
|
{
|
||||||
rtn.typeid = types_find_pointer(linear1, rtn.typeid);
|
rtn.type = types_find_pointer(&rtn.type);
|
||||||
if (rtn.typeid == dbg_itype_none)
|
if (rtn.type.id == dbg_itype_none)
|
||||||
{
|
{
|
||||||
dbg_printf("Cannot find pointer type\n");
|
dbg_printf("Cannot find pointer type\n");
|
||||||
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
||||||
|
@ -344,18 +345,21 @@ struct dbg_lvalue expr_eval(struct expr* exp)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EXPR_TYPE_STRING:
|
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;
|
rtn.addr.Offset = (unsigned int)&exp->un.string.str;
|
||||||
break;
|
break;
|
||||||
case EXPR_TYPE_U_CONST:
|
case EXPR_TYPE_U_CONST:
|
||||||
rtn.typeid = dbg_itype_unsigned_int;
|
|
||||||
rtn.cookie = DLV_HOST;
|
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;
|
rtn.addr.Offset = (unsigned int)&exp->un.u_const.value;
|
||||||
break;
|
break;
|
||||||
case EXPR_TYPE_S_CONST:
|
case EXPR_TYPE_S_CONST:
|
||||||
rtn.typeid = dbg_itype_signed_int;
|
|
||||||
rtn.cookie = DLV_HOST;
|
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;
|
rtn.addr.Offset = (unsigned int)&exp->un.s_const.value;
|
||||||
break;
|
break;
|
||||||
case EXPR_TYPE_SYMBOL:
|
case EXPR_TYPE_SYMBOL:
|
||||||
|
@ -373,8 +377,8 @@ struct dbg_lvalue expr_eval(struct expr* exp)
|
||||||
break;
|
break;
|
||||||
case EXPR_TYPE_PSTRUCT:
|
case EXPR_TYPE_PSTRUCT:
|
||||||
exp1 = expr_eval(exp->un.structure.exp1);
|
exp1 = expr_eval(exp->un.structure.exp1);
|
||||||
if (exp1.typeid == dbg_itype_none || !types_deref(&exp1, &rtn) ||
|
if (exp1.type.id == dbg_itype_none || !types_deref(&exp1, &rtn) ||
|
||||||
rtn.typeid == dbg_itype_none)
|
rtn.type.id == dbg_itype_none)
|
||||||
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
||||||
if (!types_udt_find_element(&rtn, exp->un.structure.element_name,
|
if (!types_udt_find_element(&rtn, exp->un.structure.element_name,
|
||||||
&exp->un.structure.result))
|
&exp->un.structure.result))
|
||||||
|
@ -385,7 +389,7 @@ struct dbg_lvalue expr_eval(struct expr* exp)
|
||||||
break;
|
break;
|
||||||
case EXPR_TYPE_STRUCT:
|
case EXPR_TYPE_STRUCT:
|
||||||
exp1 = expr_eval(exp->un.structure.exp1);
|
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;
|
rtn = exp1;
|
||||||
if (!types_udt_find_element(&rtn, exp->un.structure.element_name,
|
if (!types_udt_find_element(&rtn, exp->un.structure.element_name,
|
||||||
&exp->un.structure.result))
|
&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++)
|
for (i = 0; i < exp->un.call.nargs; i++)
|
||||||
{
|
{
|
||||||
exp1 = expr_eval(exp->un.call.arg[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);
|
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
||||||
cexp[i] = types_extract_as_integer(&exp1);
|
cexp[i] = types_extract_as_integer(&exp1);
|
||||||
}
|
}
|
||||||
|
@ -458,93 +462,93 @@ struct dbg_lvalue expr_eval(struct expr* exp)
|
||||||
*/
|
*/
|
||||||
exp->un.call.result = 0;
|
exp->un.call.result = 0;
|
||||||
#endif
|
#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.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;
|
rtn.addr.Offset = (unsigned int)&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.cookie = DLV_HOST;
|
rtn.type.id = div->typeid;
|
||||||
rtn.typeid = div->typeid;
|
rtn.type.module = 0;
|
||||||
rtn.addr.Offset = (unsigned int)div->pval;
|
rtn.addr.Offset = (unsigned int)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);
|
||||||
rtn.cookie = DLV_HOST;
|
if (exp1.type.id == dbg_itype_none || exp2.type.id == dbg_itype_none)
|
||||||
if (exp1.typeid == dbg_itype_none || exp2.typeid == dbg_itype_none)
|
|
||||||
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
||||||
linear1 = (DWORD)memory_to_linear_addr(&exp1.addr);
|
rtn.type.id = dbg_itype_signed_int;
|
||||||
linear2 = (DWORD)memory_to_linear_addr(&exp2.addr);
|
rtn.type.module = 0;
|
||||||
rtn.typeid = dbg_itype_signed_int;
|
|
||||||
rtn.addr.Offset = (unsigned int)&exp->un.binop.result;
|
rtn.addr.Offset = (unsigned int)&exp->un.binop.result;
|
||||||
switch (exp->un.binop.binop_type)
|
switch (exp->un.binop.binop_type)
|
||||||
{
|
{
|
||||||
case EXP_OP_ADD:
|
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 ||
|
tag != SymTagPointerType ||
|
||||||
!types_get_info(linear1, exp1.typeid, TI_GET_TYPE, &type1))
|
!types_get_info(&exp1.type, TI_GET_TYPE, &type1))
|
||||||
type1 = dbg_itype_none;
|
type1.id = dbg_itype_none;
|
||||||
if (!types_get_info(linear1, exp2.typeid, TI_GET_SYMTAG, &tag) ||
|
if (!types_get_info(&exp2.type, TI_GET_SYMTAG, &tag) ||
|
||||||
tag != SymTagPointerType ||
|
tag != SymTagPointerType ||
|
||||||
!types_get_info(linear1, exp2.typeid, TI_GET_TYPE, &type2))
|
!types_get_info(&exp2.type, TI_GET_TYPE, &type2))
|
||||||
type2 = dbg_itype_none;
|
type2.id = dbg_itype_none;
|
||||||
scale1 = 1;
|
scale1 = 1;
|
||||||
scale2 = 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);
|
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);
|
types_get_info(&type1, TI_GET_LENGTH, &scale2);
|
||||||
rtn.typeid = exp1.typeid;
|
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);
|
types_get_info(&type2, TI_GET_LENGTH, &scale1);
|
||||||
rtn.typeid = exp2.typeid;
|
rtn.type = exp2.type;
|
||||||
}
|
}
|
||||||
exp->un.binop.result = (types_extract_as_integer(&exp1) * scale1 +
|
exp->un.binop.result = (types_extract_as_integer(&exp1) * scale1 +
|
||||||
scale2 * types_extract_as_integer(&exp2));
|
scale2 * types_extract_as_integer(&exp2));
|
||||||
break;
|
break;
|
||||||
case EXP_OP_SUB:
|
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 ||
|
tag != SymTagPointerType ||
|
||||||
!types_get_info(linear1, exp1.typeid, TI_GET_TYPE, &type1))
|
!types_get_info(&exp1.type, TI_GET_TYPE, &type1))
|
||||||
type1 = dbg_itype_none;
|
type1.id = dbg_itype_none;
|
||||||
if (!types_get_info(linear2, exp2.typeid, TI_GET_SYMTAG, &tag) ||
|
if (!types_get_info(&exp2.type, TI_GET_SYMTAG, &tag) ||
|
||||||
tag != SymTagPointerType ||
|
tag != SymTagPointerType ||
|
||||||
!types_get_info(linear2, exp2.typeid, TI_GET_TYPE, &type2))
|
!types_get_info(&exp2.type, TI_GET_TYPE, &type2))
|
||||||
type2 = dbg_itype_none;
|
type2.id = dbg_itype_none;
|
||||||
scale1 = 1;
|
scale1 = 1;
|
||||||
scale2 = 1;
|
scale2 = 1;
|
||||||
scale3 = 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);
|
WINE_FIXME("This may fail (if module base address are wrongly calculated)\n");
|
||||||
types_get_info(linear1, type1, TI_GET_LENGTH, &scale3);
|
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);
|
types_get_info(&type1, TI_GET_LENGTH, &scale2);
|
||||||
rtn.typeid = exp1.typeid;
|
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);
|
types_get_info(&type2, TI_GET_LENGTH, &scale1);
|
||||||
rtn.typeid = exp2.typeid;
|
rtn.type = exp2.type;
|
||||||
}
|
}
|
||||||
exp->un.binop.result = (types_extract_as_integer(&exp1) * scale1 -
|
exp->un.binop.result = (types_extract_as_integer(&exp1) * scale1 -
|
||||||
types_extract_as_integer(&exp2) * scale2) / scale3;
|
types_extract_as_integer(&exp2) * scale2) / scale3;
|
||||||
break;
|
break;
|
||||||
case EXP_OP_SEG:
|
case EXP_OP_SEG:
|
||||||
rtn.cookie = DLV_TARGET;
|
rtn.type.id = dbg_itype_none;
|
||||||
rtn.typeid = dbg_itype_none;
|
rtn.type.module = 0;
|
||||||
rtn.addr.Mode = AddrMode1632;
|
rtn.addr.Mode = AddrMode1632;
|
||||||
rtn.addr.Segment = types_extract_as_integer(&exp1);
|
rtn.addr.Segment = types_extract_as_integer(&exp1);
|
||||||
rtn.addr.Offset = types_extract_as_integer(&exp2);
|
rtn.addr.Offset = types_extract_as_integer(&exp2);
|
||||||
|
@ -607,11 +611,12 @@ struct dbg_lvalue expr_eval(struct expr* exp)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EXPR_TYPE_UNOP:
|
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;
|
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.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)
|
switch (exp->un.unop.unop_type)
|
||||||
{
|
{
|
||||||
case EXP_OP_NEG:
|
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);
|
exp->un.unop.result = ~types_extract_as_integer(&exp1);
|
||||||
break;
|
break;
|
||||||
case EXP_OP_DEREF:
|
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))
|
if (!types_deref(&exp1, &rtn))
|
||||||
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
||||||
break;
|
break;
|
||||||
|
@ -650,7 +642,7 @@ struct dbg_lvalue expr_eval(struct expr* exp)
|
||||||
if (exp1.addr.Mode != AddrModeFlat)
|
if (exp1.addr.Mode != AddrModeFlat)
|
||||||
RaiseException(DEBUG_STATUS_CANT_DEREF, 0, 0, NULL);
|
RaiseException(DEBUG_STATUS_CANT_DEREF, 0, 0, NULL);
|
||||||
exp->un.unop.result = (unsigned int)memory_to_linear_addr(&exp1.addr);
|
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;
|
break;
|
||||||
default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
|
default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
|
||||||
}
|
}
|
||||||
|
@ -661,14 +653,13 @@ struct dbg_lvalue expr_eval(struct expr* exp)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(rtn.cookie == DLV_TARGET || rtn.cookie == DLV_HOST);
|
|
||||||
|
|
||||||
return rtn;
|
return rtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
int expr_print(const struct expr* exp)
|
int expr_print(const struct expr* exp)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
struct dbg_type type;
|
||||||
|
|
||||||
switch (exp->type)
|
switch (exp->type)
|
||||||
{
|
{
|
||||||
|
@ -678,7 +669,9 @@ int expr_print(const struct expr* exp)
|
||||||
switch (exp->un.cast.cast_to.type)
|
switch (exp->un.cast.cast_to.type)
|
||||||
{
|
{
|
||||||
case type_expr_type_id:
|
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:
|
case type_expr_udt_class:
|
||||||
dbg_printf("class %s", exp->un.cast.cast_to.u.name); break;
|
dbg_printf("class %s", exp->un.cast.cast_to.u.name); break;
|
||||||
case type_expr_udt_struct:
|
case type_expr_udt_struct:
|
||||||
|
|
|
@ -468,7 +468,7 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
|
||||||
case OUTPUT_DEBUG_STRING_EVENT:
|
case OUTPUT_DEBUG_STRING_EVENT:
|
||||||
assert(dbg_curr_thread);
|
assert(dbg_curr_thread);
|
||||||
memory_get_string(gdbctx->process->handle,
|
memory_get_string(gdbctx->process->handle,
|
||||||
de->u.DebugString.lpDebugStringData, DLV_TARGET,
|
de->u.DebugString.lpDebugStringData, TRUE,
|
||||||
de->u.DebugString.fUnicode, buffer, sizeof(buffer));
|
de->u.DebugString.fUnicode, buffer, sizeof(buffer));
|
||||||
if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
|
if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
|
||||||
fprintf(stderr, "%08lx:%08lx: output debug string (%s)\n",
|
fprintf(stderr, "%08lx:%08lx: output debug string (%s)\n",
|
||||||
|
|
|
@ -99,7 +99,6 @@ BOOL memory_read_value(const struct dbg_lvalue* lvalue, DWORD size, void* result
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
assert(lvalue->addr.Mode == AddrModeFlat);
|
|
||||||
if (!lvalue->addr.Offset) return FALSE;
|
if (!lvalue->addr.Offset) return FALSE;
|
||||||
memcpy(result, (void*)lvalue->addr.Offset, size);
|
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);
|
DWORD linear = (DWORD)memory_to_linear_addr(&lvalue->addr);
|
||||||
|
|
||||||
os = ~size;
|
os = ~size;
|
||||||
types_get_info(linear, lvalue->typeid, TI_GET_LENGTH, &os);
|
types_get_info(&lvalue->type, TI_GET_LENGTH, &os);
|
||||||
assert(size == os);
|
assert(size == os);
|
||||||
|
|
||||||
/* FIXME: only works on little endian systems */
|
/* 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
|
else
|
||||||
{
|
{
|
||||||
assert(lvalue->addr.Mode == AddrModeFlat);
|
|
||||||
memcpy((void*)lvalue->addr.Offset, value, size);
|
memcpy((void*)lvalue->addr.Offset, value, size);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -139,17 +137,18 @@ BOOL memory_write_value(const struct dbg_lvalue* lvalue, DWORD size, void* value
|
||||||
*
|
*
|
||||||
* Implementation of the 'x' command.
|
* 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;
|
int i;
|
||||||
ADDRESS x;
|
|
||||||
char buffer[256];
|
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)
|
if (format != 'i' && count > 1)
|
||||||
{
|
{
|
||||||
print_address(&x, FALSE);
|
print_address(&addr, FALSE);
|
||||||
dbg_printf(": ");
|
dbg_printf(": ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,32 +156,33 @@ void memory_examine(const struct dbg_lvalue* lvalue, int count, char format)
|
||||||
{
|
{
|
||||||
case 'u':
|
case 'u':
|
||||||
if (count == 1) count = 256;
|
if (count == 1) count = 256;
|
||||||
memory_get_string(dbg_curr_thread->handle, (void*)x.Offset, lvalue->cookie,
|
memory_get_string(dbg_curr_process->handle, linear,
|
||||||
TRUE, buffer, min(count, sizeof(buffer)));
|
TRUE, TRUE, buffer, min(count, sizeof(buffer)));
|
||||||
dbg_printf("%s\n", buffer);
|
dbg_printf("%s\n", buffer);
|
||||||
return;
|
return;
|
||||||
case 's':
|
case 's':
|
||||||
if (count == 1) count = 256;
|
if (count == 1) count = 256;
|
||||||
memory_get_string(dbg_curr_thread->handle, (void*)x.Offset, lvalue->cookie,
|
memory_get_string(dbg_curr_process->handle, linear,
|
||||||
FALSE, buffer, min(count, sizeof(buffer)));
|
TRUE, FALSE, buffer, min(count, sizeof(buffer)));
|
||||||
dbg_printf("%s\n", buffer);
|
dbg_printf("%s\n", buffer);
|
||||||
return;
|
return;
|
||||||
case 'i':
|
case 'i':
|
||||||
while (count-- && memory_disasm_one_insn(&x));
|
while (count-- && memory_disasm_one_insn(&addr));
|
||||||
return;
|
return;
|
||||||
case 'g':
|
case 'g':
|
||||||
while (count--)
|
while (count--)
|
||||||
{
|
{
|
||||||
GUID guid;
|
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",
|
dbg_printf("{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
|
||||||
guid.Data1, guid.Data2, guid.Data3,
|
guid.Data1, guid.Data2, guid.Data3,
|
||||||
guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
|
guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
|
||||||
guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
|
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)
|
if (count)
|
||||||
{
|
{
|
||||||
print_address(&x, FALSE);
|
print_address(&addr, FALSE);
|
||||||
dbg_printf(": ");
|
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) { \
|
#define DO_DUMP2(_t,_l,_f,_vv) { \
|
||||||
_t _v; \
|
_t _v; \
|
||||||
for (i = 0; i < count; i++) { \
|
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; \
|
sizeof(_t))) break; \
|
||||||
dbg_printf(_f, (_vv)); \
|
dbg_printf(_f, (_vv)); \
|
||||||
x.Offset += sizeof(_t); \
|
addr.Offset += sizeof(_t); \
|
||||||
if ((i % (_l)) == (_l) - 1) { \
|
linear = (char*)linear + sizeof(_t); \
|
||||||
|
if ((i % (_l)) == (_l) - 1 && i != count - 1) \
|
||||||
|
{ \
|
||||||
dbg_printf("\n"); \
|
dbg_printf("\n"); \
|
||||||
print_address(&x, FALSE); \
|
print_address(&addr, FALSE); \
|
||||||
dbg_printf(": "); \
|
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)
|
char* buffer, int size)
|
||||||
{
|
{
|
||||||
DWORD sz;
|
DWORD sz;
|
||||||
|
@ -222,9 +224,8 @@ BOOL memory_get_string(HANDLE hp, void* addr, unsigned cookie, BOOL unicode,
|
||||||
|
|
||||||
buffer[0] = 0;
|
buffer[0] = 0;
|
||||||
if (!addr) return FALSE;
|
if (!addr) return FALSE;
|
||||||
switch (cookie)
|
if (in_debuggee)
|
||||||
{
|
{
|
||||||
case DLV_TARGET:
|
|
||||||
if (!unicode) return ReadProcessMemory(hp, addr, buffer, size, &sz);
|
if (!unicode) return ReadProcessMemory(hp, addr, buffer, size, &sz);
|
||||||
|
|
||||||
buffW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
|
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,
|
WideCharToMultiByte(CP_ACP, 0, buffW, sz / sizeof(WCHAR), buffer, size,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
HeapFree(GetProcessHeap(), 0, buffW);
|
HeapFree(GetProcessHeap(), 0, buffW);
|
||||||
return TRUE;
|
}
|
||||||
case DLV_HOST:
|
else
|
||||||
|
{
|
||||||
strncpy(buffer, addr, size);
|
strncpy(buffer, addr, size);
|
||||||
buffer[size - 1] = 0;
|
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)
|
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 &&
|
if (addr &&
|
||||||
ReadProcessMemory(hp, addr, &ad, sizeof(ad), &sz) && sz == sizeof(ad) && ad)
|
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -260,20 +261,19 @@ static void print_typed_basic(const struct dbg_lvalue* lvalue)
|
||||||
long long int val_int;
|
long long int val_int;
|
||||||
void* val_ptr;
|
void* val_ptr;
|
||||||
long double val_real;
|
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);
|
DWORD linear = (DWORD)memory_to_linear_addr(&lvalue->addr);
|
||||||
|
|
||||||
assert(lvalue->cookie == DLV_TARGET || lvalue->cookie == DLV_HOST);
|
if (lvalue->type.id == dbg_itype_none ||
|
||||||
|
!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
|
||||||
if (lvalue->typeid == dbg_itype_none ||
|
|
||||||
!types_get_info(linear, lvalue->typeid, TI_GET_SYMTAG, &tag))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (tag)
|
switch (tag)
|
||||||
{
|
{
|
||||||
case SymTagBaseType:
|
case SymTagBaseType:
|
||||||
if (!types_get_info(linear, lvalue->typeid, TI_GET_LENGTH, &size) ||
|
if (!types_get_info(&lvalue->type, TI_GET_LENGTH, &size) ||
|
||||||
!types_get_info(linear, lvalue->typeid, 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);
|
||||||
|
@ -309,20 +309,21 @@ static void print_typed_basic(const struct dbg_lvalue* lvalue)
|
||||||
case SymTagPointerType:
|
case SymTagPointerType:
|
||||||
if (!memory_read_value(lvalue, sizeof(void*), &val_ptr)) return;
|
if (!memory_read_value(lvalue, sizeof(void*), &val_ptr)) return;
|
||||||
|
|
||||||
if (!types_get_info(linear, lvalue->typeid, TI_GET_TYPE, &rtype) ||
|
if (!types_get_info(&lvalue->type, TI_GET_TYPE, &rtype.id) ||
|
||||||
rtype == dbg_itype_none)
|
rtype.id == dbg_itype_none)
|
||||||
{
|
{
|
||||||
dbg_printf("Internal symbol error: unable to access memory location %p", val_ptr);
|
dbg_printf("Internal symbol error: unable to access memory location %p", val_ptr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
rtype.module = lvalue->type.module;
|
||||||
if (types_get_info(linear, rtype, TI_GET_SYMTAG, &tag) && tag == SymTagBaseType &&
|
if (types_get_info(&rtype, TI_GET_SYMTAG, &tag) && tag == SymTagBaseType &&
|
||||||
types_get_info(linear, rtype, TI_GET_BASETYPE, &bt) && bt == btChar &&
|
types_get_info(&rtype, TI_GET_BASETYPE, &bt) && bt == btChar &&
|
||||||
types_get_info(linear, rtype, TI_GET_LENGTH, &size))
|
types_get_info(&rtype, TI_GET_LENGTH, &size))
|
||||||
{
|
{
|
||||||
char buffer[1024];
|
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));
|
size == 2, buffer, sizeof(buffer));
|
||||||
dbg_printf("\"%s\"", 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 (!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)];
|
char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
|
||||||
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
|
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
|
||||||
WCHAR* ptr;
|
WCHAR* ptr;
|
||||||
char tmp[256];
|
char tmp[256];
|
||||||
VARIANT variant;
|
VARIANT variant;
|
||||||
int i;
|
int i;
|
||||||
|
struct dbg_type type;
|
||||||
|
|
||||||
fcp->Start = 0;
|
fcp->Start = 0;
|
||||||
while (count)
|
while (count)
|
||||||
{
|
{
|
||||||
fcp->Count = min(count, 256);
|
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++)
|
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;
|
continue;
|
||||||
switch (variant.n1.n2.vt)
|
switch (variant.n1.n2.vt)
|
||||||
{
|
{
|
||||||
|
@ -372,7 +376,7 @@ static void print_typed_basic(const struct dbg_lvalue* lvalue)
|
||||||
if (ok)
|
if (ok)
|
||||||
{
|
{
|
||||||
ptr = NULL;
|
ptr = NULL;
|
||||||
types_get_info(linear, fcp->ChildId[i], TI_GET_SYMNAME, &ptr);
|
types_get_info(&type, TI_GET_SYMNAME, &ptr);
|
||||||
if (!ptr) continue;
|
if (!ptr) continue;
|
||||||
WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
|
WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
|
||||||
HeapFree(GetProcessHeap(), 0, ptr);
|
HeapFree(GetProcessHeap(), 0, ptr);
|
||||||
|
@ -404,8 +408,7 @@ void print_basic(const struct dbg_lvalue* lvalue, int count, char format)
|
||||||
{
|
{
|
||||||
long int res;
|
long int res;
|
||||||
|
|
||||||
assert(lvalue->cookie == DLV_TARGET || lvalue->cookie == DLV_HOST);
|
if (lvalue->type.id == dbg_itype_none)
|
||||||
if (lvalue->typeid == dbg_itype_none)
|
|
||||||
{
|
{
|
||||||
dbg_printf("Unable to evaluate expression\n");
|
dbg_printf("Unable to evaluate expression\n");
|
||||||
return;
|
return;
|
||||||
|
@ -465,6 +468,9 @@ void print_bare_address(const ADDRESS* addr)
|
||||||
case AddrMode1632:
|
case AddrMode1632:
|
||||||
dbg_printf("0x%04x:0x%08lx", addr->Segment, addr->Offset);
|
dbg_printf("0x%04x:0x%08lx", addr->Segment, addr->Offset);
|
||||||
break;
|
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;
|
char* tmp;
|
||||||
DWORD frame;
|
DWORD frame;
|
||||||
|
@ -507,19 +513,23 @@ struct foo
|
||||||
|
|
||||||
static BOOL WINAPI sym_enum_cb(SYMBOL_INFO* sym_info, ULONG size, void* user)
|
static BOOL WINAPI sym_enum_cb(SYMBOL_INFO* sym_info, ULONG size, void* user)
|
||||||
{
|
{
|
||||||
struct foo* foo = (struct foo*)user;
|
struct sym_enum* se = (struct sym_enum*)user;
|
||||||
DWORD addr;
|
DWORD addr;
|
||||||
unsigned val;
|
unsigned val;
|
||||||
long offset;
|
long offset;
|
||||||
|
|
||||||
if ((sym_info->Flags & (SYMFLAG_PARAMETER|SYMFLAG_FRAMEREL)) == (SYMFLAG_PARAMETER|SYMFLAG_FRAMEREL))
|
if ((sym_info->Flags & (SYMFLAG_PARAMETER|SYMFLAG_FRAMEREL)) == (SYMFLAG_PARAMETER|SYMFLAG_FRAMEREL))
|
||||||
{
|
{
|
||||||
if (foo->tmp[0]) strcat(foo->tmp, ", ");
|
struct dbg_type type;
|
||||||
addr = foo->frame;
|
|
||||||
types_get_info(sym_info->ModBase, sym_info->TypeIndex, TI_GET_OFFSET, &offset);
|
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;
|
addr += offset;
|
||||||
dbg_read_memory_verbose((char*)addr, &val, sizeof(val));
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -531,7 +541,7 @@ void print_addr_and_args(const ADDRESS* pc, const ADDRESS* frame)
|
||||||
IMAGEHLP_STACK_FRAME isf;
|
IMAGEHLP_STACK_FRAME isf;
|
||||||
IMAGEHLP_LINE il;
|
IMAGEHLP_LINE il;
|
||||||
IMAGEHLP_MODULE im;
|
IMAGEHLP_MODULE im;
|
||||||
struct foo foo;
|
struct sym_enum se;
|
||||||
char tmp[1024];
|
char tmp[1024];
|
||||||
DWORD disp;
|
DWORD disp;
|
||||||
|
|
||||||
|
@ -552,10 +562,10 @@ void print_addr_and_args(const ADDRESS* pc, const ADDRESS* frame)
|
||||||
if (disp) dbg_printf("+0x%lx", disp);
|
if (disp) dbg_printf("+0x%lx", disp);
|
||||||
|
|
||||||
SymSetContext(dbg_curr_process->handle, &isf, NULL);
|
SymSetContext(dbg_curr_process->handle, &isf, NULL);
|
||||||
foo.tmp = tmp;
|
se.tmp = tmp;
|
||||||
foo.frame = isf.FrameOffset;
|
se.frame = isf.FrameOffset;
|
||||||
tmp[0] = '\0';
|
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);
|
if (tmp[0]) dbg_printf("(%s)", tmp);
|
||||||
|
|
||||||
il.SizeOfStruct = sizeof(il);
|
il.SizeOfStruct = sizeof(il);
|
||||||
|
|
|
@ -42,27 +42,24 @@ static IMAGEHLP_STACK_FRAME* frames = NULL;
|
||||||
*/
|
*/
|
||||||
void stack_info(void)
|
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 */
|
/* FIXME: we assume stack grows the same way as on i386 */
|
||||||
if (!memory_get_current_stack(&lvalue.addr))
|
if (!memory_get_current_stack(&addr))
|
||||||
dbg_printf("Bad segment (%d)\n", lvalue.addr.Segment);
|
dbg_printf("Bad segment (%d)\n", addr.Segment);
|
||||||
|
|
||||||
dbg_printf("Stack dump:\n");
|
dbg_printf("Stack dump:\n");
|
||||||
switch (lvalue.addr.Mode)
|
switch (addr.Mode)
|
||||||
{
|
{
|
||||||
case AddrModeFlat: /* 32-bit mode */
|
case AddrModeFlat: /* 32-bit mode */
|
||||||
case AddrMode1632: /* 32-bit mode */
|
case AddrMode1632: /* 32-bit mode */
|
||||||
memory_examine(&lvalue, 24, 'x');
|
memory_examine(memory_to_linear_addr(&addr), 24, 'x');
|
||||||
break;
|
break;
|
||||||
case AddrModeReal: /* 16-bit mode */
|
case AddrModeReal: /* 16-bit mode */
|
||||||
case AddrMode1616:
|
case AddrMode1616:
|
||||||
memory_examine(&lvalue, 24, 'w');
|
memory_examine(memory_to_linear_addr(&addr), 24, 'w');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
dbg_printf("\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int stack_set_frame(int newframe)
|
int stack_set_frame(int newframe)
|
||||||
|
|
|
@ -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)];
|
char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
|
||||||
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
|
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
|
||||||
int i;
|
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;
|
fcp->Start = 0;
|
||||||
while (count)
|
while (count)
|
||||||
{
|
{
|
||||||
fcp->Count = min(count, 256);
|
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++)
|
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;
|
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);
|
count -= min(count, 256);
|
||||||
fcp->Start += 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)
|
else if (sym->Flags & SYMFLAG_FRAMEREL)
|
||||||
{
|
{
|
||||||
ULONG offset;
|
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;
|
addr = sgv->ihsf.FrameOffset + offset;
|
||||||
}
|
}
|
||||||
else if (sym->Flags & SYMFLAG_THUNK)
|
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],
|
memmove(&sgv->syms[insp + 1], &sgv->syms[insp],
|
||||||
sizeof(sgv->syms[0]) * sgv->num_thunks);
|
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.Mode = AddrModeFlat;
|
||||||
sgv->syms[insp].lvalue.addr.Offset = addr;
|
sgv->syms[insp].lvalue.addr.Offset = addr;
|
||||||
types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_TYPE,
|
sgv->syms[insp].lvalue.type.module = sym->ModBase;
|
||||||
&sgv->syms[insp].lvalue.typeid);
|
sgv->syms[insp].lvalue.type.id = sym->TypeIndex;
|
||||||
sgv->syms[insp].lvalue.cookie = cookie;
|
types_get_info(&sgv->syms[insp].lvalue.type, TI_GET_TYPE,
|
||||||
|
&sgv->syms[insp].lvalue.type.id);
|
||||||
sgv->syms[insp].flags = sym->Flags;
|
sgv->syms[insp].flags = sym->Flags;
|
||||||
sgv->num++;
|
sgv->num++;
|
||||||
|
|
||||||
|
@ -314,8 +325,9 @@ enum sym_get_lval symbol_get_lvalue(const char* name, const int lineno,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dbg_printf("More than one symbol named %s, picking the first one\n", name);
|
/* FIXME: could display the list of non-picked up symbols */
|
||||||
i = 0;
|
if (sgv.num > 1)
|
||||||
|
dbg_printf("More than one symbol named %s, picking the first one\n", name);
|
||||||
}
|
}
|
||||||
*rtn = sgv.syms[i].lvalue;
|
*rtn = sgv.syms[i].lvalue;
|
||||||
return sglv_found;
|
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);
|
DWORD lin = (DWORD)memory_to_linear_addr(addr);
|
||||||
char buffer[sizeof(SYMBOL_INFO) + 256];
|
char buffer[sizeof(SYMBOL_INFO) + 256];
|
||||||
SYMBOL_INFO* sym = (SYMBOL_INFO*)buffer;
|
SYMBOL_INFO* sym = (SYMBOL_INFO*)buffer;
|
||||||
|
struct dbg_type type;
|
||||||
|
|
||||||
il.SizeOfStruct = sizeof(il);
|
il.SizeOfStruct = sizeof(il);
|
||||||
sym->SizeOfStruct = sizeof(SYMBOL_INFO);
|
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)
|
if (symbol_get_debug_start(sym->ModBase, sym->TypeIndex, &start) && lin < start)
|
||||||
return dbg_not_on_a_line_number;
|
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;
|
size = 0x100000;
|
||||||
if (il.FileName && il.FileName[0] && disp < size)
|
if (il.FileName && il.FileName[0] && disp < size)
|
||||||
return (disp == 0) ? dbg_on_a_line_number : dbg_not_on_a_line_number;
|
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)
|
static BOOL CALLBACK info_locals_cb(SYMBOL_INFO* sym, ULONG size, void* ctx)
|
||||||
{
|
{
|
||||||
DWORD tid;
|
ULONG v, val;
|
||||||
ULONG v, val;
|
const char* explain = NULL;
|
||||||
const char* explain = NULL;
|
char buf[128];
|
||||||
char buf[128];
|
struct dbg_type type;
|
||||||
|
|
||||||
dbg_printf("\t");
|
dbg_printf("\t");
|
||||||
types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_TYPE, &tid);
|
type.module = sym->ModBase;
|
||||||
types_print_type(sym->ModBase, tid, FALSE);
|
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";
|
if (sym->Flags & SYMFLAG_LOCAL) explain = "local";
|
||||||
else if (sym->Flags & SYMFLAG_PARAMETER) explain = "parameter";
|
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)
|
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;
|
v += ((IMAGEHLP_STACK_FRAME*)ctx)->FrameOffset;
|
||||||
|
|
||||||
dbg_read_memory_verbose((void*)v, &val, sizeof(val));
|
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)
|
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);
|
dbg_printf("%08lx: %s (", sym->Address, sym->Name);
|
||||||
if (sym->TypeIndex != dbg_itype_none && sym->TypeIndex != 0 &&
|
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");
|
dbg_printf(")\n");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -39,19 +39,16 @@ long int types_extract_as_integer(const struct dbg_lvalue* lvalue)
|
||||||
{
|
{
|
||||||
long int rtn = 0;
|
long int rtn = 0;
|
||||||
DWORD tag, size, bt;
|
DWORD tag, size, bt;
|
||||||
DWORD linear = (DWORD)memory_to_linear_addr(&lvalue->addr);
|
|
||||||
|
|
||||||
assert(lvalue->cookie == DLV_TARGET || lvalue->cookie == DLV_HOST);
|
if (lvalue->type.id == dbg_itype_none ||
|
||||||
|
!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
|
||||||
if (lvalue->typeid == dbg_itype_none ||
|
|
||||||
!types_get_info(linear, lvalue->typeid, TI_GET_SYMTAG, &tag))
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
switch (tag)
|
switch (tag)
|
||||||
{
|
{
|
||||||
case SymTagBaseType:
|
case SymTagBaseType:
|
||||||
if (!types_get_info(linear, lvalue->typeid, TI_GET_LENGTH, &size) ||
|
if (!types_get_info(&lvalue->type, TI_GET_LENGTH, &size) ||
|
||||||
!types_get_info(linear, lvalue->typeid, 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);
|
||||||
|
@ -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)
|
BOOL types_deref(const struct dbg_lvalue* lvalue, struct dbg_lvalue* result)
|
||||||
{
|
{
|
||||||
DWORD tag;
|
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));
|
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.
|
* 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 ||
|
tag != SymTagPointerType ||
|
||||||
memory_read_value(lvalue, sizeof(result->addr.Offset), &result->addr.Offset) ||
|
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;
|
return FALSE;
|
||||||
|
result->type.module = lvalue->type.module;
|
||||||
result->cookie = DLV_TARGET; /* see comment on DEREF below */
|
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;
|
result->addr.Mode = AddrModeFlat;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -133,19 +141,20 @@ BOOL types_deref(const struct dbg_lvalue* lvalue, struct dbg_lvalue* result)
|
||||||
*
|
*
|
||||||
* Implement a structure derefencement
|
* Implement a structure derefencement
|
||||||
*/
|
*/
|
||||||
static BOOL types_get_udt_element_lvalue(struct dbg_lvalue* lvalue, DWORD linear,
|
static BOOL types_get_udt_element_lvalue(struct dbg_lvalue* lvalue,
|
||||||
DWORD typeid, long int* tmpbuf)
|
const struct dbg_type* type, long int* tmpbuf)
|
||||||
{
|
{
|
||||||
DWORD offset, length, bitoffset;
|
DWORD offset, length, bitoffset;
|
||||||
DWORD bt;
|
DWORD bt;
|
||||||
unsigned mask;
|
unsigned mask;
|
||||||
|
|
||||||
types_get_info(linear, typeid, TI_GET_TYPE, &lvalue->typeid);
|
types_get_info(type, TI_GET_TYPE, &lvalue->type.id);
|
||||||
types_get_info(linear, typeid, TI_GET_OFFSET, &offset);
|
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;
|
if (length > sizeof(*tmpbuf)) return FALSE;
|
||||||
/*
|
/*
|
||||||
* Bitfield operation. We have to extract the field and store
|
* 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 >>= bitoffset & 7;
|
||||||
*tmpbuf &= ~mask;
|
*tmpbuf &= ~mask;
|
||||||
|
|
||||||
lvalue->cookie = DLV_HOST;
|
lvalue->cookie = DLV_HOST;
|
||||||
lvalue->addr.Mode = AddrModeFlat;
|
|
||||||
lvalue->addr.Offset = (DWORD)tmpbuf;
|
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,
|
* Check to see whether the basic type is signed or not, and if so,
|
||||||
* we need to sign extend the number.
|
* 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))))
|
bt == btInt && (*tmpbuf & (1 << (length - 1))))
|
||||||
{
|
{
|
||||||
*tmpbuf |= mask;
|
*tmpbuf |= mask;
|
||||||
}
|
}
|
||||||
return TRUE;
|
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;
|
lvalue->addr.Offset += offset;
|
||||||
return TRUE;
|
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)
|
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;
|
DWORD tag, count;
|
||||||
char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
|
char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
|
||||||
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
|
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
|
||||||
WCHAR* ptr;
|
WCHAR* ptr;
|
||||||
char tmp[256];
|
char tmp[256];
|
||||||
int i;
|
int i;
|
||||||
|
struct dbg_type type;
|
||||||
|
|
||||||
assert(lvalue->cookie == DLV_TARGET || lvalue->cookie == DLV_HOST);
|
if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag) ||
|
||||||
|
|
||||||
if (!types_get_info(linear, lvalue->typeid, TI_GET_SYMTAG, &tag) ||
|
|
||||||
tag != SymTagUDT)
|
tag != SymTagUDT)
|
||||||
return FALSE;
|
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;
|
fcp->Start = 0;
|
||||||
while (count)
|
while (count)
|
||||||
{
|
{
|
||||||
fcp->Count = min(count, 256);
|
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++)
|
for (i = 0; i < min(fcp->Count, count); i++)
|
||||||
{
|
{
|
||||||
ptr = NULL;
|
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;
|
if (!ptr) continue;
|
||||||
WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
|
WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
|
||||||
HeapFree(GetProcessHeap(), 0, ptr);
|
HeapFree(GetProcessHeap(), 0, ptr);
|
||||||
if (strcmp(tmp, name)) continue;
|
if (strcmp(tmp, name)) continue;
|
||||||
|
|
||||||
return types_get_udt_element_lvalue(lvalue, linear,
|
return types_get_udt_element_lvalue(lvalue, &type, tmpbuf);
|
||||||
fcp->ChildId[i], tmpbuf);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
count -= min(count, 256);
|
count -= min(count, 256);
|
||||||
|
@ -238,26 +245,23 @@ BOOL types_array_index(const struct dbg_lvalue* lvalue, int index,
|
||||||
struct dbg_lvalue* result)
|
struct dbg_lvalue* result)
|
||||||
{
|
{
|
||||||
DWORD tag, length, count;
|
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(&lvalue->type, TI_GET_SYMTAG, &tag))
|
||||||
|
|
||||||
if (!types_get_info(0, lvalue->typeid, TI_GET_SYMTAG, &tag))
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
switch (tag)
|
switch (tag)
|
||||||
{
|
{
|
||||||
case SymTagArrayType:
|
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;
|
if (index < 0 || index >= count) return FALSE;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case SymTagPointerType:
|
case SymTagPointerType:
|
||||||
/*
|
/*
|
||||||
* Get the base type, so we know how much to index by.
|
* 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(&lvalue->type, TI_GET_TYPE, &result->type.id);
|
||||||
types_get_info(linear, result->typeid, TI_GET_LENGTH, &length);
|
result->type.module = lvalue->type.module;
|
||||||
|
types_get_info(&result->type, TI_GET_LENGTH, &length);
|
||||||
/* Contents of array must be on same target */
|
/* Contents of array must be on same target */
|
||||||
result->cookie = lvalue->cookie;
|
|
||||||
result->addr.Mode = lvalue->addr.Mode;
|
result->addr.Mode = lvalue->addr.Mode;
|
||||||
memory_read_value(lvalue, sizeof(result->addr.Offset), &result->addr.Offset);
|
memory_read_value(lvalue, sizeof(result->addr.Offset), &result->addr.Offset);
|
||||||
result->addr.Offset += index * length;
|
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;
|
struct type_find_t* user = (struct type_find_t*)_user;
|
||||||
BOOL ret = TRUE;
|
BOOL ret = TRUE;
|
||||||
DWORD typeid;
|
struct dbg_type type;
|
||||||
|
|
||||||
if (sym->Tag == user->tag)
|
if (sym->Tag == user->tag)
|
||||||
{
|
{
|
||||||
|
@ -297,9 +301,9 @@ static BOOL CALLBACK types_cb(PSYMBOL_INFO sym, ULONG size, void* _user)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SymTagPointerType:
|
case SymTagPointerType:
|
||||||
types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_TYPE, &typeid);
|
type.module = sym->ModBase;
|
||||||
if (types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_TYPE, &typeid) &&
|
type.id = sym->TypeIndex;
|
||||||
typeid == user->u.typeid)
|
if (types_get_info(&type, TI_GET_TYPE, &type.id) && type.id == user->u.typeid)
|
||||||
{
|
{
|
||||||
user->result = sym->TypeIndex;
|
user->result = sym->TypeIndex;
|
||||||
ret = FALSE;
|
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
|
* Should look up in module based at linear whether (typeid*) exists
|
||||||
* Otherwise, we could create it locally
|
* 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 type_find_t f;
|
||||||
|
struct dbg_type ret;
|
||||||
|
|
||||||
f.result = dbg_itype_none;
|
f.result = dbg_itype_none;
|
||||||
f.tag = SymTagPointerType;
|
f.tag = SymTagPointerType;
|
||||||
f.u.typeid = typeid;
|
f.u.typeid = type->id;
|
||||||
SymEnumTypes(dbg_curr_process->handle, linear, types_cb, &f);
|
SymEnumTypes(dbg_curr_process->handle, type->module, types_cb, &f);
|
||||||
return f.result;
|
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
|
* Should look up in the module based at linear address whether a type
|
||||||
* named 'name' and with the correct tag exists
|
* 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 type_find_t f;
|
||||||
|
struct dbg_type ret;
|
||||||
|
|
||||||
f.result = dbg_itype_none;
|
f.result = dbg_itype_none;
|
||||||
f.tag = tag;
|
f.tag = tag;
|
||||||
f.u.name = name;
|
f.u.name = name;
|
||||||
SymEnumTypes(dbg_curr_process->handle, linear, types_cb, &f);
|
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;
|
struct dbg_lvalue lvalue_field;
|
||||||
int i;
|
int i;
|
||||||
unsigned long linear;
|
|
||||||
DWORD tag;
|
DWORD tag;
|
||||||
DWORD count;
|
DWORD count;
|
||||||
DWORD size;
|
DWORD size;
|
||||||
|
|
||||||
assert(lvalue->cookie == DLV_TARGET || lvalue->cookie == DLV_HOST);
|
if (lvalue->type.id == dbg_itype_none)
|
||||||
linear = (unsigned long)memory_to_linear_addr(&lvalue->addr);
|
|
||||||
|
|
||||||
if (lvalue->typeid == dbg_itype_none)
|
|
||||||
{
|
{
|
||||||
/* No type, just print the addr value */
|
/* No type, just print the addr value */
|
||||||
print_bare_address(&lvalue->addr);
|
print_bare_address(&lvalue->addr);
|
||||||
|
@ -373,7 +381,7 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level)
|
||||||
format = '\0';
|
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");
|
WINE_FIXME("---error\n");
|
||||||
return;
|
return;
|
||||||
|
@ -386,32 +394,34 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level)
|
||||||
print_basic(lvalue, 1, format);
|
print_basic(lvalue, 1, format);
|
||||||
break;
|
break;
|
||||||
case SymTagUDT:
|
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)];
|
char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
|
||||||
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
|
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
|
||||||
WCHAR* ptr;
|
WCHAR* ptr;
|
||||||
char tmp[256];
|
char tmp[256];
|
||||||
long int tmpbuf;
|
long int tmpbuf;
|
||||||
|
struct dbg_type type;
|
||||||
|
|
||||||
dbg_printf("{");
|
dbg_printf("{");
|
||||||
fcp->Start = 0;
|
fcp->Start = 0;
|
||||||
while (count)
|
while (count)
|
||||||
{
|
{
|
||||||
fcp->Count = min(count, 256);
|
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++)
|
for (i = 0; i < min(fcp->Count, count); i++)
|
||||||
{
|
{
|
||||||
ptr = NULL;
|
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;
|
if (!ptr) continue;
|
||||||
WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
|
WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
|
||||||
dbg_printf("%s=", tmp);
|
dbg_printf("%s=", tmp);
|
||||||
HeapFree(GetProcessHeap(), 0, ptr);
|
HeapFree(GetProcessHeap(), 0, ptr);
|
||||||
lvalue_field = *lvalue;
|
lvalue_field = *lvalue;
|
||||||
if (types_get_udt_element_lvalue(&lvalue_field, linear,
|
if (types_get_udt_element_lvalue(&lvalue_field, &type, &tmpbuf))
|
||||||
fcp->ChildId[i], &tmpbuf))
|
|
||||||
{
|
{
|
||||||
print_value(&lvalue_field, format, level + 1);
|
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.
|
* Loop over all of the entries, printing stuff as we go.
|
||||||
*/
|
*/
|
||||||
count = 1; size = 1;
|
count = 1; size = 1;
|
||||||
types_get_info(linear, lvalue->typeid, TI_GET_COUNT, &count);
|
types_get_info(&lvalue->type, TI_GET_COUNT, &count);
|
||||||
types_get_info(linear, lvalue->typeid, TI_GET_LENGTH, &size);
|
types_get_info(&lvalue->type, TI_GET_LENGTH, &size);
|
||||||
|
|
||||||
if (size == count)
|
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!!!!)... */
|
/* FIXME should check basic type here (should be a char!!!!)... */
|
||||||
len = min(count, sizeof(buffer));
|
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),
|
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) ? "..." : "");
|
dbg_printf("\"%s%s\"", buffer, (len < count) ? "..." : "");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
lvalue_field = *lvalue;
|
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("{");
|
dbg_printf("{");
|
||||||
for (i = 0; i < count; i++)
|
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 ");
|
dbg_printf("Function ");
|
||||||
print_bare_address(&lvalue->addr);
|
print_bare_address(&lvalue->addr);
|
||||||
dbg_printf(": ");
|
dbg_printf(": ");
|
||||||
types_print_type(linear, lvalue->typeid, FALSE);
|
types_print_type(&lvalue->type, FALSE);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
WINE_FIXME("Unknown tag (%lu)\n", tag);
|
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)
|
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");
|
dbg_printf("\n");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -492,20 +506,21 @@ int print_types(void)
|
||||||
return 0;
|
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;
|
WCHAR* ptr;
|
||||||
char tmp[256];
|
char tmp[256];
|
||||||
const char* name;
|
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;
|
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);
|
WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
|
||||||
name = tmp;
|
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);
|
if (details) dbg_printf("Basic<%s>", name); else dbg_printf("%s", name);
|
||||||
break;
|
break;
|
||||||
case SymTagPointerType:
|
case SymTagPointerType:
|
||||||
types_get_info(linear, typeid, TI_GET_TYPE, &subtype);
|
types_get_info(type, TI_GET_TYPE, &subtype.id);
|
||||||
types_print_type(linear, subtype, details);
|
subtype.module = type->module;
|
||||||
|
types_print_type(&subtype, FALSE);
|
||||||
dbg_printf("*");
|
dbg_printf("*");
|
||||||
break;
|
break;
|
||||||
case SymTagUDT:
|
case SymTagUDT:
|
||||||
types_get_info(linear, typeid, TI_GET_UDTKIND, &subtype);
|
types_get_info(type, TI_GET_UDTKIND, &udt);
|
||||||
switch (subtype)
|
switch (udt)
|
||||||
{
|
{
|
||||||
case UdtStruct: dbg_printf("struct %s", name); break;
|
case UdtStruct: dbg_printf("struct %s", name); break;
|
||||||
case UdtUnion: dbg_printf("union %s", name); break;
|
case UdtUnion: dbg_printf("union %s", name); break;
|
||||||
case UdtClass: dbg_printf("class %s", name); break;
|
case UdtClass: dbg_printf("class %s", name); break;
|
||||||
}
|
}
|
||||||
if (details &&
|
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)];
|
char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
|
||||||
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
|
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
|
||||||
WCHAR* ptr;
|
WCHAR* ptr;
|
||||||
char tmp[256];
|
char tmp[256];
|
||||||
int i;
|
int i;
|
||||||
|
struct dbg_type type_elt;
|
||||||
dbg_printf(" {");
|
dbg_printf(" {");
|
||||||
|
|
||||||
fcp->Start = 0;
|
fcp->Start = 0;
|
||||||
while (count)
|
while (count)
|
||||||
{
|
{
|
||||||
fcp->Count = min(count, 256);
|
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++)
|
for (i = 0; i < min(fcp->Count, count); i++)
|
||||||
{
|
{
|
||||||
ptr = NULL;
|
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;
|
if (!ptr) continue;
|
||||||
WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
|
WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
|
||||||
HeapFree(GetProcessHeap(), 0, ptr);
|
HeapFree(GetProcessHeap(), 0, ptr);
|
||||||
dbg_printf("%s", tmp);
|
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(":");
|
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(", ");
|
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;
|
break;
|
||||||
case SymTagArrayType:
|
case SymTagArrayType:
|
||||||
types_get_info(linear, typeid, TI_GET_TYPE, &subtype);
|
types_get_info(type, TI_GET_TYPE, &subtype.id);
|
||||||
types_print_type(linear, subtype, details);
|
subtype.module = type->module;
|
||||||
|
types_print_type(&subtype, details);
|
||||||
dbg_printf(" %s[]", name);
|
dbg_printf(" %s[]", name);
|
||||||
break;
|
break;
|
||||||
case SymTagEnum:
|
case SymTagEnum:
|
||||||
dbg_printf("enum %s", name);
|
dbg_printf("enum %s", name);
|
||||||
break;
|
break;
|
||||||
case SymTagFunctionType:
|
case SymTagFunctionType:
|
||||||
types_get_info(linear, typeid, TI_GET_TYPE, &subtype);
|
types_get_info(type, TI_GET_TYPE, &subtype.id);
|
||||||
types_print_type(linear, subtype, FALSE);
|
subtype.module = type->module;
|
||||||
|
types_print_type(&subtype, FALSE);
|
||||||
dbg_printf(" (*%s)(", name);
|
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)];
|
char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
|
||||||
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
|
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
|
||||||
|
@ -592,11 +612,12 @@ int types_print_type(DWORD linear, DWORD typeid, BOOL details)
|
||||||
while (count)
|
while (count)
|
||||||
{
|
{
|
||||||
fcp->Count = min(count, 256);
|
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++)
|
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(", ");
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL types_get_info(unsigned long modbase, unsigned long typeid,
|
BOOL types_get_info(const struct dbg_type* type, IMAGEHLP_SYMBOL_TYPE_INFO ti, void* pInfo)
|
||||||
IMAGEHLP_SYMBOL_TYPE_INFO ti, void* pInfo)
|
|
||||||
{
|
{
|
||||||
if (typeid == dbg_itype_none) return FALSE;
|
if (type->id == dbg_itype_none) return FALSE;
|
||||||
if (typeid < dbg_itype_first)
|
if (type->module != 0)
|
||||||
{
|
return SymGetTypeInfo(dbg_curr_process->handle, type->module, type->id, ti, pInfo);
|
||||||
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);
|
|
||||||
|
|
||||||
|
assert(type->id >= dbg_itype_first);
|
||||||
/* helper to typecast pInfo to its expected type (_t) */
|
/* helper to typecast pInfo to its expected type (_t) */
|
||||||
#define X(_t) (*((_t*)pInfo))
|
#define X(_t) (*((_t*)pInfo))
|
||||||
|
|
||||||
switch (typeid)
|
switch (type->id)
|
||||||
{
|
{
|
||||||
case dbg_itype_unsigned_int:
|
case dbg_itype_unsigned_int:
|
||||||
switch (ti)
|
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;
|
default: WINE_FIXME("unsupported %u for a string\n", ti); return FALSE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: WINE_FIXME("unsupported typeid 0x%lx\n", typeid);
|
default: WINE_FIXME("unsupported type id 0x%lx\n", type->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef X
|
#undef X
|
||||||
|
|
|
@ -45,6 +45,9 @@
|
||||||
* + make the output as close as possible to what gdb does
|
* + make the output as close as possible to what gdb does
|
||||||
* - symbol management:
|
* - symbol management:
|
||||||
* + symbol table loading is broken
|
* + 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:
|
* - type management:
|
||||||
* + some bits of internal types are missing (like type casts and the address
|
* + some bits of internal types are missing (like type casts and the address
|
||||||
* operator)
|
* operator)
|
||||||
|
@ -55,7 +58,10 @@
|
||||||
* o bitfield size is on a 4-bytes
|
* o bitfield size is on a 4-bytes
|
||||||
* + some bits of internal types are missing (like type casts and the address
|
* + some bits of internal types are missing (like type casts and the address
|
||||||
* operator)
|
* 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
|
* + set a better fix for gdb (proxy mode) than the step-mode hack
|
||||||
* + implement function call in debuggee
|
* + implement function call in debuggee
|
||||||
* + trampoline management is broken when getting 16 <=> 32 thunk destination
|
* + 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->wait_for_first_exception = 0;
|
||||||
t->exec_mode = dbg_exec_cont;
|
t->exec_mode = dbg_exec_cont;
|
||||||
t->exec_count = 0;
|
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);
|
snprintf(t->name, sizeof(t->name), "0x%08lx", tid);
|
||||||
|
|
||||||
|
@ -354,8 +362,8 @@ static void dbg_init_current_thread(void* start)
|
||||||
{
|
{
|
||||||
if (start)
|
if (start)
|
||||||
{
|
{
|
||||||
if (dbg_curr_thread->process->threads &&
|
if (dbg_curr_process->threads &&
|
||||||
!dbg_curr_thread->process->threads->next && /* first thread ? */
|
!dbg_curr_process->threads->next && /* first thread ? */
|
||||||
DBG_IVAR(BreakAllThreadsStartup))
|
DBG_IVAR(BreakAllThreadsStartup))
|
||||||
{
|
{
|
||||||
ADDRESS addr;
|
ADDRESS addr;
|
||||||
|
@ -562,8 +570,7 @@ static DWORD dbg_handle_exception(EXCEPTION_RECORD* rec, BOOL first_chance,
|
||||||
else
|
else
|
||||||
pThread = dbg_get_thread(dbg_curr_process, pThreadName->dwThreadID);
|
pThread = dbg_get_thread(dbg_curr_process, pThreadName->dwThreadID);
|
||||||
|
|
||||||
if (ReadProcessMemory(dbg_curr_thread->process->handle, pThreadName->szName,
|
if (dbg_read_memory(pThreadName->szName, pThread->name, 9))
|
||||||
pThread->name, 9, NULL))
|
|
||||||
dbg_printf("Thread ID=0x%lx renamed using MS VC6 extension (name==\"%s\")\n",
|
dbg_printf("Thread ID=0x%lx renamed using MS VC6 extension (name==\"%s\")\n",
|
||||||
pThread->tid, pThread->name);
|
pThread->tid, pThread->name);
|
||||||
return DBG_CONTINUE;
|
return DBG_CONTINUE;
|
||||||
|
@ -636,11 +643,11 @@ static DWORD dbg_handle_exception(EXCEPTION_RECORD* rec, BOOL first_chance,
|
||||||
case EXCEPTION_WINE_STUB:
|
case EXCEPTION_WINE_STUB:
|
||||||
{
|
{
|
||||||
char dll[32], name[64];
|
char dll[32], name[64];
|
||||||
memory_get_string(dbg_curr_thread->process->handle,
|
memory_get_string(dbg_curr_process->handle,
|
||||||
(void*)rec->ExceptionInformation[0], DLV_TARGET, FALSE,
|
(void*)rec->ExceptionInformation[0], TRUE, FALSE,
|
||||||
dll, sizeof(dll));
|
dll, sizeof(dll));
|
||||||
memory_get_string(dbg_curr_thread->process->handle,
|
memory_get_string(dbg_curr_process->handle,
|
||||||
(void*)rec->ExceptionInformation[1], DLV_TARGET, FALSE,
|
(void*)rec->ExceptionInformation[1], TRUE, FALSE,
|
||||||
name, sizeof(name));
|
name, sizeof(name));
|
||||||
dbg_printf("unimplemented function %s.%s called", dll, 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");
|
WINE_ERR("Unknown thread\n");
|
||||||
break;
|
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.lpImageName,
|
||||||
de->u.LoadDll.fUnicode,
|
de->u.LoadDll.fUnicode,
|
||||||
buffer, sizeof(buffer));
|
buffer, sizeof(buffer));
|
||||||
|
@ -894,8 +901,8 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
memory_get_string(dbg_curr_thread->process->handle,
|
memory_get_string(dbg_curr_process->handle,
|
||||||
de->u.DebugString.lpDebugStringData, DLV_TARGET,
|
de->u.DebugString.lpDebugStringData, TRUE,
|
||||||
de->u.DebugString.fUnicode, buffer, sizeof(buffer));
|
de->u.DebugString.fUnicode, buffer, sizeof(buffer));
|
||||||
WINE_TRACE("%08lx:%08lx: output debug string (%s)\n",
|
WINE_TRACE("%08lx:%08lx: output debug string (%s)\n",
|
||||||
de->dwProcessId, de->dwThreadId, buffer);
|
de->dwProcessId, de->dwThreadId, buffer);
|
||||||
|
|
Loading…
Reference in a new issue