Eric Pouech : dbghelp/dwarf: Added support for OP_call_frame_cfa.
Alexandre Julliard
julliard at winehq.org
Mon Sep 27 15:21:43 CDT 2021
Module: wine
Branch: master
Commit: d8c9171c78548897e2ffeee6d8c34216bd79f229
URL: https://source.winehq.org/git/wine.git/?a=commit;h=d8c9171c78548897e2ffeee6d8c34216bd79f229
Author: Eric Pouech <eric.pouech at gmail.com>
Date: Sun Sep 26 14:47:01 2021 +0200
dbghelp/dwarf: Added support for OP_call_frame_cfa.
Signed-off-by: Eric Pouech <eric.pouech at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/dbghelp/dwarf.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 50 insertions(+), 2 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c
index 4edba930698..9e0df966b3c 100644
--- a/dlls/dbghelp/dwarf.c
+++ b/dlls/dbghelp/dwarf.c
@@ -234,6 +234,7 @@ struct dwarf2_module_info_s
#define loc_dwarf2_location_list (loc_user + 0)
#define loc_dwarf2_block (loc_user + 1)
+#define loc_dwarf2_frame_cfa (loc_user + 2)
/* forward declarations */
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 */
-
- if (xloc.u.block.size)
+ if (dw == DW_AT_frame_base && xloc.u.block.size == 1 && *xloc.u.block.ptr == DW_OP_call_frame_cfa)
+ {
+ 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;
enum location_error err;
@@ -2818,6 +2824,8 @@ static const dwarf2_cuhead_t* get_cuhead_from_func(const struct symt_function* f
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,
const struct module_format* modfmt,
const struct symt_function* func,
@@ -2858,6 +2866,9 @@ static enum location_error loc_compute_frame(struct process* pcs,
return loc_err_too_complex;
}
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:
WARN("Unsupported frame kind %d\n", pframe->kind);
return loc_err_internal;
@@ -3647,6 +3658,43 @@ BOOL dwarf2_virtual_unwind(struct cpu_stack_walk *csw, ULONG_PTR ip,
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,
const struct module_format* modfmt,
const struct symt_function* func,
More information about the wine-cvs
mailing list