mirror of
git://source.winehq.org/git/wine.git
synced 2024-07-20 19:04:11 +00:00
winedbg: Do type / id discrimination when parsing.
- Get rid of struct type_expr_t - Enable back typecasts (and rewrite the typecast to fit the type parsing scheme) Signed-off-by: Eric Pouech <eric.pouech@gmail.com>
This commit is contained in:
parent
af0c59bcc8
commit
73770ce573
|
@ -44,7 +44,7 @@ static void parser(const char*);
|
|||
dbg_lgint_t integer;
|
||||
IMAGEHLP_LINE64 listing;
|
||||
struct expr* expression;
|
||||
struct type_expr_t type;
|
||||
struct dbg_type type;
|
||||
struct list_string* strings;
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,7 @@ static void parser(const char*);
|
|||
%token tSTEPI tNEXTI tFINISH tSHOW tDIR tWHATIS tSOURCE
|
||||
%token <string> tPATH tIDENTIFIER tSTRING tINTVAR
|
||||
%token <integer> tNUM tFORMAT
|
||||
%token <type> tTYPEDEF
|
||||
%token tSYMBOLFILE tRUN tATTACH tDETACH tKILL tMAINTENANCE tTYPE tMINIDUMP
|
||||
%token tNOPROCESS
|
||||
|
||||
|
@ -346,11 +347,12 @@ type_expr:
|
|||
| tFLOAT { if (!types_find_basic(L"float", $1, &$$)) YYERROR; }
|
||||
| tDOUBLE { if (!types_find_basic(L"double", $1, &$$)) YYERROR; }
|
||||
| tLONG tDOUBLE { if (!types_find_basic(L"long double", $1, &$$)) YYERROR; }
|
||||
| type_expr '*' { $$ = $1; $$.deref_count++; }
|
||||
| tCLASS identifier { $$.type = type_expr_udt_class; $$.deref_count = 0; $$.u.name = $2; }
|
||||
| tSTRUCT identifier { $$.type = type_expr_udt_struct; $$.deref_count = 0; $$.u.name = $2; }
|
||||
| tUNION identifier { $$.type = type_expr_udt_union; $$.deref_count = 0; $$.u.name = $2; }
|
||||
| tENUM identifier { $$.type = type_expr_enumeration; $$.deref_count = 0; $$.u.name = $2; }
|
||||
| tTYPEDEF { $$ = $1; }
|
||||
| type_expr '*' { if (!types_find_pointer(&$1, &$$)) {yyerror("Cannot find pointer type\n"); YYERROR; } }
|
||||
| tCLASS identifier { if (!types_find_type($2, SymTagUDT, &$$)) {yyerror("Unknown type\n"); YYERROR; } }
|
||||
| tSTRUCT identifier { if (!types_find_type($2, SymTagUDT, &$$)) {yyerror("Unknown type\n"); YYERROR; } }
|
||||
| tUNION identifier { if (!types_find_type($2, SymTagUDT, &$$)) {yyerror("Unknown type\n"); YYERROR; } }
|
||||
| tENUM identifier { if (!types_find_type($2, SymTagEnum, &$$)) {yyerror("Unknown type\n"); YYERROR; } }
|
||||
;
|
||||
|
||||
expr_lvalue:
|
||||
|
|
|
@ -100,6 +100,13 @@ static char* unescape_string(const char* str)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int resolve_identifier(const char* id, DBG_STYPE* lval)
|
||||
{
|
||||
if (types_find_type(id, SymTagTypedef, &lval->type)) return tTYPEDEF;
|
||||
lval->string = lexeme_alloc(id);
|
||||
return tIDENTIFIER;
|
||||
}
|
||||
|
||||
#define YY_INPUT(buf,result,max_size) \
|
||||
(result = input_lex_read_buffer(buf, max_size))
|
||||
|
||||
|
@ -258,7 +265,7 @@ union { return tUNION; }
|
|||
enum { return tENUM; }
|
||||
all { return tALL; }
|
||||
|
||||
{MODULE_IDENTIFIER}?{SCOPED_IDENTIFIER}*{IDENTIFIER} { dbg_lval.string = lexeme_alloc(yytext); return tIDENTIFIER; }
|
||||
{MODULE_IDENTIFIER}?{SCOPED_IDENTIFIER}*{IDENTIFIER} { return resolve_identifier(yytext, &dbg_lval); }
|
||||
"$"{IDENTIFIER} { dbg_lval.string = lexeme_alloc(yytext+1); return tINTVAR; }
|
||||
|
||||
<PATH_EXPECTED,PATH_ACCEPTED>{PATHNAME} { dbg_lval.string = lexeme_alloc(yytext); return tPATH; }
|
||||
|
|
|
@ -150,14 +150,15 @@ static inline void init_lvalue(struct dbg_lvalue* lv, BOOL in_debuggee, void* ad
|
|||
lv->type.id = dbg_itype_none;
|
||||
}
|
||||
|
||||
static inline void init_lvalue_in_debugger(struct dbg_lvalue* lv, enum dbg_internal_types it, void* addr)
|
||||
static inline void init_lvalue_in_debugger(struct dbg_lvalue* lv, DWORD_PTR module,
|
||||
enum dbg_internal_types it, void* addr)
|
||||
{
|
||||
lv->in_debuggee = 0;
|
||||
lv->bitstart = 0;
|
||||
lv->bitlen = 0;
|
||||
lv->addr.Mode = AddrModeFlat;
|
||||
lv->addr.Offset = (DWORD_PTR)addr;
|
||||
lv->type.module = 0;
|
||||
lv->type.module = module;
|
||||
lv->type.id = it;
|
||||
}
|
||||
|
||||
|
@ -310,26 +311,6 @@ struct dbg_internal_var
|
|||
|
||||
enum sym_get_lval {sglv_found, sglv_unknown, sglv_aborted};
|
||||
|
||||
enum type_expr_e
|
||||
{
|
||||
type_expr_type_id,
|
||||
type_expr_udt_class,
|
||||
type_expr_udt_struct,
|
||||
type_expr_udt_union,
|
||||
type_expr_enumeration
|
||||
};
|
||||
|
||||
struct type_expr_t
|
||||
{
|
||||
enum type_expr_e type;
|
||||
unsigned deref_count;
|
||||
union
|
||||
{
|
||||
struct dbg_type type;
|
||||
const char* name;
|
||||
} u;
|
||||
};
|
||||
|
||||
enum dbg_start {start_ok, start_error_parse, start_error_init};
|
||||
|
||||
/* break.c */
|
||||
|
@ -385,7 +366,7 @@ extern struct expr* expr_alloc_unary_op(int oper, struct expr*);
|
|||
extern struct expr* expr_alloc_pstruct(struct expr*, const char* element);
|
||||
extern struct expr* expr_alloc_struct(struct expr*, const char* element);
|
||||
extern struct expr* WINAPIV expr_alloc_func_call(const char*, int nargs, ...);
|
||||
extern struct expr* expr_alloc_typecast(struct type_expr_t*, struct expr*);
|
||||
extern struct expr* expr_alloc_typecast(struct dbg_type*, struct expr*);
|
||||
extern struct dbg_lvalue expr_eval(struct expr*);
|
||||
extern struct expr* expr_clone(const struct expr* exp, BOOL *local_binding);
|
||||
extern BOOL expr_free(struct expr* exp);
|
||||
|
@ -510,12 +491,13 @@ extern BOOL types_udt_find_element(struct dbg_lvalue* value, const c
|
|||
extern BOOL types_array_index(const struct dbg_lvalue* value, int index, struct dbg_lvalue* result);
|
||||
extern BOOL types_get_info(const struct dbg_type*, IMAGEHLP_SYMBOL_TYPE_INFO, void*);
|
||||
extern BOOL types_get_real_type(struct dbg_type* type, DWORD* tag);
|
||||
extern struct dbg_type types_find_pointer(const struct dbg_type* type);
|
||||
extern struct dbg_type types_find_type(DWORD64 linear, const char* name, enum SymTagEnum tag);
|
||||
extern BOOL types_find_pointer(const struct dbg_type* type, struct dbg_type* outtype);
|
||||
extern BOOL types_find_type(const char* name, enum SymTagEnum tag, struct dbg_type* outtype);
|
||||
extern BOOL types_compare(const struct dbg_type, const struct dbg_type, BOOL* equal);
|
||||
extern BOOL types_is_integral_type(const struct dbg_lvalue*);
|
||||
extern BOOL types_is_float_type(const struct dbg_lvalue*);
|
||||
extern BOOL types_find_basic(const WCHAR*, const char*, struct type_expr_t* type);
|
||||
extern BOOL types_is_pointer_type(const struct dbg_lvalue*);
|
||||
extern BOOL types_find_basic(const WCHAR*, const char*, struct dbg_type* type);
|
||||
|
||||
/* winedbg.c */
|
||||
#ifdef __GNUC__
|
||||
|
|
|
@ -75,8 +75,9 @@ struct expr
|
|||
|
||||
struct
|
||||
{
|
||||
struct type_expr_t cast_to;
|
||||
struct dbg_type cast_to;
|
||||
struct expr* expr;
|
||||
dbg_lgint_t result;
|
||||
} cast;
|
||||
|
||||
struct
|
||||
|
@ -128,14 +129,14 @@ void expr_free_all(void)
|
|||
next_expr_free = 0;
|
||||
}
|
||||
|
||||
struct expr* expr_alloc_typecast(struct type_expr_t* tet, struct expr* exp)
|
||||
struct expr* expr_alloc_typecast(struct dbg_type* type, struct expr* exp)
|
||||
{
|
||||
struct expr* ex;
|
||||
|
||||
ex = expr_alloc();
|
||||
|
||||
ex->type = EXPR_TYPE_CAST;
|
||||
ex->un.cast.cast_to = *tet;
|
||||
ex->un.cast.cast_to = *type;
|
||||
ex->un.cast.expr = exp;
|
||||
return ex;
|
||||
}
|
||||
|
@ -272,75 +273,74 @@ struct expr* WINAPIV expr_alloc_func_call(const char* funcname, int nargs, ...)
|
|||
struct dbg_lvalue expr_eval(struct expr* exp)
|
||||
{
|
||||
struct dbg_lvalue rtn;
|
||||
int i;
|
||||
struct dbg_lvalue exp1;
|
||||
struct dbg_lvalue exp2;
|
||||
DWORD64 scale1, scale2, scale3;
|
||||
struct dbg_type type1, type2;
|
||||
DWORD tag;
|
||||
const struct dbg_internal_var* div;
|
||||
BOOL ret;
|
||||
|
||||
init_lvalue_in_debugger(&rtn, dbg_itype_none, NULL);
|
||||
init_lvalue_in_debugger(&rtn, 0, dbg_itype_none, NULL);
|
||||
|
||||
switch (exp->type)
|
||||
{
|
||||
case EXPR_TYPE_CAST:
|
||||
/* this is really brute force, we simply change the type... without
|
||||
* checking if this is right or not
|
||||
*/
|
||||
rtn = expr_eval(exp->un.cast.expr);
|
||||
switch (exp->un.cast.cast_to.type)
|
||||
{
|
||||
case type_expr_type_id:
|
||||
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.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.type = types_find_type(rtn.type.module, 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.type = types_find_type(rtn.type.module, 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);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
dbg_printf("Unsupported cast type %u\n", exp->un.cast.cast_to.type);
|
||||
exp1 = expr_eval(exp->un.cast.expr);
|
||||
if (exp1.type.id == dbg_itype_none)
|
||||
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
||||
}
|
||||
for (i = 0; i < exp->un.cast.cast_to.deref_count; i++)
|
||||
rtn = exp1;
|
||||
rtn.type = exp->un.cast.cast_to;
|
||||
init_lvalue_in_debugger(&rtn, exp->un.cast.cast_to.module, exp->un.cast.cast_to.id, &exp->un.cast.result);
|
||||
if (types_is_float_type(&exp1))
|
||||
{
|
||||
rtn.type = types_find_pointer(&rtn.type);
|
||||
if (rtn.type.id == dbg_itype_none)
|
||||
double dbl;
|
||||
ret = memory_fetch_float(&exp1, &dbl);
|
||||
if (ret)
|
||||
{
|
||||
dbg_printf("Cannot find pointer type\n");
|
||||
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
||||
if (types_is_float_type(&rtn))
|
||||
ret = memory_store_float(&rtn, &dbl);
|
||||
else if (types_is_integral_type(&rtn))
|
||||
ret = memory_store_integer(&rtn, (dbg_lgint_t)dbl);
|
||||
else
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
else if (types_is_integral_type(&exp1))
|
||||
{
|
||||
dbg_lgint_t val = types_extract_as_integer(&exp1);
|
||||
if (types_is_float_type(&rtn))
|
||||
{
|
||||
double dbl = val;
|
||||
ret = memory_store_float(&rtn, &dbl);
|
||||
}
|
||||
else if (types_is_integral_type(&rtn) || types_is_pointer_type(&rtn))
|
||||
ret = memory_store_integer(&rtn, val);
|
||||
else
|
||||
ret = FALSE;
|
||||
}
|
||||
else if (types_is_pointer_type(&exp1))
|
||||
{
|
||||
dbg_lgint_t val = types_extract_as_integer(&exp1);
|
||||
|
||||
if (types_is_integral_type(&rtn) || types_is_pointer_type(&rtn))
|
||||
ret = memory_store_integer(&rtn, val);
|
||||
else
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
if (!ret)
|
||||
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
||||
break;
|
||||
case EXPR_TYPE_STRING:
|
||||
init_lvalue_in_debugger(&rtn, dbg_itype_astring, &exp->un.string.str);
|
||||
init_lvalue_in_debugger(&rtn, 0, dbg_itype_astring, &exp->un.string.str);
|
||||
break;
|
||||
case EXPR_TYPE_U_CONST:
|
||||
init_lvalue_in_debugger(&rtn, dbg_itype_lguint, &exp->un.u_const.value);
|
||||
init_lvalue_in_debugger(&rtn, 0, dbg_itype_lguint, &exp->un.u_const.value);
|
||||
break;
|
||||
case EXPR_TYPE_S_CONST:
|
||||
init_lvalue_in_debugger(&rtn, dbg_itype_lgint, &exp->un.s_const.value);
|
||||
init_lvalue_in_debugger(&rtn, 0, dbg_itype_lgint, &exp->un.s_const.value);
|
||||
break;
|
||||
case EXPR_TYPE_SYMBOL:
|
||||
switch (symbol_get_lvalue(exp->un.symbol.name, -1, &rtn, FALSE))
|
||||
|
@ -440,7 +440,7 @@ struct dbg_lvalue expr_eval(struct expr* exp)
|
|||
*/
|
||||
exp->un.call.result = 0;
|
||||
#endif
|
||||
init_lvalue_in_debugger(&rtn, dbg_itype_none, &exp->un.call.result);
|
||||
init_lvalue_in_debugger(&rtn, 0, dbg_itype_none, &exp->un.call.result);
|
||||
/* get return type from function signature type */
|
||||
/* FIXME rtn.type.module should be set to function's module... */
|
||||
types_get_info(&rtn.type, TI_GET_TYPE, &rtn.type.id);
|
||||
|
@ -448,14 +448,14 @@ struct dbg_lvalue expr_eval(struct expr* exp)
|
|||
case EXPR_TYPE_INTVAR:
|
||||
if (!(div = dbg_get_internal_var(exp->un.intvar.name)))
|
||||
RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
|
||||
init_lvalue_in_debugger(&rtn, div->typeid, div->pval);
|
||||
init_lvalue_in_debugger(&rtn, 0, div->typeid, div->pval);
|
||||
break;
|
||||
case EXPR_TYPE_BINOP:
|
||||
exp1 = expr_eval(exp->un.binop.exp1);
|
||||
exp2 = expr_eval(exp->un.binop.exp2);
|
||||
if (exp1.type.id == dbg_itype_none || exp2.type.id == dbg_itype_none)
|
||||
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
||||
init_lvalue_in_debugger(&rtn, dbg_itype_lgint, &exp->un.binop.result);
|
||||
init_lvalue_in_debugger(&rtn, 0, dbg_itype_lgint, &exp->un.binop.result);
|
||||
type1 = exp1.type;
|
||||
type2 = exp2.type;
|
||||
switch (exp->un.binop.binop_type)
|
||||
|
@ -584,7 +584,7 @@ struct dbg_lvalue expr_eval(struct expr* exp)
|
|||
case EXPR_TYPE_UNOP:
|
||||
exp1 = expr_eval(exp->un.unop.exp1);
|
||||
if (exp1.type.id == dbg_itype_none) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
||||
init_lvalue_in_debugger(&rtn, dbg_itype_lgint, &exp->un.unop.result);
|
||||
init_lvalue_in_debugger(&rtn, 0, dbg_itype_lgint, &exp->un.unop.result);
|
||||
switch (exp->un.unop.unop_type)
|
||||
{
|
||||
case EXP_OP_NEG:
|
||||
|
@ -610,8 +610,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 = (ULONG_PTR)memory_to_linear_addr(&exp1.addr);
|
||||
rtn.type = types_find_pointer(&exp1.type);
|
||||
if (rtn.type.id == dbg_itype_none)
|
||||
if (!types_find_pointer(&exp1.type, &rtn.type))
|
||||
RaiseException(DEBUG_STATUS_CANT_DEREF, 0, 0, NULL);
|
||||
break;
|
||||
default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
|
||||
|
@ -629,30 +628,12 @@ struct dbg_lvalue expr_eval(struct expr* exp)
|
|||
BOOL expr_print(const struct expr* exp)
|
||||
{
|
||||
int i;
|
||||
struct dbg_type type;
|
||||
|
||||
switch (exp->type)
|
||||
{
|
||||
case EXPR_TYPE_CAST:
|
||||
WINE_FIXME("No longer supported (missing module base)\n");
|
||||
dbg_printf("((");
|
||||
switch (exp->un.cast.cast_to.type)
|
||||
{
|
||||
case type_expr_type_id:
|
||||
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:
|
||||
dbg_printf("struct %s", exp->un.cast.cast_to.u.name); break;
|
||||
case type_expr_udt_union:
|
||||
dbg_printf("union %s", exp->un.cast.cast_to.u.name); break;
|
||||
case type_expr_enumeration:
|
||||
dbg_printf("enum %s", exp->un.cast.cast_to.u.name); break;
|
||||
}
|
||||
for (i = 0; i < exp->un.cast.cast_to.deref_count; i++)
|
||||
dbg_printf("*");
|
||||
types_print_type(&exp->un.cast.cast_to, FALSE);
|
||||
dbg_printf(")");
|
||||
expr_print(exp->un.cast.expr);
|
||||
dbg_printf(")");
|
||||
|
|
|
@ -103,7 +103,7 @@ BOOL stack_get_register_frame(const struct dbg_internal_var* div, struct dbg_lva
|
|||
struct dbg_frame* currfrm = stack_get_curr_frame();
|
||||
if (currfrm == NULL) return FALSE;
|
||||
if (currfrm->is_ctx_valid)
|
||||
init_lvalue_in_debugger(lvalue, div->typeid,
|
||||
init_lvalue_in_debugger(lvalue, 0, div->typeid,
|
||||
(char*)&currfrm->context + (DWORD_PTR)div->pval);
|
||||
else
|
||||
{
|
||||
|
@ -116,13 +116,13 @@ BOOL stack_get_register_frame(const struct dbg_internal_var* div, struct dbg_lva
|
|||
switch (kind)
|
||||
{
|
||||
case be_cpu_addr_pc:
|
||||
init_lvalue_in_debugger(lvalue, itype, &currfrm->linear_pc);
|
||||
init_lvalue_in_debugger(lvalue, 0, itype, &currfrm->linear_pc);
|
||||
break;
|
||||
case be_cpu_addr_stack:
|
||||
init_lvalue_in_debugger(lvalue, itype, &currfrm->linear_stack);
|
||||
init_lvalue_in_debugger(lvalue, 0, itype, &currfrm->linear_stack);
|
||||
break;
|
||||
case be_cpu_addr_frame:
|
||||
init_lvalue_in_debugger(lvalue, itype, &currfrm->linear_frame);
|
||||
init_lvalue_in_debugger(lvalue, 0, itype, &currfrm->linear_frame);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -300,7 +300,8 @@ BOOL types_array_index(const struct dbg_lvalue* lvalue, int index, struct dbg_lv
|
|||
}
|
||||
break;
|
||||
default:
|
||||
assert(FALSE);
|
||||
FIXME("unexpected tag %lx\n", tag);
|
||||
return FALSE;
|
||||
}
|
||||
/*
|
||||
* Get the base type, so we know how much to index by.
|
||||
|
@ -332,13 +333,9 @@ BOOL types_array_index(const struct dbg_lvalue* lvalue, int index, struct dbg_lv
|
|||
|
||||
struct type_find_t
|
||||
{
|
||||
ULONG result; /* out: the found type */
|
||||
enum SymTagEnum tag; /* in: the tag to look for */
|
||||
union
|
||||
{
|
||||
ULONG typeid; /* when tag is SymTagUDT */
|
||||
const char* name; /* when tag is SymTagPointerType */
|
||||
} u;
|
||||
struct dbg_type type; /* out: the type found */
|
||||
ULONG ptr_typeid; /* in: when tag is SymTagPointerType */
|
||||
};
|
||||
|
||||
static BOOL CALLBACK types_cb(PSYMBOL_INFO sym, ULONG size, void* _user)
|
||||
|
@ -353,18 +350,18 @@ static BOOL CALLBACK types_cb(PSYMBOL_INFO sym, ULONG size, void* _user)
|
|||
switch (user->tag)
|
||||
{
|
||||
case SymTagUDT:
|
||||
if (!strcmp(user->u.name, sym->Name))
|
||||
{
|
||||
user->result = sym->TypeIndex;
|
||||
ret = FALSE;
|
||||
}
|
||||
case SymTagEnum:
|
||||
case SymTagTypedef:
|
||||
user->type.module = sym->ModBase;
|
||||
user->type.id = sym->TypeIndex;
|
||||
ret = FALSE;
|
||||
break;
|
||||
case SymTagPointerType:
|
||||
type.module = sym->ModBase;
|
||||
type.id = sym->TypeIndex;
|
||||
if (types_get_info(&type, TI_GET_TYPE, &type_id) && type_id == user->u.typeid)
|
||||
if (types_get_info(&type, TI_GET_TYPE, &type_id) && type_id == user->ptr_typeid)
|
||||
{
|
||||
user->result = sym->TypeIndex;
|
||||
user->type = type;
|
||||
ret = FALSE;
|
||||
}
|
||||
break;
|
||||
|
@ -380,18 +377,17 @@ 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
|
||||
*/
|
||||
struct dbg_type types_find_pointer(const struct dbg_type* type)
|
||||
BOOL types_find_pointer(const struct dbg_type* type, struct dbg_type* outtype)
|
||||
{
|
||||
struct type_find_t f;
|
||||
struct dbg_type ret;
|
||||
|
||||
f.result = dbg_itype_none;
|
||||
f.type.id = dbg_itype_none;
|
||||
f.tag = SymTagPointerType;
|
||||
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;
|
||||
f.ptr_typeid = type->id;
|
||||
if (!SymEnumTypes(dbg_curr_process->handle, type->module, types_cb, &f) || f.type.id == dbg_itype_none)
|
||||
return FALSE;
|
||||
*outtype = f.type;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
|
@ -400,19 +396,29 @@ struct dbg_type types_find_pointer(const struct dbg_type* type)
|
|||
* Should look up in the module based at linear address whether a type
|
||||
* named 'name' and with the correct tag exists
|
||||
*/
|
||||
struct dbg_type types_find_type(DWORD64 linear, const char* name, enum SymTagEnum tag)
|
||||
|
||||
BOOL types_find_type(const char* name, enum SymTagEnum tag, struct dbg_type* outtype)
|
||||
{
|
||||
struct type_find_t f;
|
||||
struct dbg_type ret;
|
||||
char* str = NULL;
|
||||
BOOL ret;
|
||||
|
||||
f.result = dbg_itype_none;
|
||||
if (!strchr(name, '!')) /* no module, lookup across all modules */
|
||||
{
|
||||
str = malloc(strlen(name) + 3);
|
||||
if (!str) return FALSE;
|
||||
str[0] = '*';
|
||||
str[1] = '!';
|
||||
strcpy(str + 2, name);
|
||||
name = str;
|
||||
}
|
||||
f.type.id = dbg_itype_none;
|
||||
f.tag = tag;
|
||||
f.u.name = name;
|
||||
SymEnumTypes(dbg_curr_process->handle, linear, types_cb, &f);
|
||||
ret.module = linear;
|
||||
ret.id = f.result;
|
||||
return ret;
|
||||
ret = SymEnumTypesByName(dbg_curr_process->handle, 0, name, types_cb, &f);
|
||||
free(str);
|
||||
if (!ret || f.type.id == dbg_itype_none)
|
||||
return FALSE;
|
||||
*outtype = f.type;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -916,7 +922,7 @@ static BOOL CALLBACK enum_mod_cb(const char* module, DWORD64 base, void* user)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL types_find_basic(const WCHAR* name, const char* mod, struct type_expr_t* type)
|
||||
BOOL types_find_basic(const WCHAR* name, const char* mod, struct dbg_type* type)
|
||||
{
|
||||
const struct data_model* model;
|
||||
struct mod_by_name mbn = {mod, 0};
|
||||
|
@ -928,15 +934,13 @@ BOOL types_find_basic(const WCHAR* name, const char* mod, struct typ
|
|||
SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES, opt);
|
||||
if (!ret || mbn.base == 0)
|
||||
return FALSE;
|
||||
type->type = type_expr_type_id;
|
||||
type->deref_count = 0;
|
||||
model = get_data_model(mbn.base);
|
||||
for (; model->name; model++)
|
||||
{
|
||||
if (!wcscmp(name, model->name))
|
||||
{
|
||||
type->u.type.module = 0;
|
||||
type->u.type.id = model->itype;
|
||||
type->module = 0;
|
||||
type->id = model->itype;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -1238,3 +1242,12 @@ BOOL types_is_float_type(const struct dbg_lvalue* lv)
|
|||
!types_get_info(&type, TI_GET_BASETYPE, &bt)) return FALSE;
|
||||
return bt == btFloat;
|
||||
}
|
||||
|
||||
BOOL types_is_pointer_type(const struct dbg_lvalue* lv)
|
||||
{
|
||||
struct dbg_type type = lv->type;
|
||||
DWORD tag;
|
||||
if (lv->bitlen) return FALSE;
|
||||
return types_get_real_type(&type, &tag) &&
|
||||
(tag == SymTagPointerType || tag == SymTagArrayType || tag == SymTagFunctionType);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue