dbghelp/dwarf: Added support for OP_call_frame_cfa.
Signed-off-by: Eric Pouech <eric.pouech@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
1ecd66200d
commit
d8c9171c78
|
@ -234,6 +234,7 @@ struct dwarf2_module_info_s
|
||||||
|
|
||||||
#define loc_dwarf2_location_list (loc_user + 0)
|
#define loc_dwarf2_location_list (loc_user + 0)
|
||||||
#define loc_dwarf2_block (loc_user + 1)
|
#define loc_dwarf2_block (loc_user + 1)
|
||||||
|
#define loc_dwarf2_frame_cfa (loc_user + 2)
|
||||||
|
|
||||||
/* forward declarations */
|
/* forward declarations */
|
||||||
static struct symt* dwarf2_parse_enumeration_type(dwarf2_debug_info_t* entry);
|
static struct symt* dwarf2_parse_enumeration_type(dwarf2_debug_info_t* entry);
|
||||||
|
@ -1085,8 +1086,13 @@ static BOOL dwarf2_compute_location_attr(dwarf2_parse_context_t* ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* assume we have a block form */
|
/* assume we have a block form */
|
||||||
|
if (dw == DW_AT_frame_base && xloc.u.block.size == 1 && *xloc.u.block.ptr == DW_OP_call_frame_cfa)
|
||||||
if (xloc.u.block.size)
|
{
|
||||||
|
loc->kind = loc_dwarf2_frame_cfa;
|
||||||
|
loc->reg = Wine_DW_no_register;
|
||||||
|
loc->offset = 0;
|
||||||
|
}
|
||||||
|
else if (xloc.u.block.size)
|
||||||
{
|
{
|
||||||
dwarf2_traverse_context_t lctx;
|
dwarf2_traverse_context_t lctx;
|
||||||
enum location_error err;
|
enum location_error err;
|
||||||
|
@ -2818,6 +2824,8 @@ static const dwarf2_cuhead_t* get_cuhead_from_func(const struct symt_function* f
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL compute_call_frame_cfa(struct module* module, ULONG_PTR ip, struct location* frame);
|
||||||
|
|
||||||
static enum location_error loc_compute_frame(struct process* pcs,
|
static enum location_error loc_compute_frame(struct process* pcs,
|
||||||
const struct module_format* modfmt,
|
const struct module_format* modfmt,
|
||||||
const struct symt_function* func,
|
const struct symt_function* func,
|
||||||
|
@ -2858,6 +2866,9 @@ static enum location_error loc_compute_frame(struct process* pcs,
|
||||||
return loc_err_too_complex;
|
return loc_err_too_complex;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case loc_dwarf2_frame_cfa:
|
||||||
|
if (!compute_call_frame_cfa(modfmt->module, ip + ((struct symt_compiland*)func->container)->address, frame)) return loc_err_internal;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
WARN("Unsupported frame kind %d\n", pframe->kind);
|
WARN("Unsupported frame kind %d\n", pframe->kind);
|
||||||
return loc_err_internal;
|
return loc_err_internal;
|
||||||
|
@ -3647,6 +3658,43 @@ BOOL dwarf2_virtual_unwind(struct cpu_stack_walk *csw, ULONG_PTR ip,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL compute_call_frame_cfa(struct module* module, ULONG_PTR ip, struct location* frame)
|
||||||
|
{
|
||||||
|
struct frame_info info;
|
||||||
|
|
||||||
|
if (!dwarf2_fetch_frame_info(module, dbghelp_current_cpu, ip, &info)) return FALSE;
|
||||||
|
|
||||||
|
/* beginning of function, or no available dwarf information ? */
|
||||||
|
if (ip == info.ip || info.state.rules[info.retaddr_reg] == RULE_UNSET)
|
||||||
|
{
|
||||||
|
/* fake the default unwinder */
|
||||||
|
frame->kind = loc_regrel;
|
||||||
|
frame->reg = dbghelp_current_cpu->frame_regno;
|
||||||
|
frame->offset = dbghelp_current_cpu->word_size; /* FIXME stack direction */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* we expect to translate the call_frame_cfa into a regrel location...
|
||||||
|
* that should cover most of the cases
|
||||||
|
*/
|
||||||
|
switch (info.state.cfa_rule)
|
||||||
|
{
|
||||||
|
case RULE_EXPRESSION:
|
||||||
|
FIXME("Too complex expression for frame_CFA resolution (RULE_EXPRESSION)\n");
|
||||||
|
break;
|
||||||
|
case RULE_VAL_EXPRESSION:
|
||||||
|
FIXME("Too complex expression for frame_CFA resolution (RULE_VAL_EXPRESSION)\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
frame->kind = loc_regrel;
|
||||||
|
frame->reg = dbghelp_current_cpu->map_dwarf_register(info.state.cfa_reg, module, TRUE);
|
||||||
|
frame->offset = info.state.cfa_offset;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void dwarf2_location_compute(struct process* pcs,
|
static void dwarf2_location_compute(struct process* pcs,
|
||||||
const struct module_format* modfmt,
|
const struct module_format* modfmt,
|
||||||
const struct symt_function* func,
|
const struct symt_function* func,
|
||||||
|
|
Loading…
Reference in New Issue