diff --git a/documentation/debugger.sgml b/documentation/debugger.sgml
index 43d97efef19..17e611cc67c 100644
--- a/documentation/debugger.sgml
+++ b/documentation/debugger.sgml
@@ -1683,17 +1683,19 @@ set $BreakAllThreadsStartup = 1
-
-
- display
-
- info display
-
-
-
+ info display
lists the active displays
+
+
+ display
+
+
+ print the active displays' values (as done each
+ time the debugger stops)
+
+
display <expr>
diff --git a/programs/winedbg/break.c b/programs/winedbg/break.c
index c78258b92ba..707ba5f795a 100644
--- a/programs/winedbg/break.c
+++ b/programs/winedbg/break.c
@@ -59,8 +59,7 @@ void break_set_xpoints(BOOL set)
for (i = 0; i < dbg_curr_process->next_bp; i++)
{
- if (!bp[i].refcount && !bp[i].enabled)
- continue;
+ if (!bp[i].refcount || !bp[i].enabled) continue;
if (bp[i].xpoint_type == be_xpoint_break)
size = 0;
@@ -78,8 +77,9 @@ void break_set_xpoints(BOOL set)
bp[i].info, size);
if (!ret)
{
- dbg_printf("Invalid address (%p) for breakpoint %d, disabling it\n",
- addr, i);
+ dbg_printf("Invalid address (");
+ print_address(&bp[i].addr, FALSE);
+ dbg_printf(") for breakpoint %d, disabling it\n", i);
bp[i].enabled = FALSE;
}
}
@@ -375,10 +375,9 @@ void break_add_watch(const struct dbg_lvalue* lvalue, BOOL is_write)
&lvalue->addr);
if (num == -1) return;
- if (lvalue->typeid != dbg_itype_none)
+ if (lvalue->type.id != dbg_itype_none)
{
- if (types_get_info((DWORD)memory_to_linear_addr(&lvalue->addr),
- lvalue->typeid, TI_GET_LENGTH, &l))
+ if (types_get_info(&lvalue->type, TI_GET_LENGTH, &l))
{
switch (l)
{
@@ -679,7 +678,7 @@ static BOOL should_stop(int bpnum)
{
struct dbg_lvalue lvalue = expr_eval(bp->condition);
- if (lvalue.typeid == dbg_itype_none)
+ if (lvalue.type.id == dbg_itype_none)
{
/*
* Something wrong - unable to evaluate this expression.
diff --git a/programs/winedbg/dbg.y b/programs/winedbg/dbg.y
index e991508413e..5fab86575ec 100644
--- a/programs/winedbg/dbg.y
+++ b/programs/winedbg/dbg.y
@@ -133,7 +133,7 @@ command:
| tSOURCE pathname { parser($2); }
| tSYMBOLFILE pathname { symbol_read_symtable($2, 0); }
| tSYMBOLFILE pathname expr_rvalue { symbol_read_symtable($2, $3); }
- | tWHATIS expr_lvalue { types_print_type((DWORD)memory_to_linear_addr(&$2.addr), $2.typeid, FALSE); dbg_printf("\n"); }
+ | tWHATIS expr_lvalue { types_print_type(&$2.type, FALSE); dbg_printf("\n"); }
| tATTACH tNUM { dbg_attach_debuggee($2, FALSE, TRUE); }
| tDETACH { dbg_detach_debuggee(); }
| run_command
@@ -202,8 +202,8 @@ set_command:
;
x_command:
- tEXAM expr_lvalue { memory_examine(&$2, 1, 'x'); }
- | tEXAM tFORMAT expr_lvalue { memory_examine(&$3, $2 >> 8, $2 & 0xff); }
+ tEXAM expr_rvalue { memory_examine((void*)$2, 1, 'x'); }
+ | tEXAM tFORMAT expr_rvalue { memory_examine((void*)$3, $2 >> 8, $2 & 0xff); }
;
print_command:
@@ -231,7 +231,7 @@ watch_command:
;
display_command:
- tDISPLAY { display_info(); }
+ tDISPLAY { display_print(); }
| tDISPLAY expr { display_add($2, 1, 0, FALSE); }
| tDISPLAY tFORMAT expr { display_add($3, $2 >> 8, $2 & 0xff, FALSE); }
| tLOCAL tDISPLAY expr { display_add($3, 1, 0, TRUE); }
@@ -280,27 +280,27 @@ noprocess_state:
;
type_expr:
- tCHAR { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_char; }
- | tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_int; }
- | tLONG tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_long_int; }
- | tLONG { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_long_int; }
- | tUNSIGNED tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_int; }
- | tUNSIGNED { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_int; }
- | tLONG tUNSIGNED tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_long_int; }
- | tLONG tUNSIGNED { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_long_int; }
- | tSHORT tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_short_int; }
- | tSHORT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_short_int; }
- | tSHORT tUNSIGNED tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_short_int; }
- | tSHORT tUNSIGNED { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_short_int; }
- | tSIGNED tCHAR { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_char_int; }
- | tUNSIGNED tCHAR { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_char_int; }
- | tLONG tLONG tUNSIGNED tINT{ $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_longlong_int; }
- | tLONG tLONG tUNSIGNED { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_longlong_int; }
- | tLONG tLONG tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_longlong_int; }
- | tLONG tLONG { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_longlong_int; }
- | tFLOAT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_short_real; }
- | tDOUBLE { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_real; }
- | tLONG tDOUBLE { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_long_real; }
+ tCHAR { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_char; }
+ | tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_signed_int; }
+ | tLONG tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_signed_long_int; }
+ | tLONG { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_signed_long_int; }
+ | tUNSIGNED tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_int; }
+ | tUNSIGNED { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_int; }
+ | tLONG tUNSIGNED tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_long_int; }
+ | tLONG tUNSIGNED { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_long_int; }
+ | tSHORT tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_signed_short_int; }
+ | tSHORT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_signed_short_int; }
+ | tSHORT tUNSIGNED tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_short_int; }
+ | tSHORT tUNSIGNED { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_short_int; }
+ | tSIGNED tCHAR { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_signed_char_int; }
+ | tUNSIGNED tCHAR { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_char_int; }
+ | tLONG tLONG tUNSIGNED tINT{ $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_longlong_int; }
+ | tLONG tLONG tUNSIGNED { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_longlong_int; }
+ | tLONG tLONG tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_signed_longlong_int; }
+ | tLONG tLONG { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_signed_longlong_int; }
+ | tFLOAT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_short_real; }
+ | tDOUBLE { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_real; }
+ | tLONG tDOUBLE { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_long_real; }
| type_expr '*' { $$ = $1; $$.deref_count++; }
| tCLASS identifier { $$.type = type_expr_udt_class; $$.deref_count = 0; $$.u.name = lexeme_alloc($2); }
| tSTRUCT identifier { $$.type = type_expr_udt_struct; $$.deref_count = 0; $$.u.name = lexeme_alloc($2); }
diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h
index 23c9c9154d5..d89f1893ec7 100644
--- a/programs/winedbg/debugger.h
+++ b/programs/winedbg/debugger.h
@@ -82,6 +82,18 @@ enum dbg_internal_types
dbg_itype_none = 0xffffffff
};
+/* type description (in the following order):
+ * - if 'id' is dbg_itype_none (whatever 'module' value), the type isn't known
+ * - if 'module' is 0, it's an internal type (id is one of dbg_itype...)
+ * - if 'module' is non 0, then 'id' is a type ID referring to module (loaded in
+ * dbghelp) which (linear) contains address 'module'.
+ */
+struct dbg_type
+{
+ unsigned long id;
+ DWORD module;
+};
+
struct dbg_lvalue /* structure to hold left-values... */
{
int cookie; /* DLV_??? */
@@ -91,7 +103,7 @@ struct dbg_lvalue /* structure to hold left-values... */
# define DLV_TARGET 0xF00D
# define DLV_HOST 0x50DA
ADDRESS addr;
- unsigned long typeid;
+ struct dbg_type type;
};
enum dbg_exec_mode
@@ -202,7 +214,7 @@ struct dbg_internal_var
DWORD val;
const char* name;
LPDWORD pval;
- unsigned long typeid;
+ unsigned long typeid; /* always internal type */
};
enum sym_get_lval {sglv_found, sglv_unknown, sglv_aborted};
@@ -222,7 +234,7 @@ struct type_expr_t
unsigned deref_count;
union
{
- unsigned long typeid;
+ struct dbg_type type;
const char* name;
} u;
};
@@ -293,15 +305,15 @@ extern void info_win32_segments(DWORD start, int length);
extern void info_wine_dbg_channel(BOOL add, const char* chnl, const char* name);
/* memory.c */
-extern BOOL memory_read_value(const struct dbg_lvalue* val, DWORD size, void* result);
+extern BOOL memory_read_value(const struct dbg_lvalue* lvalue, DWORD size, void* result);
extern BOOL memory_write_value(const struct dbg_lvalue* val, DWORD size, void* value);
-extern void memory_examine(const struct dbg_lvalue* addr, int count, char format);
+extern void memory_examine(void* linear, int count, char format);
extern void memory_report_invalid_addr(const void* addr);
extern void* memory_to_linear_addr(const ADDRESS* address);
extern BOOL memory_get_current_pc(ADDRESS* address);
extern BOOL memory_get_current_stack(ADDRESS* address);
extern BOOL memory_get_current_frame(ADDRESS* address);
-extern BOOL memory_get_string(HANDLE hp, void* addr, unsigned cookie, BOOL unicode, char* buffer, int size);
+extern BOOL memory_get_string(HANDLE hp, void* addr, BOOL in_debuggee, BOOL unicode, char* buffer, int size);
extern BOOL memory_get_string_indirect(HANDLE hp, void* addr, BOOL unicode, char* buffer, int size);
extern void memory_disassemble(const struct dbg_lvalue*, const struct dbg_lvalue*, int offset);
extern BOOL memory_disasm_one_insn(ADDRESS* addr);
@@ -333,16 +345,15 @@ extern int symbol_info_locals(void);
/* types.c */
extern void print_value(const struct dbg_lvalue* addr, char format, int level);
-extern int types_print_type(DWORD linear, DWORD typeid, BOOL details);
+extern int types_print_type(const struct dbg_type*, BOOL details);
extern int print_types(void);
extern long int types_extract_as_integer(const struct dbg_lvalue*);
extern BOOL types_deref(const struct dbg_lvalue* value, struct dbg_lvalue* result);
extern BOOL types_udt_find_element(struct dbg_lvalue* value, const char* name, long int* tmpbuf);
extern BOOL types_array_index(const struct dbg_lvalue* value, int index, struct dbg_lvalue* result);
-extern BOOL types_get_info(unsigned long, unsigned long,
- IMAGEHLP_SYMBOL_TYPE_INFO, void*);
-extern unsigned long types_find_pointer(unsigned long linear, unsigned long typeid);
-extern unsigned long types_find_type(unsigned long linear, const char* name, enum SymTagEnum tag);
+extern BOOL types_get_info(const struct dbg_type*, IMAGEHLP_SYMBOL_TYPE_INFO, void*);
+extern struct dbg_type types_find_pointer(const struct dbg_type* type);
+extern struct dbg_type types_find_type(unsigned long linear, const char* name, enum SymTagEnum tag);
/* winedbg.c */
extern void dbg_outputA(const char* buffer, int len);
diff --git a/programs/winedbg/display.c b/programs/winedbg/display.c
index e72f33eb03d..f49a7011d9c 100644
--- a/programs/winedbg/display.c
+++ b/programs/winedbg/display.c
@@ -43,10 +43,18 @@ struct display
static struct display *displaypoints = NULL;
static unsigned int maxdisplays = 0, ndisplays = 0;
+#define OFFSET_OF(_f,_s) ((unsigned)(&(((_s*)NULL)->_f)))
+
static inline BOOL cmp_symbol(const SYMBOL_INFO* si1, const SYMBOL_INFO* si2)
{
- if (si1->NameLen != si2->NameLen) return FALSE;
- return !memcmp(si1, si2, sizeof(SYMBOL_INFO) + si1->NameLen);
+ /* FIXME: !memcmp(si1, si2, sizeof(SYMBOL_INFO) + si1->NameLen)
+ * is wrong because sizeof(SYMBOL_INFO) can be aligned on 4-byte boundary
+ * Note: we also need to zero out the structures before calling
+ * stack_get_frame, so that un-touched fields by stack_get_frame
+ * get the same value!!
+ */
+ return !memcmp(si1, si2, OFFSET_OF(Name, SYMBOL_INFO)) &&
+ !memcmp(si1->Name, si2->Name, si1->NameLen);
}
int display_add(struct expr *exp, int count, char format, int in_frame)
@@ -74,6 +82,7 @@ int display_add(struct expr *exp, int count, char format, int in_frame)
if (in_frame)
{
displaypoints[i].func = (SYMBOL_INFO*)displaypoints[i].func_buffer;
+ memset(displaypoints[i].func, 0, sizeof(SYMBOL_INFO));
displaypoints[i].func->SizeOfStruct = sizeof(SYMBOL_INFO);
displaypoints[i].func->MaxNameLen = sizeof(displaypoints[i].func_buffer) -
sizeof(*displaypoints[i].func);
@@ -97,6 +106,7 @@ int display_info(void)
const char* info;
func = (SYMBOL_INFO*)buffer;
+ memset(func, 0, sizeof(SYMBOL_INFO));
func->SizeOfStruct = sizeof(SYMBOL_INFO);
func->MaxNameLen = sizeof(buffer) - sizeof(*func);
if (!stack_get_frame(func, NULL)) return FALSE;
@@ -105,6 +115,9 @@ int display_info(void)
{
if (displaypoints[i].exp == NULL) continue;
+ dbg_printf("%d: ", i + 1);
+ expr_print(displaypoints[i].exp);
+
if (displaypoints[i].enabled)
{
if (displaypoints[i].func && !cmp_symbol(displaypoints[i].func, func))
@@ -114,10 +127,9 @@ int display_info(void)
}
else
info = " (disabled)";
- dbg_printf("%d in %s%s: ",
- i + 1, func ? displaypoints[i].func->Name : "", info);
- expr_print(displaypoints[i].exp);
- dbg_printf("\n");
+ if (displaypoints[i].func)
+ dbg_printf(" in %s", displaypoints[i].func->Name);
+ dbg_printf("%s\n", info);
}
return TRUE;
}
@@ -129,7 +141,7 @@ static void print_one_display(int i)
if (displaypoints[i].enabled)
{
lvalue = expr_eval(displaypoints[i].exp);
- if (lvalue.typeid == dbg_itype_none)
+ if (lvalue.type.id == dbg_itype_none)
{
dbg_printf("Unable to evaluate expression ");
expr_print(displaypoints[i].exp);
@@ -146,7 +158,8 @@ static void print_one_display(int i)
dbg_printf("(disabled)\n");
else
if (displaypoints[i].format == 'i')
- memory_examine(&lvalue, displaypoints[i].count, displaypoints[i].format);
+ memory_examine((void*)types_extract_as_integer(&lvalue),
+ displaypoints[i].count, displaypoints[i].format);
else
print_value(&lvalue, displaypoints[i].format, 0);
}
@@ -158,6 +171,7 @@ int display_print(void)
SYMBOL_INFO* func;
func = (SYMBOL_INFO*)buffer;
+ memset(func, 0, sizeof(SYMBOL_INFO));
func->SizeOfStruct = sizeof(SYMBOL_INFO);
func->MaxNameLen = sizeof(buffer) - sizeof(*func);
if (!stack_get_frame(func, NULL)) return FALSE;
@@ -226,6 +240,7 @@ int display_enable(int displaynum, int enable)
SYMBOL_INFO* func;
func = (SYMBOL_INFO*)buffer;
+ memset(func, 0, sizeof(SYMBOL_INFO));
func->SizeOfStruct = sizeof(SYMBOL_INFO);
func->MaxNameLen = sizeof(buffer) - sizeof(*func);
if (!stack_get_frame(func, NULL)) return FALSE;
diff --git a/programs/winedbg/expr.c b/programs/winedbg/expr.c
index 2fcf73348f4..eda0e9be4dd 100644
--- a/programs/winedbg/expr.c
+++ b/programs/winedbg/expr.c
@@ -282,13 +282,13 @@ struct dbg_lvalue expr_eval(struct expr* exp)
struct dbg_lvalue exp2;
unsigned int cexp[5];
DWORD scale1, scale2, scale3;
- DWORD type1, type2;
- DWORD linear1, linear2;
+ struct dbg_type type1, type2;
DWORD tag;
const struct dbg_internal_var* div;
-
- rtn.typeid = dbg_itype_none;
+
rtn.cookie = 0;
+ rtn.type.id = dbg_itype_none;
+ rtn.type.module = 0;
rtn.addr.Mode = AddrModeFlat;
rtn.addr.Offset = 0;
rtn.addr.Segment = 0;
@@ -300,30 +300,31 @@ struct dbg_lvalue expr_eval(struct expr* exp)
* checking if this is right or not
*/
rtn = expr_eval(exp->un.cast.expr);
- linear1 = (DWORD)memory_to_linear_addr(&rtn.addr);
switch (exp->un.cast.cast_to.type)
{
case type_expr_type_id:
- if (exp->un.cast.cast_to.u.typeid == dbg_itype_none)
+ if (exp->un.cast.cast_to.u.type.id == dbg_itype_none)
{
dbg_printf("Can't cast to unknown type\n");
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
}
- rtn.typeid = exp->un.cast.cast_to.u.typeid;
+ rtn.type = exp->un.cast.cast_to.u.type;
break;
case type_expr_udt_class:
case type_expr_udt_struct:
case type_expr_udt_union:
- rtn.typeid = types_find_type(linear1, exp->un.cast.cast_to.u.name, SymTagUDT);
- if (rtn.typeid == dbg_itype_none)
+ rtn.type = types_find_type((DWORD)memory_to_linear_addr(&rtn.addr),
+ exp->un.cast.cast_to.u.name, SymTagUDT);
+ if (rtn.type.id == dbg_itype_none)
{
dbg_printf("Can't cast to UDT %s\n", exp->un.cast.cast_to.u.name);
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
}
break;
case type_expr_enumeration:
- rtn.typeid = types_find_type(linear1, exp->un.cast.cast_to.u.name, SymTagEnum);
- if (rtn.typeid == dbg_itype_none)
+ rtn.type = types_find_type((DWORD)memory_to_linear_addr(&rtn.addr),
+ exp->un.cast.cast_to.u.name, SymTagEnum);
+ if (rtn.type.id == dbg_itype_none)
{
dbg_printf("Can't cast to enumeration %s\n", exp->un.cast.cast_to.u.name);
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
@@ -335,8 +336,8 @@ struct dbg_lvalue expr_eval(struct expr* exp)
}
for (i = 0; i < exp->un.cast.cast_to.deref_count; i++)
{
- rtn.typeid = types_find_pointer(linear1, rtn.typeid);
- if (rtn.typeid == dbg_itype_none)
+ rtn.type = types_find_pointer(&rtn.type);
+ if (rtn.type.id == dbg_itype_none)
{
dbg_printf("Cannot find pointer type\n");
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
@@ -344,18 +345,21 @@ struct dbg_lvalue expr_eval(struct expr* exp)
}
break;
case EXPR_TYPE_STRING:
- rtn.typeid = dbg_itype_astring;
- rtn.cookie = DLV_HOST;
+ rtn.cookie = DLV_HOST;
+ rtn.type.id = dbg_itype_astring;
+ rtn.type.module = 0;
rtn.addr.Offset = (unsigned int)&exp->un.string.str;
break;
case EXPR_TYPE_U_CONST:
- rtn.typeid = dbg_itype_unsigned_int;
rtn.cookie = DLV_HOST;
+ rtn.type.id = dbg_itype_unsigned_int;
+ rtn.type.module = 0;
rtn.addr.Offset = (unsigned int)&exp->un.u_const.value;
break;
case EXPR_TYPE_S_CONST:
- rtn.typeid = dbg_itype_signed_int;
rtn.cookie = DLV_HOST;
+ rtn.type.id = dbg_itype_signed_int;
+ rtn.type.module = 0;
rtn.addr.Offset = (unsigned int)&exp->un.s_const.value;
break;
case EXPR_TYPE_SYMBOL:
@@ -373,8 +377,8 @@ struct dbg_lvalue expr_eval(struct expr* exp)
break;
case EXPR_TYPE_PSTRUCT:
exp1 = expr_eval(exp->un.structure.exp1);
- if (exp1.typeid == dbg_itype_none || !types_deref(&exp1, &rtn) ||
- rtn.typeid == dbg_itype_none)
+ if (exp1.type.id == dbg_itype_none || !types_deref(&exp1, &rtn) ||
+ rtn.type.id == dbg_itype_none)
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
if (!types_udt_find_element(&rtn, exp->un.structure.element_name,
&exp->un.structure.result))
@@ -385,7 +389,7 @@ struct dbg_lvalue expr_eval(struct expr* exp)
break;
case EXPR_TYPE_STRUCT:
exp1 = expr_eval(exp->un.structure.exp1);
- if (exp1.typeid == dbg_itype_none) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
+ if (exp1.type.id == dbg_itype_none) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
rtn = exp1;
if (!types_udt_find_element(&rtn, exp->un.structure.element_name,
&exp->un.structure.result))
@@ -402,7 +406,7 @@ struct dbg_lvalue expr_eval(struct expr* exp)
for (i = 0; i < exp->un.call.nargs; i++)
{
exp1 = expr_eval(exp->un.call.arg[i]);
- if (exp1.typeid == dbg_itype_none)
+ if (exp1.type.id == dbg_itype_none)
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
cexp[i] = types_extract_as_integer(&exp1);
}
@@ -458,93 +462,93 @@ struct dbg_lvalue expr_eval(struct expr* exp)
*/
exp->un.call.result = 0;
#endif
- linear1 = (DWORD)memory_to_linear_addr(&rtn.addr);
- /* get function signature type */
- types_get_info(linear1, rtn.typeid, TI_GET_TYPE, &rtn.typeid);
- /* and now, return type */
- types_get_info(linear1, rtn.typeid, TI_GET_TYPE, &rtn.typeid);
rtn.cookie = DLV_HOST;
- rtn.addr.Mode = AddrModeFlat;
+ /* get function signature type */
+ types_get_info(&rtn.type, TI_GET_TYPE, &rtn.type);
+ /* and now, return type */
+ types_get_info(&rtn.type, TI_GET_TYPE, &rtn.type);
rtn.addr.Offset = (unsigned int)&exp->un.call.result;
break;
case EXPR_TYPE_INTVAR:
+ rtn.cookie = DLV_HOST;
if (!(div = dbg_get_internal_var(exp->un.intvar.name)))
RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
- rtn.cookie = DLV_HOST;
- rtn.typeid = div->typeid;
+ rtn.type.id = div->typeid;
+ rtn.type.module = 0;
rtn.addr.Offset = (unsigned int)div->pval;
break;
case EXPR_TYPE_BINOP:
+ rtn.cookie = DLV_HOST;
exp1 = expr_eval(exp->un.binop.exp1);
exp2 = expr_eval(exp->un.binop.exp2);
- rtn.cookie = DLV_HOST;
- if (exp1.typeid == dbg_itype_none || exp2.typeid == dbg_itype_none)
+ if (exp1.type.id == dbg_itype_none || exp2.type.id == dbg_itype_none)
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
- linear1 = (DWORD)memory_to_linear_addr(&exp1.addr);
- linear2 = (DWORD)memory_to_linear_addr(&exp2.addr);
- rtn.typeid = dbg_itype_signed_int;
+ rtn.type.id = dbg_itype_signed_int;
+ rtn.type.module = 0;
rtn.addr.Offset = (unsigned int)&exp->un.binop.result;
switch (exp->un.binop.binop_type)
{
case EXP_OP_ADD:
- if (!types_get_info(linear1, exp1.typeid, TI_GET_SYMTAG, &tag) ||
+ if (!types_get_info(&exp1.type, TI_GET_SYMTAG, &tag) ||
tag != SymTagPointerType ||
- !types_get_info(linear1, exp1.typeid, TI_GET_TYPE, &type1))
- type1 = dbg_itype_none;
- if (!types_get_info(linear1, exp2.typeid, TI_GET_SYMTAG, &tag) ||
+ !types_get_info(&exp1.type, TI_GET_TYPE, &type1))
+ type1.id = dbg_itype_none;
+ if (!types_get_info(&exp2.type, TI_GET_SYMTAG, &tag) ||
tag != SymTagPointerType ||
- !types_get_info(linear1, exp2.typeid, TI_GET_TYPE, &type2))
- type2 = dbg_itype_none;
+ !types_get_info(&exp2.type, TI_GET_TYPE, &type2))
+ type2.id = dbg_itype_none;
scale1 = 1;
scale2 = 1;
- if (type1 != dbg_itype_none && type2 != dbg_itype_none)
+ if (type1.id != dbg_itype_none && type2.id != dbg_itype_none)
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
- if (type1 != dbg_itype_none)
+ if (type1.id != dbg_itype_none)
{
- types_get_info(linear1, type1, TI_GET_LENGTH, &scale2);
- rtn.typeid = exp1.typeid;
+ types_get_info(&type1, TI_GET_LENGTH, &scale2);
+ rtn.type = exp1.type;
}
- else if (type2 != dbg_itype_none)
+ else if (type2.id != dbg_itype_none)
{
- types_get_info(linear2, type2, TI_GET_LENGTH, &scale1);
- rtn.typeid = exp2.typeid;
+ types_get_info(&type2, TI_GET_LENGTH, &scale1);
+ rtn.type = exp2.type;
}
exp->un.binop.result = (types_extract_as_integer(&exp1) * scale1 +
scale2 * types_extract_as_integer(&exp2));
break;
case EXP_OP_SUB:
- if (!types_get_info(linear1, exp1.typeid, TI_GET_SYMTAG, &tag) ||
+ if (!types_get_info(&exp1.type, TI_GET_SYMTAG, &tag) ||
tag != SymTagPointerType ||
- !types_get_info(linear1, exp1.typeid, TI_GET_TYPE, &type1))
- type1 = dbg_itype_none;
- if (!types_get_info(linear2, exp2.typeid, TI_GET_SYMTAG, &tag) ||
+ !types_get_info(&exp1.type, TI_GET_TYPE, &type1))
+ type1.id = dbg_itype_none;
+ if (!types_get_info(&exp2.type, TI_GET_SYMTAG, &tag) ||
tag != SymTagPointerType ||
- !types_get_info(linear2, exp2.typeid, TI_GET_TYPE, &type2))
- type2 = dbg_itype_none;
+ !types_get_info(&exp2.type, TI_GET_TYPE, &type2))
+ type2.id = dbg_itype_none;
scale1 = 1;
scale2 = 1;
scale3 = 1;
- if (type1 != dbg_itype_none && type2 != dbg_itype_none)
+ if (type1.id != dbg_itype_none && type2.id != dbg_itype_none)
{
- if (type1 != type2) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
- types_get_info(linear1, type1, TI_GET_LENGTH, &scale3);
+ WINE_FIXME("This may fail (if module base address are wrongly calculated)\n");
+ if (memcmp(&type1, &type2, sizeof(struct dbg_type)))
+ RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
+ types_get_info(&type1, TI_GET_LENGTH, &scale3);
}
- else if (type1 != dbg_itype_none)
+ else if (type1.id != dbg_itype_none)
{
- types_get_info(linear1, type1, TI_GET_LENGTH, &scale2);
- rtn.typeid = exp1.typeid;
+ types_get_info(&type1, TI_GET_LENGTH, &scale2);
+ rtn.type = exp1.type;
}
- else if (type2 != dbg_itype_none)
+ else if (type2.id != dbg_itype_none)
{
- types_get_info(linear2, type2, TI_GET_LENGTH, &scale1);
- rtn.typeid = exp2.typeid;
+ types_get_info(&type2, TI_GET_LENGTH, &scale1);
+ rtn.type = exp2.type;
}
exp->un.binop.result = (types_extract_as_integer(&exp1) * scale1 -
types_extract_as_integer(&exp2) * scale2) / scale3;
break;
case EXP_OP_SEG:
- rtn.cookie = DLV_TARGET;
- rtn.typeid = dbg_itype_none;
+ rtn.type.id = dbg_itype_none;
+ rtn.type.module = 0;
rtn.addr.Mode = AddrMode1632;
rtn.addr.Segment = types_extract_as_integer(&exp1);
rtn.addr.Offset = types_extract_as_integer(&exp2);
@@ -607,11 +611,12 @@ struct dbg_lvalue expr_eval(struct expr* exp)
}
break;
case EXPR_TYPE_UNOP:
- exp1 = expr_eval(exp->un.unop.exp1);
- if (exp1.typeid == dbg_itype_none) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
rtn.cookie = DLV_HOST;
+ exp1 = expr_eval(exp->un.unop.exp1);
+ if (exp1.type.id == dbg_itype_none) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
rtn.addr.Offset = (unsigned int)&exp->un.unop.result;
- rtn.typeid = dbg_itype_signed_int;
+ rtn.type.id = dbg_itype_signed_int;
+ rtn.type.module = 0;
switch (exp->un.unop.unop_type)
{
case EXP_OP_NEG:
@@ -624,19 +629,6 @@ struct dbg_lvalue expr_eval(struct expr* exp)
exp->un.unop.result = ~types_extract_as_integer(&exp1);
break;
case EXP_OP_DEREF:
- /* FIXME: this is currently buggy.
- * there is no way to tell were the deref:ed value is...
- * for example:
- * x is a pointer to struct s, x being on the stack
- * => exp1 is target, result is target
- * x is a pointer to struct s, x being optimized into a reg
- * => exp1 is host, result is target
- * x is a pointer to internal variable x
- * => exp1 is host, result is host
- * so we force DLV_TARGET, because dereferencing pointers to
- * internal variables is very unlikely. a correct fix would be
- * rather large.
- */
if (!types_deref(&exp1, &rtn))
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
break;
@@ -650,7 +642,7 @@ struct dbg_lvalue expr_eval(struct expr* exp)
if (exp1.addr.Mode != AddrModeFlat)
RaiseException(DEBUG_STATUS_CANT_DEREF, 0, 0, NULL);
exp->un.unop.result = (unsigned int)memory_to_linear_addr(&exp1.addr);
- rtn.typeid = types_find_pointer(exp->un.unop.result, exp1.typeid);
+ rtn.type = types_find_pointer(&exp1.type);
break;
default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
}
@@ -661,14 +653,13 @@ struct dbg_lvalue expr_eval(struct expr* exp)
break;
}
- assert(rtn.cookie == DLV_TARGET || rtn.cookie == DLV_HOST);
-
return rtn;
}
int expr_print(const struct expr* exp)
{
- int i;
+ int i;
+ struct dbg_type type;
switch (exp->type)
{
@@ -678,7 +669,9 @@ int expr_print(const struct expr* exp)
switch (exp->un.cast.cast_to.type)
{
case type_expr_type_id:
- types_print_type(0, exp->un.cast.cast_to.type, FALSE); break;
+ type.module = 0;
+ type.id = exp->un.cast.cast_to.type;
+ types_print_type(&type, FALSE); break;
case type_expr_udt_class:
dbg_printf("class %s", exp->un.cast.cast_to.u.name); break;
case type_expr_udt_struct:
diff --git a/programs/winedbg/gdbproxy.c b/programs/winedbg/gdbproxy.c
index 0665778ad72..f39861da4ab 100644
--- a/programs/winedbg/gdbproxy.c
+++ b/programs/winedbg/gdbproxy.c
@@ -468,7 +468,7 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
case OUTPUT_DEBUG_STRING_EVENT:
assert(dbg_curr_thread);
memory_get_string(gdbctx->process->handle,
- de->u.DebugString.lpDebugStringData, DLV_TARGET,
+ de->u.DebugString.lpDebugStringData, TRUE,
de->u.DebugString.fUnicode, buffer, sizeof(buffer));
if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
fprintf(stderr, "%08lx:%08lx: output debug string (%s)\n",
diff --git a/programs/winedbg/memory.c b/programs/winedbg/memory.c
index 9976d3d90c3..8d1d16c0c6e 100644
--- a/programs/winedbg/memory.c
+++ b/programs/winedbg/memory.c
@@ -99,7 +99,6 @@ BOOL memory_read_value(const struct dbg_lvalue* lvalue, DWORD size, void* result
}
else
{
- assert(lvalue->addr.Mode == AddrModeFlat);
if (!lvalue->addr.Offset) return FALSE;
memcpy(result, (void*)lvalue->addr.Offset, size);
}
@@ -118,7 +117,7 @@ BOOL memory_write_value(const struct dbg_lvalue* lvalue, DWORD size, void* value
DWORD linear = (DWORD)memory_to_linear_addr(&lvalue->addr);
os = ~size;
- types_get_info(linear, lvalue->typeid, TI_GET_LENGTH, &os);
+ types_get_info(&lvalue->type, TI_GET_LENGTH, &os);
assert(size == os);
/* FIXME: only works on little endian systems */
@@ -128,7 +127,6 @@ BOOL memory_write_value(const struct dbg_lvalue* lvalue, DWORD size, void* value
}
else
{
- assert(lvalue->addr.Mode == AddrModeFlat);
memcpy((void*)lvalue->addr.Offset, value, size);
}
return ret;
@@ -139,17 +137,18 @@ BOOL memory_write_value(const struct dbg_lvalue* lvalue, DWORD size, void* value
*
* Implementation of the 'x' command.
*/
-void memory_examine(const struct dbg_lvalue* lvalue, int count, char format)
+void memory_examine(void* linear, int count, char format)
{
int i;
- ADDRESS x;
char buffer[256];
+ ADDRESS addr;
+
+ addr.Mode = AddrModeFlat;
+ addr.Offset = (unsigned long)linear;
- x.Mode = AddrModeFlat;
- x.Offset = types_extract_as_integer(lvalue);
if (format != 'i' && count > 1)
{
- print_address(&x, FALSE);
+ print_address(&addr, FALSE);
dbg_printf(": ");
}
@@ -157,32 +156,33 @@ void memory_examine(const struct dbg_lvalue* lvalue, int count, char format)
{
case 'u':
if (count == 1) count = 256;
- memory_get_string(dbg_curr_thread->handle, (void*)x.Offset, lvalue->cookie,
- TRUE, buffer, min(count, sizeof(buffer)));
+ memory_get_string(dbg_curr_process->handle, linear,
+ TRUE, TRUE, buffer, min(count, sizeof(buffer)));
dbg_printf("%s\n", buffer);
return;
case 's':
if (count == 1) count = 256;
- memory_get_string(dbg_curr_thread->handle, (void*)x.Offset, lvalue->cookie,
- FALSE, buffer, min(count, sizeof(buffer)));
+ memory_get_string(dbg_curr_process->handle, linear,
+ TRUE, FALSE, buffer, min(count, sizeof(buffer)));
dbg_printf("%s\n", buffer);
return;
case 'i':
- while (count-- && memory_disasm_one_insn(&x));
+ while (count-- && memory_disasm_one_insn(&addr));
return;
case 'g':
while (count--)
{
GUID guid;
- if (!dbg_read_memory_verbose((void*)x.Offset, &guid, sizeof(guid))) break;
+ if (!dbg_read_memory_verbose(linear, &guid, sizeof(guid))) break;
dbg_printf("{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
guid.Data1, guid.Data2, guid.Data3,
guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
- x.Offset += sizeof(guid);
+ linear = (char*)linear + sizeof(guid);
+ addr.Offset += sizeof(guid);
if (count)
{
- print_address(&x, FALSE);
+ print_address(&addr, FALSE);
dbg_printf(": ");
}
}
@@ -191,13 +191,15 @@ void memory_examine(const struct dbg_lvalue* lvalue, int count, char format)
#define DO_DUMP2(_t,_l,_f,_vv) { \
_t _v; \
for (i = 0; i < count; i++) { \
- if (!dbg_read_memory_verbose((void*)x.Offset, &_v, \
+ if (!dbg_read_memory_verbose(linear, &_v, \
sizeof(_t))) break; \
dbg_printf(_f, (_vv)); \
- x.Offset += sizeof(_t); \
- if ((i % (_l)) == (_l) - 1) { \
+ addr.Offset += sizeof(_t); \
+ linear = (char*)linear + sizeof(_t); \
+ if ((i % (_l)) == (_l) - 1 && i != count - 1) \
+ { \
dbg_printf("\n"); \
- print_address(&x, FALSE); \
+ print_address(&addr, FALSE); \
dbg_printf(": "); \
} \
} \
@@ -214,7 +216,7 @@ void memory_examine(const struct dbg_lvalue* lvalue, int count, char format)
}
}
-BOOL memory_get_string(HANDLE hp, void* addr, unsigned cookie, BOOL unicode,
+BOOL memory_get_string(HANDLE hp, void* addr, BOOL in_debuggee, BOOL unicode,
char* buffer, int size)
{
DWORD sz;
@@ -222,9 +224,8 @@ BOOL memory_get_string(HANDLE hp, void* addr, unsigned cookie, BOOL unicode,
buffer[0] = 0;
if (!addr) return FALSE;
- switch (cookie)
+ if (in_debuggee)
{
- case DLV_TARGET:
if (!unicode) return ReadProcessMemory(hp, addr, buffer, size, &sz);
buffW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
@@ -232,13 +233,13 @@ BOOL memory_get_string(HANDLE hp, void* addr, unsigned cookie, BOOL unicode,
WideCharToMultiByte(CP_ACP, 0, buffW, sz / sizeof(WCHAR), buffer, size,
NULL, NULL);
HeapFree(GetProcessHeap(), 0, buffW);
- return TRUE;
- case DLV_HOST:
+ }
+ else
+ {
strncpy(buffer, addr, size);
buffer[size - 1] = 0;
- return TRUE;
}
- return FALSE;
+ return TRUE;
}
BOOL memory_get_string_indirect(HANDLE hp, void* addr, BOOL unicode, char* buffer, int size)
@@ -250,7 +251,7 @@ BOOL memory_get_string_indirect(HANDLE hp, void* addr, BOOL unicode, char* buffe
if (addr &&
ReadProcessMemory(hp, addr, &ad, sizeof(ad), &sz) && sz == sizeof(ad) && ad)
{
- return memory_get_string(hp, ad, DLV_TARGET, unicode, buffer, size);
+ return memory_get_string(hp, ad, TRUE, unicode, buffer, size);
}
return FALSE;
}
@@ -260,20 +261,19 @@ static void print_typed_basic(const struct dbg_lvalue* lvalue)
long long int val_int;
void* val_ptr;
long double val_real;
- DWORD tag, size, count, bt, rtype;
+ DWORD tag, size, count, bt;
+ struct dbg_type rtype;
DWORD linear = (DWORD)memory_to_linear_addr(&lvalue->addr);
- assert(lvalue->cookie == DLV_TARGET || lvalue->cookie == DLV_HOST);
-
- if (lvalue->typeid == dbg_itype_none ||
- !types_get_info(linear, lvalue->typeid, TI_GET_SYMTAG, &tag))
+ if (lvalue->type.id == dbg_itype_none ||
+ !types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
return;
switch (tag)
{
case SymTagBaseType:
- if (!types_get_info(linear, lvalue->typeid, TI_GET_LENGTH, &size) ||
- !types_get_info(linear, lvalue->typeid, TI_GET_BASETYPE, &bt))
+ if (!types_get_info(&lvalue->type, TI_GET_LENGTH, &size) ||
+ !types_get_info(&lvalue->type, TI_GET_BASETYPE, &bt))
{
WINE_ERR("Couldn't get information\n");
RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
@@ -309,20 +309,21 @@ static void print_typed_basic(const struct dbg_lvalue* lvalue)
case SymTagPointerType:
if (!memory_read_value(lvalue, sizeof(void*), &val_ptr)) return;
- if (!types_get_info(linear, lvalue->typeid, TI_GET_TYPE, &rtype) ||
- rtype == dbg_itype_none)
+ if (!types_get_info(&lvalue->type, TI_GET_TYPE, &rtype.id) ||
+ rtype.id == dbg_itype_none)
{
dbg_printf("Internal symbol error: unable to access memory location %p", val_ptr);
break;
}
-
- if (types_get_info(linear, rtype, TI_GET_SYMTAG, &tag) && tag == SymTagBaseType &&
- types_get_info(linear, rtype, TI_GET_BASETYPE, &bt) && bt == btChar &&
- types_get_info(linear, rtype, TI_GET_LENGTH, &size))
+ rtype.module = lvalue->type.module;
+ if (types_get_info(&rtype, TI_GET_SYMTAG, &tag) && tag == SymTagBaseType &&
+ types_get_info(&rtype, TI_GET_BASETYPE, &bt) && bt == btChar &&
+ types_get_info(&rtype, TI_GET_LENGTH, &size))
{
char buffer[1024];
- memory_get_string(dbg_curr_thread->handle, (void*)val_ptr, lvalue->cookie,
+ memory_get_string(dbg_curr_process->handle, val_ptr,
+ lvalue->cookie == DLV_TARGET,
size == 2, buffer, sizeof(buffer));
dbg_printf("\"%s\"", buffer);
}
@@ -345,24 +346,27 @@ static void print_typed_basic(const struct dbg_lvalue* lvalue)
*/
if (!be_cpu->fetch_integer(lvalue, 4, TRUE, &val_int)) return;
- if (types_get_info(linear, lvalue->typeid, TI_GET_CHILDRENCOUNT, &count))
+ if (types_get_info(&lvalue->type, TI_GET_CHILDRENCOUNT, &count))
{
- char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
- TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
- WCHAR* ptr;
- char tmp[256];
- VARIANT variant;
- int i;
+ char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
+ TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
+ WCHAR* ptr;
+ char tmp[256];
+ VARIANT variant;
+ int i;
+ struct dbg_type type;
fcp->Start = 0;
while (count)
{
fcp->Count = min(count, 256);
- if (types_get_info(linear, lvalue->typeid, TI_FINDCHILDREN, fcp))
+ if (types_get_info(&lvalue->type, TI_FINDCHILDREN, fcp))
{
+ type.module = linear;
for (i = 0; i < min(fcp->Count, count); i++)
{
- if (!types_get_info(linear, fcp->ChildId[i], TI_GET_VALUE, &variant))
+ type.id = fcp->ChildId[i];
+ if (!types_get_info(&type, TI_GET_VALUE, &variant))
continue;
switch (variant.n1.n2.vt)
{
@@ -372,7 +376,7 @@ static void print_typed_basic(const struct dbg_lvalue* lvalue)
if (ok)
{
ptr = NULL;
- types_get_info(linear, fcp->ChildId[i], TI_GET_SYMNAME, &ptr);
+ types_get_info(&type, TI_GET_SYMNAME, &ptr);
if (!ptr) continue;
WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
HeapFree(GetProcessHeap(), 0, ptr);
@@ -404,8 +408,7 @@ void print_basic(const struct dbg_lvalue* lvalue, int count, char format)
{
long int res;
- assert(lvalue->cookie == DLV_TARGET || lvalue->cookie == DLV_HOST);
- if (lvalue->typeid == dbg_itype_none)
+ if (lvalue->type.id == dbg_itype_none)
{
dbg_printf("Unable to evaluate expression\n");
return;
@@ -465,6 +468,9 @@ void print_bare_address(const ADDRESS* addr)
case AddrMode1632:
dbg_printf("0x%04x:0x%08lx", addr->Segment, addr->Offset);
break;
+ default:
+ dbg_printf("Unknown mode %x\n", addr->Mode);
+ break;
}
}
@@ -499,7 +505,7 @@ void print_address(const ADDRESS* addr, BOOLEAN with_line)
}
}
-struct foo
+struct sym_enum
{
char* tmp;
DWORD frame;
@@ -507,19 +513,23 @@ struct foo
static BOOL WINAPI sym_enum_cb(SYMBOL_INFO* sym_info, ULONG size, void* user)
{
- struct foo* foo = (struct foo*)user;
- DWORD addr;
- unsigned val;
- long offset;
+ struct sym_enum* se = (struct sym_enum*)user;
+ DWORD addr;
+ unsigned val;
+ long offset;
if ((sym_info->Flags & (SYMFLAG_PARAMETER|SYMFLAG_FRAMEREL)) == (SYMFLAG_PARAMETER|SYMFLAG_FRAMEREL))
{
- if (foo->tmp[0]) strcat(foo->tmp, ", ");
- addr = foo->frame;
- types_get_info(sym_info->ModBase, sym_info->TypeIndex, TI_GET_OFFSET, &offset);
+ struct dbg_type type;
+
+ if (se->tmp[0]) strcat(se->tmp, ", ");
+ addr = se->frame;
+ type.module = sym_info->ModBase;
+ type.id = sym_info->TypeIndex;
+ types_get_info(&type, TI_GET_OFFSET, &offset);
addr += offset;
dbg_read_memory_verbose((char*)addr, &val, sizeof(val));
- sprintf(foo->tmp + strlen(foo->tmp), "%s=0x%x", sym_info->Name, val);
+ sprintf(se->tmp + strlen(se->tmp), "%s=0x%x", sym_info->Name, val);
}
return TRUE;
}
@@ -531,7 +541,7 @@ void print_addr_and_args(const ADDRESS* pc, const ADDRESS* frame)
IMAGEHLP_STACK_FRAME isf;
IMAGEHLP_LINE il;
IMAGEHLP_MODULE im;
- struct foo foo;
+ struct sym_enum se;
char tmp[1024];
DWORD disp;
@@ -552,10 +562,10 @@ void print_addr_and_args(const ADDRESS* pc, const ADDRESS* frame)
if (disp) dbg_printf("+0x%lx", disp);
SymSetContext(dbg_curr_process->handle, &isf, NULL);
- foo.tmp = tmp;
- foo.frame = isf.FrameOffset;
+ se.tmp = tmp;
+ se.frame = isf.FrameOffset;
tmp[0] = '\0';
- SymEnumSymbols(dbg_curr_process->handle, 0, NULL, sym_enum_cb, &foo);
+ SymEnumSymbols(dbg_curr_process->handle, 0, NULL, sym_enum_cb, &se);
if (tmp[0]) dbg_printf("(%s)", tmp);
il.SizeOfStruct = sizeof(il);
diff --git a/programs/winedbg/stack.c b/programs/winedbg/stack.c
index d1181bbee9f..8a739f5e69e 100644
--- a/programs/winedbg/stack.c
+++ b/programs/winedbg/stack.c
@@ -42,27 +42,24 @@ static IMAGEHLP_STACK_FRAME* frames = NULL;
*/
void stack_info(void)
{
- struct dbg_lvalue lvalue;
+ ADDRESS addr;
- lvalue.typeid = dbg_itype_none;
- lvalue.cookie = DLV_TARGET;
/* FIXME: we assume stack grows the same way as on i386 */
- if (!memory_get_current_stack(&lvalue.addr))
- dbg_printf("Bad segment (%d)\n", lvalue.addr.Segment);
+ if (!memory_get_current_stack(&addr))
+ dbg_printf("Bad segment (%d)\n", addr.Segment);
dbg_printf("Stack dump:\n");
- switch (lvalue.addr.Mode)
+ switch (addr.Mode)
{
case AddrModeFlat: /* 32-bit mode */
case AddrMode1632: /* 32-bit mode */
- memory_examine(&lvalue, 24, 'x');
+ memory_examine(memory_to_linear_addr(&addr), 24, 'x');
break;
case AddrModeReal: /* 16-bit mode */
case AddrMode1616:
- memory_examine(&lvalue, 24, 'w');
+ memory_examine(memory_to_linear_addr(&addr), 24, 'w');
break;
}
- dbg_printf("\n");
}
int stack_set_frame(int newframe)
diff --git a/programs/winedbg/symbol.c b/programs/winedbg/symbol.c
index 6addcb86526..b3de9cef09d 100644
--- a/programs/winedbg/symbol.c
+++ b/programs/winedbg/symbol.c
@@ -38,19 +38,24 @@ static BOOL symbol_get_debug_start(DWORD mod_base, DWORD typeid, DWORD* start)
char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
int i;
+ struct dbg_type type;
- if (!types_get_info(mod_base, typeid, TI_GET_CHILDRENCOUNT, &count)) return FALSE;
+ type.module = mod_base;
+ type.id = typeid;
+
+ if (!types_get_info(&type, TI_GET_CHILDRENCOUNT, &count)) return FALSE;
fcp->Start = 0;
while (count)
{
fcp->Count = min(count, 256);
- if (types_get_info(mod_base, typeid, TI_FINDCHILDREN, fcp))
+ if (types_get_info(&type, TI_FINDCHILDREN, fcp))
{
for (i = 0; i < min(fcp->Count, count); i++)
{
- types_get_info(mod_base, fcp->ChildId[i], TI_GET_SYMTAG, &tag);
+ type.id = fcp->ChildId[i];
+ types_get_info(&type, TI_GET_SYMTAG, &tag);
if (tag != SymTagFuncDebugStart) continue;
- return types_get_info(mod_base, fcp->ChildId[i], TI_GET_ADDRESS, start);
+ return types_get_info(&type, TI_GET_ADDRESS, start);
}
count -= min(count, 256);
fcp->Start += 256;
@@ -107,7 +112,11 @@ static BOOL CALLBACK sgv_cb(SYMBOL_INFO* sym, ULONG size, void* ctx)
else if (sym->Flags & SYMFLAG_FRAMEREL)
{
ULONG offset;
- types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_OFFSET, &offset);
+ struct dbg_type type;
+
+ type.module = sym->ModBase;
+ type.id = sym->TypeIndex;
+ types_get_info(&type, TI_GET_OFFSET, &offset);
addr = sgv->ihsf.FrameOffset + offset;
}
else if (sym->Flags & SYMFLAG_THUNK)
@@ -175,11 +184,13 @@ static BOOL CALLBACK sgv_cb(SYMBOL_INFO* sym, ULONG size, void* ctx)
memmove(&sgv->syms[insp + 1], &sgv->syms[insp],
sizeof(sgv->syms[0]) * sgv->num_thunks);
}
+ sgv->syms[insp].lvalue.cookie = cookie;
sgv->syms[insp].lvalue.addr.Mode = AddrModeFlat;
sgv->syms[insp].lvalue.addr.Offset = addr;
- types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_TYPE,
- &sgv->syms[insp].lvalue.typeid);
- sgv->syms[insp].lvalue.cookie = cookie;
+ sgv->syms[insp].lvalue.type.module = sym->ModBase;
+ sgv->syms[insp].lvalue.type.id = sym->TypeIndex;
+ types_get_info(&sgv->syms[insp].lvalue.type, TI_GET_TYPE,
+ &sgv->syms[insp].lvalue.type.id);
sgv->syms[insp].flags = sym->Flags;
sgv->num++;
@@ -314,8 +325,9 @@ enum sym_get_lval symbol_get_lvalue(const char* name, const int lineno,
}
else
{
- dbg_printf("More than one symbol named %s, picking the first one\n", name);
- i = 0;
+ /* FIXME: could display the list of non-picked up symbols */
+ if (sgv.num > 1)
+ dbg_printf("More than one symbol named %s, picking the first one\n", name);
}
*rtn = sgv.syms[i].lvalue;
return sglv_found;
@@ -390,6 +402,7 @@ enum dbg_line_status symbol_get_function_line_status(const ADDRESS* addr)
DWORD lin = (DWORD)memory_to_linear_addr(addr);
char buffer[sizeof(SYMBOL_INFO) + 256];
SYMBOL_INFO* sym = (SYMBOL_INFO*)buffer;
+ struct dbg_type type;
il.SizeOfStruct = sizeof(il);
sym->SizeOfStruct = sizeof(SYMBOL_INFO);
@@ -419,7 +432,9 @@ enum dbg_line_status symbol_get_function_line_status(const ADDRESS* addr)
if (symbol_get_debug_start(sym->ModBase, sym->TypeIndex, &start) && lin < start)
return dbg_not_on_a_line_number;
- if (!types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_LENGTH, &size) || size == 0)
+ type.module = sym->ModBase;
+ type.id = sym->TypeIndex;
+ if (!types_get_info(&type, TI_GET_LENGTH, &size) || size == 0)
size = 0x100000;
if (il.FileName && il.FileName[0] && disp < size)
return (disp == 0) ? dbg_on_a_line_number : dbg_not_on_a_line_number;
@@ -492,14 +507,16 @@ BOOL symbol_get_line(const char* filename, const char* name, IMAGEHLP_LINE* line
static BOOL CALLBACK info_locals_cb(SYMBOL_INFO* sym, ULONG size, void* ctx)
{
- DWORD tid;
- ULONG v, val;
- const char* explain = NULL;
- char buf[128];
+ ULONG v, val;
+ const char* explain = NULL;
+ char buf[128];
+ struct dbg_type type;
dbg_printf("\t");
- types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_TYPE, &tid);
- types_print_type(sym->ModBase, tid, FALSE);
+ type.module = sym->ModBase;
+ type.id = sym->TypeIndex;
+ types_get_info(&type, TI_GET_TYPE, &type.id);
+ types_print_type(&type, FALSE);
if (sym->Flags & SYMFLAG_LOCAL) explain = "local";
else if (sym->Flags & SYMFLAG_PARAMETER) explain = "parameter";
@@ -527,7 +544,8 @@ static BOOL CALLBACK info_locals_cb(SYMBOL_INFO* sym, ULONG size, void* ctx)
}
else if (sym->Flags & SYMFLAG_FRAMEREL)
{
- types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_OFFSET, &v);
+ type.id = sym->TypeIndex;
+ types_get_info(&type, TI_GET_OFFSET, &v);
v += ((IMAGEHLP_STACK_FRAME*)ctx)->FrameOffset;
dbg_read_memory_verbose((void*)v, &val, sizeof(val));
@@ -556,13 +574,13 @@ int symbol_info_locals(void)
static BOOL CALLBACK symbols_info_cb(SYMBOL_INFO* sym, ULONG size, void* ctx)
{
- DWORD type;
+ struct dbg_type type;
dbg_printf("%08lx: %s (", sym->Address, sym->Name);
if (sym->TypeIndex != dbg_itype_none && sym->TypeIndex != 0 &&
- types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_TYPE, &type))
+ types_get_info(&type, TI_GET_TYPE, &type.id))
{
- types_print_type(sym->ModBase, type, FALSE);
+ types_print_type(&type, FALSE);
}
dbg_printf(")\n");
return TRUE;
diff --git a/programs/winedbg/types.c b/programs/winedbg/types.c
index 0b3e6300d8b..06c88ed57bd 100644
--- a/programs/winedbg/types.c
+++ b/programs/winedbg/types.c
@@ -39,19 +39,16 @@ long int types_extract_as_integer(const struct dbg_lvalue* lvalue)
{
long int rtn = 0;
DWORD tag, size, bt;
- DWORD linear = (DWORD)memory_to_linear_addr(&lvalue->addr);
- assert(lvalue->cookie == DLV_TARGET || lvalue->cookie == DLV_HOST);
-
- if (lvalue->typeid == dbg_itype_none ||
- !types_get_info(linear, lvalue->typeid, TI_GET_SYMTAG, &tag))
+ if (lvalue->type.id == dbg_itype_none ||
+ !types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
return 0;
switch (tag)
{
case SymTagBaseType:
- if (!types_get_info(linear, lvalue->typeid, TI_GET_LENGTH, &size) ||
- !types_get_info(linear, lvalue->typeid, TI_GET_BASETYPE, &bt))
+ if (!types_get_info(&lvalue->type, TI_GET_LENGTH, &size) ||
+ !types_get_info(&lvalue->type, TI_GET_BASETYPE, &bt))
{
WINE_ERR("Couldn't get information\n");
RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
@@ -107,23 +104,34 @@ long int types_extract_as_integer(const struct dbg_lvalue* lvalue)
BOOL types_deref(const struct dbg_lvalue* lvalue, struct dbg_lvalue* result)
{
DWORD tag;
- DWORD linear = (DWORD)memory_to_linear_addr(&lvalue->addr);
-
- assert(lvalue->cookie == DLV_TARGET || lvalue->cookie == DLV_HOST);
memset(result, 0, sizeof(*result));
- result->typeid = dbg_itype_none;
+ result->type.id = dbg_itype_none;
+ result->type.module = 0;
/*
* Make sure that this really makes sense.
*/
- if (!types_get_info(linear, lvalue->typeid, TI_GET_SYMTAG, &tag) ||
+ if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag) ||
tag != SymTagPointerType ||
memory_read_value(lvalue, sizeof(result->addr.Offset), &result->addr.Offset) ||
- !types_get_info(linear, lvalue->typeid, TI_GET_TYPE, &result->typeid))
+ !types_get_info(&lvalue->type, TI_GET_TYPE, &result->type.id))
return FALSE;
-
- result->cookie = DLV_TARGET; /* see comment on DEREF below */
+ result->type.module = lvalue->type.module;
+ result->cookie = DLV_TARGET;
+ /* FIXME: this is currently buggy.
+ * there is no way to tell were the deref:ed value is...
+ * for example:
+ * x is a pointer to struct s, x being on the stack
+ * => lvalue is in debuggee, result is in debugger
+ * x is a pointer to struct s, x being optimized into a reg
+ * => lvalue is debugger, result is debuggee
+ * x is a pointer to internal variable x
+ * => lvalue is debugger, result is debuggee
+ * so we force debuggee address space, because dereferencing pointers to
+ * internal variables is very unlikely. A correct fix would be
+ * rather large.
+ */
result->addr.Mode = AddrModeFlat;
return TRUE;
}
@@ -133,19 +141,20 @@ BOOL types_deref(const struct dbg_lvalue* lvalue, struct dbg_lvalue* result)
*
* Implement a structure derefencement
*/
-static BOOL types_get_udt_element_lvalue(struct dbg_lvalue* lvalue, DWORD linear,
- DWORD typeid, long int* tmpbuf)
+static BOOL types_get_udt_element_lvalue(struct dbg_lvalue* lvalue,
+ const struct dbg_type* type, long int* tmpbuf)
{
DWORD offset, length, bitoffset;
DWORD bt;
unsigned mask;
- types_get_info(linear, typeid, TI_GET_TYPE, &lvalue->typeid);
- types_get_info(linear, typeid, TI_GET_OFFSET, &offset);
+ types_get_info(type, TI_GET_TYPE, &lvalue->type.id);
+ lvalue->type.module = type->module;
+ types_get_info(type, TI_GET_OFFSET, &offset);
- if (types_get_info(linear, typeid, TI_GET_BITPOSITION, &bitoffset))
+ if (types_get_info(type, TI_GET_BITPOSITION, &bitoffset))
{
- types_get_info(linear, typeid, TI_GET_LENGTH, &length);
+ types_get_info(type, TI_GET_LENGTH, &length);
if (length > sizeof(*tmpbuf)) return FALSE;
/*
* Bitfield operation. We have to extract the field and store
@@ -157,8 +166,7 @@ static BOOL types_get_udt_element_lvalue(struct dbg_lvalue* lvalue, DWORD linear
*tmpbuf >>= bitoffset & 7;
*tmpbuf &= ~mask;
- lvalue->cookie = DLV_HOST;
- lvalue->addr.Mode = AddrModeFlat;
+ lvalue->cookie = DLV_HOST;
lvalue->addr.Offset = (DWORD)tmpbuf;
/*
@@ -166,14 +174,14 @@ static BOOL types_get_udt_element_lvalue(struct dbg_lvalue* lvalue, DWORD linear
* Check to see whether the basic type is signed or not, and if so,
* we need to sign extend the number.
*/
- if (types_get_info(linear, lvalue->typeid, TI_GET_BASETYPE, &bt) &&
+ if (types_get_info(&lvalue->type, TI_GET_BASETYPE, &bt) &&
bt == btInt && (*tmpbuf & (1 << (length - 1))))
{
*tmpbuf |= mask;
}
return TRUE;
}
- if (types_get_info(linear, typeid, TI_GET_OFFSET, &offset))
+ if (types_get_info(type, TI_GET_OFFSET, &offset))
{
lvalue->addr.Offset += offset;
return TRUE;
@@ -187,39 +195,38 @@ static BOOL types_get_udt_element_lvalue(struct dbg_lvalue* lvalue, DWORD linear
*/
BOOL types_udt_find_element(struct dbg_lvalue* lvalue, const char* name, long int* tmpbuf)
{
- DWORD linear = (DWORD)memory_to_linear_addr(&lvalue->addr);
DWORD tag, count;
char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
WCHAR* ptr;
char tmp[256];
int i;
+ struct dbg_type type;
- assert(lvalue->cookie == DLV_TARGET || lvalue->cookie == DLV_HOST);
-
- if (!types_get_info(linear, lvalue->typeid, TI_GET_SYMTAG, &tag) ||
+ if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag) ||
tag != SymTagUDT)
return FALSE;
- if (types_get_info(linear, lvalue->typeid, TI_GET_CHILDRENCOUNT, &count))
+ if (types_get_info(&lvalue->type, TI_GET_CHILDRENCOUNT, &count))
{
fcp->Start = 0;
while (count)
{
fcp->Count = min(count, 256);
- if (types_get_info(linear, lvalue->typeid, TI_FINDCHILDREN, fcp))
+ if (types_get_info(&lvalue->type, TI_FINDCHILDREN, fcp))
{
+ type.module = lvalue->type.module;
for (i = 0; i < min(fcp->Count, count); i++)
{
ptr = NULL;
- types_get_info(linear, fcp->ChildId[i], TI_GET_SYMNAME, &ptr);
+ type.id = fcp->ChildId[i];
+ types_get_info(&type, TI_GET_SYMNAME, &ptr);
if (!ptr) continue;
WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
HeapFree(GetProcessHeap(), 0, ptr);
if (strcmp(tmp, name)) continue;
- return types_get_udt_element_lvalue(lvalue, linear,
- fcp->ChildId[i], tmpbuf);
+ return types_get_udt_element_lvalue(lvalue, &type, tmpbuf);
}
}
count -= min(count, 256);
@@ -238,26 +245,23 @@ BOOL types_array_index(const struct dbg_lvalue* lvalue, int index,
struct dbg_lvalue* result)
{
DWORD tag, length, count;
- DWORD linear = (DWORD)memory_to_linear_addr(&lvalue->addr);
- assert(lvalue->cookie == DLV_TARGET || lvalue->cookie == DLV_HOST);
-
- if (!types_get_info(0, lvalue->typeid, TI_GET_SYMTAG, &tag))
+ if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
return FALSE;
switch (tag)
{
case SymTagArrayType:
- types_get_info(linear, lvalue->typeid, TI_GET_COUNT, &count);
+ types_get_info(&lvalue->type, TI_GET_COUNT, &count);
if (index < 0 || index >= count) return FALSE;
/* fall through */
case SymTagPointerType:
/*
* Get the base type, so we know how much to index by.
*/
- types_get_info(linear, lvalue->typeid, TI_GET_TYPE, &result->typeid);
- types_get_info(linear, result->typeid, TI_GET_LENGTH, &length);
+ types_get_info(&lvalue->type, TI_GET_TYPE, &result->type.id);
+ result->type.module = lvalue->type.module;
+ types_get_info(&result->type, TI_GET_LENGTH, &length);
/* Contents of array must be on same target */
- result->cookie = lvalue->cookie;
result->addr.Mode = lvalue->addr.Mode;
memory_read_value(lvalue, sizeof(result->addr.Offset), &result->addr.Offset);
result->addr.Offset += index * length;
@@ -283,7 +287,7 @@ static BOOL CALLBACK types_cb(PSYMBOL_INFO sym, ULONG size, void* _user)
{
struct type_find_t* user = (struct type_find_t*)_user;
BOOL ret = TRUE;
- DWORD typeid;
+ struct dbg_type type;
if (sym->Tag == user->tag)
{
@@ -297,9 +301,9 @@ static BOOL CALLBACK types_cb(PSYMBOL_INFO sym, ULONG size, void* _user)
}
break;
case SymTagPointerType:
- types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_TYPE, &typeid);
- if (types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_TYPE, &typeid) &&
- typeid == user->u.typeid)
+ type.module = sym->ModBase;
+ type.id = sym->TypeIndex;
+ if (types_get_info(&type, TI_GET_TYPE, &type.id) && type.id == user->u.typeid)
{
user->result = sym->TypeIndex;
ret = FALSE;
@@ -316,14 +320,18 @@ static BOOL CALLBACK types_cb(PSYMBOL_INFO sym, ULONG size, void* _user)
* Should look up in module based at linear whether (typeid*) exists
* Otherwise, we could create it locally
*/
-unsigned long types_find_pointer(unsigned long linear, unsigned long typeid)
+struct dbg_type types_find_pointer(const struct dbg_type* type)
{
struct type_find_t f;
+ struct dbg_type ret;
+
f.result = dbg_itype_none;
f.tag = SymTagPointerType;
- f.u.typeid = typeid;
- SymEnumTypes(dbg_curr_process->handle, linear, types_cb, &f);
- return f.result;
+ f.u.typeid = type->id;
+ SymEnumTypes(dbg_curr_process->handle, type->module, types_cb, &f);
+ ret.module = type->module;
+ ret.id = f.result;
+ return ret;
}
/******************************************************************
@@ -332,15 +340,19 @@ unsigned long types_find_pointer(unsigned long linear, unsigned long typeid)
* Should look up in the module based at linear address whether a type
* named 'name' and with the correct tag exists
*/
-unsigned long types_find_type(unsigned long linear, const char* name, enum SymTagEnum tag)
+struct dbg_type types_find_type(unsigned long linear, const char* name, enum SymTagEnum tag)
{
struct type_find_t f;
+ struct dbg_type ret;
+
f.result = dbg_itype_none;
f.tag = tag;
f.u.name = name;
SymEnumTypes(dbg_curr_process->handle, linear, types_cb, &f);
- return f.result;
+ ret.module = linear;
+ ret.id = f.result;
+ return ret;
}
/***********************************************************************
@@ -352,15 +364,11 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level)
{
struct dbg_lvalue lvalue_field;
int i;
- unsigned long linear;
DWORD tag;
DWORD count;
DWORD size;
- assert(lvalue->cookie == DLV_TARGET || lvalue->cookie == DLV_HOST);
- linear = (unsigned long)memory_to_linear_addr(&lvalue->addr);
-
- if (lvalue->typeid == dbg_itype_none)
+ if (lvalue->type.id == dbg_itype_none)
{
/* No type, just print the addr value */
print_bare_address(&lvalue->addr);
@@ -373,7 +381,7 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level)
format = '\0';
}
- if (!types_get_info(linear, lvalue->typeid, TI_GET_SYMTAG, &tag))
+ if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
{
WINE_FIXME("---error\n");
return;
@@ -386,32 +394,34 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level)
print_basic(lvalue, 1, format);
break;
case SymTagUDT:
- if (types_get_info(linear, lvalue->typeid, TI_GET_CHILDRENCOUNT, &count))
+ if (types_get_info(&lvalue->type, TI_GET_CHILDRENCOUNT, &count))
{
char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
WCHAR* ptr;
char tmp[256];
long int tmpbuf;
+ struct dbg_type type;
dbg_printf("{");
fcp->Start = 0;
while (count)
{
fcp->Count = min(count, 256);
- if (types_get_info(linear, lvalue->typeid, TI_FINDCHILDREN, fcp))
+ if (types_get_info(&lvalue->type, TI_FINDCHILDREN, fcp))
{
for (i = 0; i < min(fcp->Count, count); i++)
{
ptr = NULL;
- types_get_info(linear, fcp->ChildId[i], TI_GET_SYMNAME, &ptr);
+ type.module = (unsigned long)memory_to_linear_addr(&lvalue->addr);
+ type.id = fcp->ChildId[i];
+ types_get_info(&type, TI_GET_SYMNAME, &ptr);
if (!ptr) continue;
WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
dbg_printf("%s=", tmp);
HeapFree(GetProcessHeap(), 0, ptr);
lvalue_field = *lvalue;
- if (types_get_udt_element_lvalue(&lvalue_field, linear,
- fcp->ChildId[i], &tmpbuf))
+ if (types_get_udt_element_lvalue(&lvalue_field, &type, &tmpbuf))
{
print_value(&lvalue_field, format, level + 1);
}
@@ -429,8 +439,8 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level)
* Loop over all of the entries, printing stuff as we go.
*/
count = 1; size = 1;
- types_get_info(linear, lvalue->typeid, TI_GET_COUNT, &count);
- types_get_info(linear, lvalue->typeid, TI_GET_LENGTH, &size);
+ types_get_info(&lvalue->type, TI_GET_COUNT, &count);
+ types_get_info(&lvalue->type, TI_GET_LENGTH, &size);
if (size == count)
{
@@ -441,14 +451,14 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level)
*/
/* FIXME should check basic type here (should be a char!!!!)... */
len = min(count, sizeof(buffer));
- memory_get_string(dbg_curr_thread->handle,
+ memory_get_string(dbg_curr_process->handle,
memory_to_linear_addr(&lvalue->addr),
- lvalue->cookie, TRUE, buffer, len);
+ lvalue->cookie == DLV_TARGET, TRUE, buffer, len);
dbg_printf("\"%s%s\"", buffer, (len < count) ? "..." : "");
break;
}
lvalue_field = *lvalue;
- types_get_info(linear, lvalue->typeid, TI_GET_TYPE, &lvalue_field.typeid);
+ types_get_info(&lvalue->type, TI_GET_TYPE, &lvalue_field.type.id);
dbg_printf("{");
for (i = 0; i < count; i++)
{
@@ -461,7 +471,7 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level)
dbg_printf("Function ");
print_bare_address(&lvalue->addr);
dbg_printf(": ");
- types_print_type(linear, lvalue->typeid, FALSE);
+ types_print_type(&lvalue->type, FALSE);
break;
default:
WINE_FIXME("Unknown tag (%lu)\n", tag);
@@ -476,7 +486,11 @@ leave:
static BOOL CALLBACK print_types_cb(PSYMBOL_INFO sym, ULONG size, void* ctx)
{
- types_print_type(sym->ModBase, sym->TypeIndex, TRUE);
+ struct dbg_type type;
+ type.module = sym->ModBase;
+ type.id = sym->TypeIndex;
+ dbg_printf("Mod: %08lx ID: %08lx \n", type.module, type.id);
+ types_print_type(&type, TRUE);
dbg_printf("\n");
return TRUE;
}
@@ -492,20 +506,21 @@ int print_types(void)
return 0;
}
-int types_print_type(DWORD linear, DWORD typeid, BOOL details)
+int types_print_type(const struct dbg_type* type, BOOL details)
{
WCHAR* ptr;
char tmp[256];
const char* name;
- DWORD tag, subtype, count;
+ DWORD tag, udt, count;
+ struct dbg_type subtype;
- if (typeid == dbg_itype_none || !types_get_info(linear, typeid, TI_GET_SYMTAG, &tag))
+ if (type->id == dbg_itype_none || !types_get_info(type, TI_GET_SYMTAG, &tag))
{
- dbg_printf("--invalid--<%lxh>--", typeid);
+ dbg_printf("--invalid--<%lxh>--", type->id);
return FALSE;
}
- if (types_get_info(linear, typeid, TI_GET_SYMNAME, &ptr) && ptr)
+ if (types_get_info(type, TI_GET_SYMNAME, &ptr) && ptr)
{
WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
name = tmp;
@@ -519,47 +534,50 @@ int types_print_type(DWORD linear, DWORD typeid, BOOL details)
if (details) dbg_printf("Basic<%s>", name); else dbg_printf("%s", name);
break;
case SymTagPointerType:
- types_get_info(linear, typeid, TI_GET_TYPE, &subtype);
- types_print_type(linear, subtype, details);
+ types_get_info(type, TI_GET_TYPE, &subtype.id);
+ subtype.module = type->module;
+ types_print_type(&subtype, FALSE);
dbg_printf("*");
break;
case SymTagUDT:
- types_get_info(linear, typeid, TI_GET_UDTKIND, &subtype);
- switch (subtype)
+ types_get_info(type, TI_GET_UDTKIND, &udt);
+ switch (udt)
{
case UdtStruct: dbg_printf("struct %s", name); break;
case UdtUnion: dbg_printf("union %s", name); break;
case UdtClass: dbg_printf("class %s", name); break;
}
if (details &&
- types_get_info(linear, typeid, TI_GET_CHILDRENCOUNT, &count))
+ types_get_info(type, TI_GET_CHILDRENCOUNT, &count))
{
char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
WCHAR* ptr;
char tmp[256];
int i;
-
+ struct dbg_type type_elt;
dbg_printf(" {");
fcp->Start = 0;
while (count)
{
fcp->Count = min(count, 256);
- if (types_get_info(linear, typeid, TI_FINDCHILDREN, fcp))
+ if (types_get_info(type, TI_FINDCHILDREN, fcp))
{
for (i = 0; i < min(fcp->Count, count); i++)
{
ptr = NULL;
- types_get_info(linear, fcp->ChildId[i], TI_GET_SYMNAME, &ptr);
+ type_elt.module = type->module;
+ type_elt.id = fcp->ChildId[i];
+ types_get_info(&type_elt, TI_GET_SYMNAME, &ptr);
if (!ptr) continue;
WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
HeapFree(GetProcessHeap(), 0, ptr);
dbg_printf("%s", tmp);
- if (types_get_info(linear, fcp->ChildId[i], TI_GET_TYPE, &subtype))
+ if (types_get_info(&type_elt, TI_GET_TYPE, &type_elt.id))
{
dbg_printf(":");
- types_print_type(linear, subtype, details);
+ types_print_type(&type_elt, details);
}
if (i < min(fcp->Count, count) - 1 || count > 256) dbg_printf(", ");
}
@@ -571,18 +589,20 @@ int types_print_type(DWORD linear, DWORD typeid, BOOL details)
}
break;
case SymTagArrayType:
- types_get_info(linear, typeid, TI_GET_TYPE, &subtype);
- types_print_type(linear, subtype, details);
+ types_get_info(type, TI_GET_TYPE, &subtype.id);
+ subtype.module = type->module;
+ types_print_type(&subtype, details);
dbg_printf(" %s[]", name);
break;
case SymTagEnum:
dbg_printf("enum %s", name);
break;
case SymTagFunctionType:
- types_get_info(linear, typeid, TI_GET_TYPE, &subtype);
- types_print_type(linear, subtype, FALSE);
+ types_get_info(type, TI_GET_TYPE, &subtype.id);
+ subtype.module = type->module;
+ types_print_type(&subtype, FALSE);
dbg_printf(" (*%s)(", name);
- if (types_get_info(linear, typeid, TI_GET_CHILDRENCOUNT, &count))
+ if (types_get_info(type, TI_GET_CHILDRENCOUNT, &count))
{
char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
@@ -592,11 +612,12 @@ int types_print_type(DWORD linear, DWORD typeid, BOOL details)
while (count)
{
fcp->Count = min(count, 256);
- if (types_get_info(linear, typeid, TI_FINDCHILDREN, fcp))
+ if (types_get_info(type, TI_FINDCHILDREN, fcp))
{
for (i = 0; i < min(fcp->Count, count); i++)
{
- types_print_type(linear, fcp->ChildId[i], FALSE);
+ subtype.id = fcp->ChildId[i];
+ types_print_type(&subtype, FALSE);
if (i < min(fcp->Count, count) - 1 || count > 256) dbg_printf(", ");
}
}
@@ -614,31 +635,17 @@ int types_print_type(DWORD linear, DWORD typeid, BOOL details)
return TRUE;
}
-BOOL types_get_info(unsigned long modbase, unsigned long typeid,
- IMAGEHLP_SYMBOL_TYPE_INFO ti, void* pInfo)
+BOOL types_get_info(const struct dbg_type* type, IMAGEHLP_SYMBOL_TYPE_INFO ti, void* pInfo)
{
- if (typeid == dbg_itype_none) return FALSE;
- if (typeid < dbg_itype_first)
- {
- BOOL ret;
- DWORD tag;
-
- ret = SymGetTypeInfo(dbg_curr_process->handle, modbase, typeid, ti, pInfo);
- if (!ret && ti == TI_GET_LENGTH &&
- (!SymGetTypeInfo(dbg_curr_process->handle, modbase, typeid,
- TI_GET_SYMTAG, &tag) || tag == SymTagData))
- {
- WINE_FIXME("get length on symtag data is no longer supported\n");
- assert(0);
- }
- return ret;
- }
- assert(modbase);
+ if (type->id == dbg_itype_none) return FALSE;
+ if (type->module != 0)
+ return SymGetTypeInfo(dbg_curr_process->handle, type->module, type->id, ti, pInfo);
+ assert(type->id >= dbg_itype_first);
/* helper to typecast pInfo to its expected type (_t) */
#define X(_t) (*((_t*)pInfo))
- switch (typeid)
+ switch (type->id)
{
case dbg_itype_unsigned_int:
switch (ti)
@@ -712,7 +719,7 @@ BOOL types_get_info(unsigned long modbase, unsigned long typeid,
default: WINE_FIXME("unsupported %u for a string\n", ti); return FALSE;
}
break;
- default: WINE_FIXME("unsupported typeid 0x%lx\n", typeid);
+ default: WINE_FIXME("unsupported type id 0x%lx\n", type->id);
}
#undef X
diff --git a/programs/winedbg/winedbg.c b/programs/winedbg/winedbg.c
index 64ce2873e4b..ee37c0fc45e 100644
--- a/programs/winedbg/winedbg.c
+++ b/programs/winedbg/winedbg.c
@@ -45,6 +45,9 @@
* + make the output as close as possible to what gdb does
* - symbol management:
* + symbol table loading is broken
+ * + in symbol_get_lvalue, we don't do any scoping (as C does) between local and
+ * global vars (we may need this to force some display for example). A solution
+ * would be always to return arrays with: local vars, global vars, thunks
* - type management:
* + some bits of internal types are missing (like type casts and the address
* operator)
@@ -55,7 +58,10 @@
* o bitfield size is on a 4-bytes
* + some bits of internal types are missing (like type casts and the address
* operator)
- * - execution
+ * - execution:
+ * + display: we shouldn't need to tell whether a display is local or not. This
+ * should be automatically guessed by checking whether the variables that are
+ * references are local or not
* + set a better fix for gdb (proxy mode) than the step-mode hack
* + implement function call in debuggee
* + trampoline management is broken when getting 16 <=> 32 thunk destination
@@ -339,6 +345,8 @@ struct dbg_thread* dbg_add_thread(struct dbg_process* p, DWORD tid,
t->wait_for_first_exception = 0;
t->exec_mode = dbg_exec_cont;
t->exec_count = 0;
+ t->step_over_bp.enabled = FALSE;
+ t->step_over_bp.refcount = 0;
snprintf(t->name, sizeof(t->name), "0x%08lx", tid);
@@ -354,8 +362,8 @@ static void dbg_init_current_thread(void* start)
{
if (start)
{
- if (dbg_curr_thread->process->threads &&
- !dbg_curr_thread->process->threads->next && /* first thread ? */
+ if (dbg_curr_process->threads &&
+ !dbg_curr_process->threads->next && /* first thread ? */
DBG_IVAR(BreakAllThreadsStartup))
{
ADDRESS addr;
@@ -562,8 +570,7 @@ static DWORD dbg_handle_exception(EXCEPTION_RECORD* rec, BOOL first_chance,
else
pThread = dbg_get_thread(dbg_curr_process, pThreadName->dwThreadID);
- if (ReadProcessMemory(dbg_curr_thread->process->handle, pThreadName->szName,
- pThread->name, 9, NULL))
+ if (dbg_read_memory(pThreadName->szName, pThread->name, 9))
dbg_printf("Thread ID=0x%lx renamed using MS VC6 extension (name==\"%s\")\n",
pThread->tid, pThread->name);
return DBG_CONTINUE;
@@ -636,11 +643,11 @@ static DWORD dbg_handle_exception(EXCEPTION_RECORD* rec, BOOL first_chance,
case EXCEPTION_WINE_STUB:
{
char dll[32], name[64];
- memory_get_string(dbg_curr_thread->process->handle,
- (void*)rec->ExceptionInformation[0], DLV_TARGET, FALSE,
+ memory_get_string(dbg_curr_process->handle,
+ (void*)rec->ExceptionInformation[0], TRUE, FALSE,
dll, sizeof(dll));
- memory_get_string(dbg_curr_thread->process->handle,
- (void*)rec->ExceptionInformation[1], DLV_TARGET, FALSE,
+ memory_get_string(dbg_curr_process->handle,
+ (void*)rec->ExceptionInformation[1], TRUE, FALSE,
name, sizeof(name));
dbg_printf("unimplemented function %s.%s called", dll, name);
}
@@ -854,7 +861,7 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de)
WINE_ERR("Unknown thread\n");
break;
}
- memory_get_string_indirect(dbg_curr_thread->process->handle,
+ memory_get_string_indirect(dbg_curr_process->handle,
de->u.LoadDll.lpImageName,
de->u.LoadDll.fUnicode,
buffer, sizeof(buffer));
@@ -894,8 +901,8 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de)
break;
}
- memory_get_string(dbg_curr_thread->process->handle,
- de->u.DebugString.lpDebugStringData, DLV_TARGET,
+ memory_get_string(dbg_curr_process->handle,
+ de->u.DebugString.lpDebugStringData, TRUE,
de->u.DebugString.fUnicode, buffer, sizeof(buffer));
WINE_TRACE("%08lx:%08lx: output debug string (%s)\n",
de->dwProcessId, de->dwThreadId, buffer);