|
|
@ -648,18 +648,18 @@ static void dwarf2_load_one_entry(dwarf2_parse_context_t*, dwarf2_debug_info_t*)
|
|
|
|
|
|
|
|
|
|
|
|
#define Wine_DW_no_register 0x7FFFFFFF
|
|
|
|
#define Wine_DW_no_register 0x7FFFFFFF
|
|
|
|
|
|
|
|
|
|
|
|
static unsigned dwarf2_map_register(int regno)
|
|
|
|
static unsigned dwarf2_map_register(int regno, const struct module* module)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (regno == Wine_DW_no_register)
|
|
|
|
if (regno == Wine_DW_no_register)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
FIXME("What the heck map reg 0x%x\n",regno);
|
|
|
|
FIXME("What the heck map reg 0x%x\n",regno);
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return dbghelp_current_cpu->map_dwarf_register(regno, FALSE);
|
|
|
|
return dbghelp_current_cpu->map_dwarf_register(regno, module, FALSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static enum location_error
|
|
|
|
static enum location_error
|
|
|
|
compute_location(dwarf2_traverse_context_t* ctx, struct location* loc,
|
|
|
|
compute_location(const struct module *module, dwarf2_traverse_context_t* ctx, struct location* loc,
|
|
|
|
HANDLE hproc, const struct location* frame)
|
|
|
|
HANDLE hproc, const struct location* frame)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
DWORD_PTR tmp, stack[64];
|
|
|
|
DWORD_PTR tmp, stack[64];
|
|
|
@ -686,7 +686,7 @@ compute_location(dwarf2_traverse_context_t* ctx, struct location* loc,
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
if (!piece_found)
|
|
|
|
if (!piece_found)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
DWORD cvreg = dwarf2_map_register(op - DW_OP_reg0);
|
|
|
|
DWORD cvreg = dwarf2_map_register(op - DW_OP_reg0, module);
|
|
|
|
if (loc->reg != Wine_DW_no_register)
|
|
|
|
if (loc->reg != Wine_DW_no_register)
|
|
|
|
FIXME("Only supporting one reg (%s/%d -> %s/%d)\n",
|
|
|
|
FIXME("Only supporting one reg (%s/%d -> %s/%d)\n",
|
|
|
|
dbghelp_current_cpu->fetch_regname(loc->reg), loc->reg,
|
|
|
|
dbghelp_current_cpu->fetch_regname(loc->reg), loc->reg,
|
|
|
@ -703,7 +703,7 @@ compute_location(dwarf2_traverse_context_t* ctx, struct location* loc,
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
if (!piece_found)
|
|
|
|
if (!piece_found)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
DWORD cvreg = dwarf2_map_register(op - DW_OP_breg0);
|
|
|
|
DWORD cvreg = dwarf2_map_register(op - DW_OP_breg0, module);
|
|
|
|
if (loc->reg != Wine_DW_no_register)
|
|
|
|
if (loc->reg != Wine_DW_no_register)
|
|
|
|
FIXME("Only supporting one breg (%s/%d -> %s/%d)\n",
|
|
|
|
FIXME("Only supporting one breg (%s/%d -> %s/%d)\n",
|
|
|
|
dbghelp_current_cpu->fetch_regname(loc->reg), loc->reg,
|
|
|
|
dbghelp_current_cpu->fetch_regname(loc->reg), loc->reg,
|
|
|
@ -762,7 +762,7 @@ compute_location(dwarf2_traverse_context_t* ctx, struct location* loc,
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (loc->reg != Wine_DW_no_register)
|
|
|
|
if (loc->reg != Wine_DW_no_register)
|
|
|
|
FIXME("Only supporting one reg\n");
|
|
|
|
FIXME("Only supporting one reg\n");
|
|
|
|
loc->reg = dwarf2_map_register(tmp);
|
|
|
|
loc->reg = dwarf2_map_register(tmp, module);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
loc->kind = loc_register;
|
|
|
|
loc->kind = loc_register;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
@ -770,7 +770,7 @@ compute_location(dwarf2_traverse_context_t* ctx, struct location* loc,
|
|
|
|
tmp = dwarf2_leb128_as_unsigned(ctx);
|
|
|
|
tmp = dwarf2_leb128_as_unsigned(ctx);
|
|
|
|
if (loc->reg != Wine_DW_no_register)
|
|
|
|
if (loc->reg != Wine_DW_no_register)
|
|
|
|
FIXME("Only supporting one regx\n");
|
|
|
|
FIXME("Only supporting one regx\n");
|
|
|
|
loc->reg = dwarf2_map_register(tmp);
|
|
|
|
loc->reg = dwarf2_map_register(tmp, module);
|
|
|
|
stack[++stk] = dwarf2_leb128_as_signed(ctx);
|
|
|
|
stack[++stk] = dwarf2_leb128_as_signed(ctx);
|
|
|
|
loc->kind = loc_regrel;
|
|
|
|
loc->kind = loc_regrel;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
@ -929,7 +929,7 @@ static BOOL dwarf2_compute_location_attr(dwarf2_parse_context_t* ctx,
|
|
|
|
lctx.end_data = xloc.u.block.ptr + xloc.u.block.size;
|
|
|
|
lctx.end_data = xloc.u.block.ptr + xloc.u.block.size;
|
|
|
|
lctx.word_size = ctx->module->format_info[DFI_DWARF]->u.dwarf2_info->word_size;
|
|
|
|
lctx.word_size = ctx->module->format_info[DFI_DWARF]->u.dwarf2_info->word_size;
|
|
|
|
|
|
|
|
|
|
|
|
err = compute_location(&lctx, loc, NULL, frame);
|
|
|
|
err = compute_location(ctx->module, &lctx, loc, NULL, frame);
|
|
|
|
if (err < 0)
|
|
|
|
if (err < 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
loc->kind = loc_error;
|
|
|
|
loc->kind = loc_error;
|
|
|
@ -942,7 +942,7 @@ static BOOL dwarf2_compute_location_attr(dwarf2_parse_context_t* ctx,
|
|
|
|
*ptr = xloc.u.block.size;
|
|
|
|
*ptr = xloc.u.block.size;
|
|
|
|
memcpy(ptr + 1, xloc.u.block.ptr, xloc.u.block.size);
|
|
|
|
memcpy(ptr + 1, xloc.u.block.ptr, xloc.u.block.size);
|
|
|
|
loc->offset = (ULONG_PTR)ptr;
|
|
|
|
loc->offset = (ULONG_PTR)ptr;
|
|
|
|
compute_location(&lctx, loc, NULL, frame);
|
|
|
|
compute_location(ctx->module, &lctx, loc, NULL, frame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
return TRUE;
|
|
|
@ -2527,7 +2527,7 @@ static enum location_error loc_compute_frame(struct process* pcs,
|
|
|
|
modfmt->u.dwarf2_info->debug_loc.address + pframe->offset,
|
|
|
|
modfmt->u.dwarf2_info->debug_loc.address + pframe->offset,
|
|
|
|
ip, &lctx))
|
|
|
|
ip, &lctx))
|
|
|
|
return loc_err_out_of_scope;
|
|
|
|
return loc_err_out_of_scope;
|
|
|
|
if ((err = compute_location(&lctx, frame, pcs->handle, NULL)) < 0) return err;
|
|
|
|
if ((err = compute_location(modfmt->module, &lctx, frame, pcs->handle, NULL)) < 0) return err;
|
|
|
|
if (frame->kind >= loc_user)
|
|
|
|
if (frame->kind >= loc_user)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
WARN("Couldn't compute runtime frame location\n");
|
|
|
|
WARN("Couldn't compute runtime frame location\n");
|
|
|
@ -2781,7 +2781,7 @@ static int valid_reg(ULONG_PTR reg)
|
|
|
|
return (reg < NB_FRAME_REGS);
|
|
|
|
return (reg < NB_FRAME_REGS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void execute_cfa_instructions(dwarf2_traverse_context_t* ctx,
|
|
|
|
static void execute_cfa_instructions(struct module* module, dwarf2_traverse_context_t* ctx,
|
|
|
|
ULONG_PTR last_ip, struct frame_info *info)
|
|
|
|
ULONG_PTR last_ip, struct frame_info *info)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
while (ctx->data < ctx->end_data && info->ip <= last_ip + info->signal_frame)
|
|
|
|
while (ctx->data < ctx->end_data && info->ip <= last_ip + info->signal_frame)
|
|
|
@ -2806,7 +2806,7 @@ static void execute_cfa_instructions(dwarf2_traverse_context_t* ctx,
|
|
|
|
if (!valid_reg(reg)) break;
|
|
|
|
if (!valid_reg(reg)) break;
|
|
|
|
TRACE("%lx: DW_CFA_offset %s, %ld\n",
|
|
|
|
TRACE("%lx: DW_CFA_offset %s, %ld\n",
|
|
|
|
info->ip,
|
|
|
|
info->ip,
|
|
|
|
dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, TRUE)),
|
|
|
|
dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, module, TRUE)),
|
|
|
|
offset);
|
|
|
|
offset);
|
|
|
|
info->state.regs[reg] = offset;
|
|
|
|
info->state.regs[reg] = offset;
|
|
|
|
info->state.rules[reg] = RULE_CFA_OFFSET;
|
|
|
|
info->state.rules[reg] = RULE_CFA_OFFSET;
|
|
|
@ -2818,7 +2818,7 @@ static void execute_cfa_instructions(dwarf2_traverse_context_t* ctx,
|
|
|
|
if (!valid_reg(reg)) break;
|
|
|
|
if (!valid_reg(reg)) break;
|
|
|
|
TRACE("%lx: DW_CFA_restore %s\n",
|
|
|
|
TRACE("%lx: DW_CFA_restore %s\n",
|
|
|
|
info->ip,
|
|
|
|
info->ip,
|
|
|
|
dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, TRUE)));
|
|
|
|
dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, module, TRUE)));
|
|
|
|
info->state.rules[reg] = RULE_UNSET;
|
|
|
|
info->state.rules[reg] = RULE_UNSET;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -2865,7 +2865,7 @@ static void execute_cfa_instructions(dwarf2_traverse_context_t* ctx,
|
|
|
|
if (!valid_reg(reg)) break;
|
|
|
|
if (!valid_reg(reg)) break;
|
|
|
|
TRACE("%lx: DW_CFA_offset_extended %s, %ld\n",
|
|
|
|
TRACE("%lx: DW_CFA_offset_extended %s, %ld\n",
|
|
|
|
info->ip,
|
|
|
|
info->ip,
|
|
|
|
dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, TRUE)),
|
|
|
|
dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, module, TRUE)),
|
|
|
|
offset);
|
|
|
|
offset);
|
|
|
|
info->state.regs[reg] = offset;
|
|
|
|
info->state.regs[reg] = offset;
|
|
|
|
info->state.rules[reg] = RULE_CFA_OFFSET;
|
|
|
|
info->state.rules[reg] = RULE_CFA_OFFSET;
|
|
|
@ -2877,7 +2877,7 @@ static void execute_cfa_instructions(dwarf2_traverse_context_t* ctx,
|
|
|
|
if (!valid_reg(reg)) break;
|
|
|
|
if (!valid_reg(reg)) break;
|
|
|
|
TRACE("%lx: DW_CFA_restore_extended %s\n",
|
|
|
|
TRACE("%lx: DW_CFA_restore_extended %s\n",
|
|
|
|
info->ip,
|
|
|
|
info->ip,
|
|
|
|
dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, TRUE)));
|
|
|
|
dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, module, TRUE)));
|
|
|
|
info->state.rules[reg] = RULE_UNSET;
|
|
|
|
info->state.rules[reg] = RULE_UNSET;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -2887,7 +2887,7 @@ static void execute_cfa_instructions(dwarf2_traverse_context_t* ctx,
|
|
|
|
if (!valid_reg(reg)) break;
|
|
|
|
if (!valid_reg(reg)) break;
|
|
|
|
TRACE("%lx: DW_CFA_undefined %s\n",
|
|
|
|
TRACE("%lx: DW_CFA_undefined %s\n",
|
|
|
|
info->ip,
|
|
|
|
info->ip,
|
|
|
|
dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, TRUE)));
|
|
|
|
dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, module, TRUE)));
|
|
|
|
info->state.rules[reg] = RULE_UNDEFINED;
|
|
|
|
info->state.rules[reg] = RULE_UNDEFINED;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -2897,7 +2897,7 @@ static void execute_cfa_instructions(dwarf2_traverse_context_t* ctx,
|
|
|
|
if (!valid_reg(reg)) break;
|
|
|
|
if (!valid_reg(reg)) break;
|
|
|
|
TRACE("%lx: DW_CFA_same_value %s\n",
|
|
|
|
TRACE("%lx: DW_CFA_same_value %s\n",
|
|
|
|
info->ip,
|
|
|
|
info->ip,
|
|
|
|
dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, TRUE)));
|
|
|
|
dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, module, TRUE)));
|
|
|
|
info->state.regs[reg] = reg;
|
|
|
|
info->state.regs[reg] = reg;
|
|
|
|
info->state.rules[reg] = RULE_SAME;
|
|
|
|
info->state.rules[reg] = RULE_SAME;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
@ -2909,8 +2909,8 @@ static void execute_cfa_instructions(dwarf2_traverse_context_t* ctx,
|
|
|
|
if (!valid_reg(reg) || !valid_reg(reg2)) break;
|
|
|
|
if (!valid_reg(reg) || !valid_reg(reg2)) break;
|
|
|
|
TRACE("%lx: DW_CFA_register %s == %s\n",
|
|
|
|
TRACE("%lx: DW_CFA_register %s == %s\n",
|
|
|
|
info->ip,
|
|
|
|
info->ip,
|
|
|
|
dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, TRUE)),
|
|
|
|
dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, module, TRUE)),
|
|
|
|
dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg2, TRUE)));
|
|
|
|
dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg2, module, TRUE)));
|
|
|
|
info->state.regs[reg] = reg2;
|
|
|
|
info->state.regs[reg] = reg2;
|
|
|
|
info->state.rules[reg] = RULE_OTHER_REG;
|
|
|
|
info->state.rules[reg] = RULE_OTHER_REG;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
@ -2938,7 +2938,7 @@ static void execute_cfa_instructions(dwarf2_traverse_context_t* ctx,
|
|
|
|
if (!valid_reg(reg)) break;
|
|
|
|
if (!valid_reg(reg)) break;
|
|
|
|
TRACE("%lx: DW_CFA_def_cfa %s, %ld\n",
|
|
|
|
TRACE("%lx: DW_CFA_def_cfa %s, %ld\n",
|
|
|
|
info->ip,
|
|
|
|
info->ip,
|
|
|
|
dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, TRUE)),
|
|
|
|
dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, module, TRUE)),
|
|
|
|
offset);
|
|
|
|
offset);
|
|
|
|
info->state.cfa_reg = reg;
|
|
|
|
info->state.cfa_reg = reg;
|
|
|
|
info->state.cfa_offset = offset;
|
|
|
|
info->state.cfa_offset = offset;
|
|
|
@ -2951,7 +2951,7 @@ static void execute_cfa_instructions(dwarf2_traverse_context_t* ctx,
|
|
|
|
if (!valid_reg(reg)) break;
|
|
|
|
if (!valid_reg(reg)) break;
|
|
|
|
TRACE("%lx: DW_CFA_def_cfa_register %s\n",
|
|
|
|
TRACE("%lx: DW_CFA_def_cfa_register %s\n",
|
|
|
|
info->ip,
|
|
|
|
info->ip,
|
|
|
|
dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, TRUE)));
|
|
|
|
dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, module, TRUE)));
|
|
|
|
info->state.cfa_reg = reg;
|
|
|
|
info->state.cfa_reg = reg;
|
|
|
|
info->state.cfa_rule = RULE_CFA_OFFSET;
|
|
|
|
info->state.cfa_rule = RULE_CFA_OFFSET;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
@ -2985,7 +2985,7 @@ static void execute_cfa_instructions(dwarf2_traverse_context_t* ctx,
|
|
|
|
if (!valid_reg(reg)) break;
|
|
|
|
if (!valid_reg(reg)) break;
|
|
|
|
TRACE("%lx: DW_CFA_%sexpression %s %lx-%lx\n",
|
|
|
|
TRACE("%lx: DW_CFA_%sexpression %s %lx-%lx\n",
|
|
|
|
info->ip, (op == DW_CFA_expression) ? "" : "val_",
|
|
|
|
info->ip, (op == DW_CFA_expression) ? "" : "val_",
|
|
|
|
dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, TRUE)),
|
|
|
|
dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, module, TRUE)),
|
|
|
|
expr, expr + len);
|
|
|
|
expr, expr + len);
|
|
|
|
info->state.regs[reg] = expr;
|
|
|
|
info->state.regs[reg] = expr;
|
|
|
|
info->state.rules[reg] = (op == DW_CFA_expression) ? RULE_EXPRESSION : RULE_VAL_EXPRESSION;
|
|
|
|
info->state.rules[reg] = (op == DW_CFA_expression) ? RULE_EXPRESSION : RULE_VAL_EXPRESSION;
|
|
|
@ -3008,10 +3008,10 @@ static void execute_cfa_instructions(dwarf2_traverse_context_t* ctx,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* retrieve a context register from its dwarf number */
|
|
|
|
/* retrieve a context register from its dwarf number */
|
|
|
|
static DWORD64 get_context_reg(struct cpu_stack_walk *csw, union ctx *context,
|
|
|
|
static DWORD64 get_context_reg(const struct module* module, struct cpu_stack_walk *csw, union ctx *context,
|
|
|
|
ULONG_PTR dw_reg)
|
|
|
|
ULONG_PTR dw_reg)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
unsigned regno = csw->cpu->map_dwarf_register(dw_reg, TRUE), sz;
|
|
|
|
unsigned regno = csw->cpu->map_dwarf_register(dw_reg, module, TRUE), sz;
|
|
|
|
void* ptr = csw->cpu->fetch_context_reg(context, regno, &sz);
|
|
|
|
void* ptr = csw->cpu->fetch_context_reg(context, regno, &sz);
|
|
|
|
|
|
|
|
|
|
|
|
if (sz == 8)
|
|
|
|
if (sz == 8)
|
|
|
@ -3024,10 +3024,10 @@ static DWORD64 get_context_reg(struct cpu_stack_walk *csw, union ctx *context,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* set a context register from its dwarf number */
|
|
|
|
/* set a context register from its dwarf number */
|
|
|
|
static void set_context_reg(struct cpu_stack_walk* csw, union ctx *context,
|
|
|
|
static void set_context_reg(const struct module* module, struct cpu_stack_walk* csw, union ctx *context,
|
|
|
|
ULONG_PTR dw_reg, ULONG_PTR val, BOOL isdebuggee)
|
|
|
|
ULONG_PTR dw_reg, ULONG_PTR val, BOOL isdebuggee)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
unsigned regno = csw->cpu->map_dwarf_register(dw_reg, TRUE), sz;
|
|
|
|
unsigned regno = csw->cpu->map_dwarf_register(dw_reg, module, TRUE), sz;
|
|
|
|
ULONG_PTR* ptr = csw->cpu->fetch_context_reg(context, regno, &sz);
|
|
|
|
ULONG_PTR* ptr = csw->cpu->fetch_context_reg(context, regno, &sz);
|
|
|
|
|
|
|
|
|
|
|
|
if (isdebuggee)
|
|
|
|
if (isdebuggee)
|
|
|
@ -3058,12 +3058,12 @@ static void set_context_reg(struct cpu_stack_walk* csw, union ctx *context,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* copy a register from one context to another using dwarf number */
|
|
|
|
/* copy a register from one context to another using dwarf number */
|
|
|
|
static void copy_context_reg(struct cpu_stack_walk *csw,
|
|
|
|
static void copy_context_reg(const struct module* module, struct cpu_stack_walk *csw,
|
|
|
|
union ctx *dstcontext, ULONG_PTR dwregdst,
|
|
|
|
union ctx *dstcontext, ULONG_PTR dwregdst,
|
|
|
|
union ctx *srccontext, ULONG_PTR dwregsrc)
|
|
|
|
union ctx *srccontext, ULONG_PTR dwregsrc)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
unsigned regdstno = csw->cpu->map_dwarf_register(dwregdst, TRUE), szdst;
|
|
|
|
unsigned regdstno = csw->cpu->map_dwarf_register(dwregdst, module, TRUE), szdst;
|
|
|
|
unsigned regsrcno = csw->cpu->map_dwarf_register(dwregsrc, TRUE), szsrc;
|
|
|
|
unsigned regsrcno = csw->cpu->map_dwarf_register(dwregsrc, module, TRUE), szsrc;
|
|
|
|
ULONG_PTR* ptrdst = csw->cpu->fetch_context_reg(dstcontext, regdstno, &szdst);
|
|
|
|
ULONG_PTR* ptrdst = csw->cpu->fetch_context_reg(dstcontext, regdstno, &szdst);
|
|
|
|
ULONG_PTR* ptrsrc = csw->cpu->fetch_context_reg(srccontext, regsrcno, &szsrc);
|
|
|
|
ULONG_PTR* ptrsrc = csw->cpu->fetch_context_reg(srccontext, regsrcno, &szsrc);
|
|
|
|
|
|
|
|
|
|
|
@ -3098,9 +3098,9 @@ static ULONG_PTR eval_expression(const struct module* module, struct cpu_stack_w
|
|
|
|
if (opcode >= DW_OP_lit0 && opcode <= DW_OP_lit31)
|
|
|
|
if (opcode >= DW_OP_lit0 && opcode <= DW_OP_lit31)
|
|
|
|
stack[++sp] = opcode - DW_OP_lit0;
|
|
|
|
stack[++sp] = opcode - DW_OP_lit0;
|
|
|
|
else if (opcode >= DW_OP_reg0 && opcode <= DW_OP_reg31)
|
|
|
|
else if (opcode >= DW_OP_reg0 && opcode <= DW_OP_reg31)
|
|
|
|
stack[++sp] = get_context_reg(csw, context, opcode - DW_OP_reg0);
|
|
|
|
stack[++sp] = get_context_reg(module, csw, context, opcode - DW_OP_reg0);
|
|
|
|
else if (opcode >= DW_OP_breg0 && opcode <= DW_OP_breg31)
|
|
|
|
else if (opcode >= DW_OP_breg0 && opcode <= DW_OP_breg31)
|
|
|
|
stack[++sp] = get_context_reg(csw, context, opcode - DW_OP_breg0)
|
|
|
|
stack[++sp] = get_context_reg(module, csw, context, opcode - DW_OP_breg0)
|
|
|
|
+ dwarf2_leb128_as_signed(&ctx);
|
|
|
|
+ dwarf2_leb128_as_signed(&ctx);
|
|
|
|
else switch (opcode)
|
|
|
|
else switch (opcode)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -3159,12 +3159,12 @@ static ULONG_PTR eval_expression(const struct module* module, struct cpu_stack_w
|
|
|
|
stack[++sp] = dwarf2_parse_augmentation_ptr(&ctx, tmp);
|
|
|
|
stack[++sp] = dwarf2_parse_augmentation_ptr(&ctx, tmp);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case DW_OP_regx:
|
|
|
|
case DW_OP_regx:
|
|
|
|
stack[++sp] = get_context_reg(csw, context, dwarf2_leb128_as_unsigned(&ctx));
|
|
|
|
stack[++sp] = get_context_reg(module, csw, context, dwarf2_leb128_as_unsigned(&ctx));
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case DW_OP_bregx:
|
|
|
|
case DW_OP_bregx:
|
|
|
|
reg = dwarf2_leb128_as_unsigned(&ctx);
|
|
|
|
reg = dwarf2_leb128_as_unsigned(&ctx);
|
|
|
|
tmp = dwarf2_leb128_as_signed(&ctx);
|
|
|
|
tmp = dwarf2_leb128_as_signed(&ctx);
|
|
|
|
stack[++sp] = get_context_reg(csw, context, reg) + tmp;
|
|
|
|
stack[++sp] = get_context_reg(module, csw, context, reg) + tmp;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case DW_OP_deref_size:
|
|
|
|
case DW_OP_deref_size:
|
|
|
|
sz = dwarf2_parse_byte(&ctx);
|
|
|
|
sz = dwarf2_parse_byte(&ctx);
|
|
|
@ -3211,7 +3211,7 @@ static void apply_frame_state(const struct module* module, struct cpu_stack_walk
|
|
|
|
*cfa = eval_expression(module, csw, (const unsigned char*)state->cfa_offset, context);
|
|
|
|
*cfa = eval_expression(module, csw, (const unsigned char*)state->cfa_offset, context);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
*cfa = get_context_reg(csw, context, state->cfa_reg) + state->cfa_offset;
|
|
|
|
*cfa = get_context_reg(module, csw, context, state->cfa_reg) + state->cfa_offset;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!*cfa) return;
|
|
|
|
if (!*cfa) return;
|
|
|
@ -3225,18 +3225,18 @@ static void apply_frame_state(const struct module* module, struct cpu_stack_walk
|
|
|
|
case RULE_SAME:
|
|
|
|
case RULE_SAME:
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case RULE_CFA_OFFSET:
|
|
|
|
case RULE_CFA_OFFSET:
|
|
|
|
set_context_reg(csw, &new_context, i, *cfa + state->regs[i], TRUE);
|
|
|
|
set_context_reg(module, csw, &new_context, i, *cfa + state->regs[i], TRUE);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case RULE_OTHER_REG:
|
|
|
|
case RULE_OTHER_REG:
|
|
|
|
copy_context_reg(csw, &new_context, i, context, state->regs[i]);
|
|
|
|
copy_context_reg(module, csw, &new_context, i, context, state->regs[i]);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case RULE_EXPRESSION:
|
|
|
|
case RULE_EXPRESSION:
|
|
|
|
value = eval_expression(module, csw, (const unsigned char*)state->regs[i], context);
|
|
|
|
value = eval_expression(module, csw, (const unsigned char*)state->regs[i], context);
|
|
|
|
set_context_reg(csw, &new_context, i, value, TRUE);
|
|
|
|
set_context_reg(module, csw, &new_context, i, value, TRUE);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case RULE_VAL_EXPRESSION:
|
|
|
|
case RULE_VAL_EXPRESSION:
|
|
|
|
value = eval_expression(module, csw, (const unsigned char*)state->regs[i], context);
|
|
|
|
value = eval_expression(module, csw, (const unsigned char*)state->regs[i], context);
|
|
|
|
set_context_reg(csw, &new_context, i, value, FALSE);
|
|
|
|
set_context_reg(module, csw, &new_context, i, value, FALSE);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -3288,11 +3288,11 @@ BOOL dwarf2_virtual_unwind(struct cpu_stack_walk *csw, ULONG_PTR ip,
|
|
|
|
|
|
|
|
|
|
|
|
TRACE("function %lx/%lx code_align %lu data_align %ld retaddr %s\n",
|
|
|
|
TRACE("function %lx/%lx code_align %lu data_align %ld retaddr %s\n",
|
|
|
|
ip, info.ip, info.code_align, info.data_align,
|
|
|
|
ip, info.ip, info.code_align, info.data_align,
|
|
|
|
csw->cpu->fetch_regname(csw->cpu->map_dwarf_register(info.retaddr_reg, TRUE)));
|
|
|
|
csw->cpu->fetch_regname(csw->cpu->map_dwarf_register(info.retaddr_reg, pair.effective, TRUE)));
|
|
|
|
|
|
|
|
|
|
|
|
/* if at very beginning of function, return and use default unwinder */
|
|
|
|
/* if at very beginning of function, return and use default unwinder */
|
|
|
|
if (ip == info.ip) return FALSE;
|
|
|
|
if (ip == info.ip) return FALSE;
|
|
|
|
execute_cfa_instructions(&cie_ctx, ip, &info);
|
|
|
|
execute_cfa_instructions(pair.effective, &cie_ctx, ip, &info);
|
|
|
|
|
|
|
|
|
|
|
|
if (info.aug_z_format) /* get length of augmentation data */
|
|
|
|
if (info.aug_z_format) /* get length of augmentation data */
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -3303,7 +3303,7 @@ BOOL dwarf2_virtual_unwind(struct cpu_stack_walk *csw, ULONG_PTR ip,
|
|
|
|
dwarf2_parse_augmentation_ptr(&fde_ctx, info.lsda_encoding); /* handler_data */
|
|
|
|
dwarf2_parse_augmentation_ptr(&fde_ctx, info.lsda_encoding); /* handler_data */
|
|
|
|
if (end) fde_ctx.data = end;
|
|
|
|
if (end) fde_ctx.data = end;
|
|
|
|
|
|
|
|
|
|
|
|
execute_cfa_instructions(&fde_ctx, ip, &info);
|
|
|
|
execute_cfa_instructions(pair.effective, &fde_ctx, ip, &info);
|
|
|
|
|
|
|
|
|
|
|
|
/* if there is no information about retaddr, use default unwinder */
|
|
|
|
/* if there is no information about retaddr, use default unwinder */
|
|
|
|
if (info.state.rules[info.retaddr_reg] == RULE_UNSET) return FALSE;
|
|
|
|
if (info.state.rules[info.retaddr_reg] == RULE_UNSET) return FALSE;
|
|
|
@ -3356,7 +3356,7 @@ static void dwarf2_location_compute(struct process* pcs,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
do_compute:
|
|
|
|
do_compute:
|
|
|
|
/* now get the variable */
|
|
|
|
/* now get the variable */
|
|
|
|
err = compute_location(&lctx, loc, pcs->handle, &frame);
|
|
|
|
err = compute_location(modfmt->module, &lctx, loc, pcs->handle, &frame);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case loc_register:
|
|
|
|
case loc_register:
|
|
|
|
case loc_regrel:
|
|
|
|
case loc_regrel:
|
|
|
|