The following series implements: - better support for some compilation units descriptions - DW_OP_call_frame_cfa implementation: gcc when emitting dwarf4, heavily uses this for describing vars/parameters. - silencing some unsupported yet elements - now letting dbghelp, **by default**, load compilations unit with dwarf 2, 3 or 4 debug information - by option, let wine be compiled with dwarf4 debug information (default is still dwarf 2) (using DEBUGFORMAT=dwarf-4 and CROSSDEBUG=dwarf-4 as configure options)
Changes from v2 - more silencing - reordered patch order for having configure bits at the end - added support for local variables with constant values - simplified a bit call_frame_cfa handling
Last patch requires re-running autoconf before applying.
A+
---
Eric Pouech (12): dbghelp/dwarf: Fixed a couple of parent/child mismatch dbghelp/dwarf: Added support for partial compilation units dbghelp/dwarf: added support for DW_TAG_imported_unit dbghelp/dwarf: pass cuhead to loc_compute_frame dbghelp/dwarf: split dwarf2_virtual_unwind into two functions dbghelp/dwarf: Added support for OP_call_frame_cfa dbghelp/dwarf: Silence a couple of dwarf DIE's tag in load_one_debug_entry dbghelp/dwarf: downgrade FIXME into WARN for empty range dbghelp/dwarf: added support for local variables with constant values dbghelp/dwarf: fix incorrect WARN dbghelp/dwarf: Bumping max supported version (by default) up to 4 configure: allow picking up a dedicated dwarf version from command line
configure | 168 ++++++++++++++++++++++---- configure.ac | 15 ++- dlls/dbghelp/dbghelp_private.h | 4 + dlls/dbghelp/dwarf.c | 212 +++++++++++++++++++++++---------- dlls/dbghelp/symbol.c | 36 ++++++ 5 files changed, 347 insertions(+), 88 deletions(-)
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 192dbf59814..731a7136601 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -1688,7 +1688,7 @@ static struct symt* dwarf2_parse_udt_type(dwarf2_debug_info_t* di, switch (child->abbrev->tag) { case DW_TAG_array_type: - dwarf2_parse_array_type(di); + dwarf2_parse_array_type(child); break; case DW_TAG_member: /* FIXME: should I follow the sibling stuff ?? */ @@ -1705,7 +1705,7 @@ static struct symt* dwarf2_parse_udt_type(dwarf2_debug_info_t* di, dwarf2_parse_const_type(child); break; case DW_TAG_volatile_type: - dwarf2_parse_volatile_type(di); + dwarf2_parse_volatile_type(child); break; case DW_TAG_pointer_type: dwarf2_parse_pointer_type(child); @@ -2205,10 +2205,10 @@ static struct symt* dwarf2_parse_subprogram(dwarf2_debug_info_t* di) dwarf2_parse_inlined_subroutine(&subpgm, NULL, child); break; case DW_TAG_pointer_type: - dwarf2_parse_pointer_type(di); + dwarf2_parse_pointer_type(child); break; case DW_TAG_const_type: - dwarf2_parse_const_type(di); + dwarf2_parse_const_type(child); break; case DW_TAG_subprogram: /* FIXME: likely a declaration (to be checked)
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 731a7136601..13423c93515 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -1147,7 +1147,7 @@ static const char* dwarf2_get_cpp_name(dwarf2_debug_info_t* di, const char* name struct attribute diname; struct attribute spec;
- if (di->abbrev->tag == DW_TAG_compile_unit) return name; + if (di->abbrev->tag == DW_TAG_compile_unit || di->abbrev->tag == DW_TAG_partial_unit) return name;
/* if the di is a definition, but has also a (previous) declaration, then scope must * be gotten from declaration not definition @@ -2718,7 +2718,7 @@ static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_context_t* ctx) ctx->status = UNIT_BEINGLOADED; if (dwarf2_read_one_debug_info(ctx, &cu_ctx, NULL, &di)) { - if (di->abbrev->tag == DW_TAG_compile_unit) + if (di->abbrev->tag == DW_TAG_compile_unit || di->abbrev->tag == DW_TAG_partial_unit) { struct attribute name; struct vector* children; @@ -2754,7 +2754,7 @@ static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_context_t* ctx) ctx->status = UNIT_LOADED; ret = TRUE; } - else FIXME("Should have a compilation unit here\n"); + else FIXME("Should have a compilation unit here %lu\n", di->abbrev->tag); } if (ctx->status == UNIT_BEINGLOADED) ctx->status = UNIT_LOADED_FAIL; return ret;
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 13423c93515..785f6651f11 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -2305,6 +2305,24 @@ static void dwarf2_parse_namespace(dwarf2_debug_info_t* di) } }
+static void dwarf2_parse_imported_unit(dwarf2_debug_info_t* di) +{ + struct attribute imp; + + if (di->symt) return; + + TRACE("%s\n", dwarf2_debug_di(di)); + + if (dwarf2_find_attribute(di, DW_AT_import, &imp)) + { + dwarf2_debug_info_t* jmp = dwarf2_jump_to_debug_info(&imp); + if (jmp) di->symt = jmp->symt; + else FIXME("Couldn't load imported CU\n"); + } + else + FIXME("Couldn't find import attribute\n"); +} + static void dwarf2_load_one_entry(dwarf2_debug_info_t* di) { switch (di->abbrev->tag) @@ -2373,6 +2391,9 @@ static void dwarf2_load_one_entry(dwarf2_debug_info_t* di) case DW_TAG_subrange_type: dwarf2_parse_subrange_type(di); break; + case DW_TAG_imported_unit: + dwarf2_parse_imported_unit(di); + break; /* silence a couple of C++ defines */ case DW_TAG_imported_module: case DW_TAG_imported_declaration:
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 785f6651f11..5f4ff8ad5d3 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -2821,20 +2821,15 @@ static const dwarf2_cuhead_t* get_cuhead_from_func(const struct symt_function* f static enum location_error loc_compute_frame(struct process* pcs, const struct module_format* modfmt, const struct symt_function* func, - DWORD_PTR ip, struct location* frame) + DWORD_PTR ip, const dwarf2_cuhead_t* head, + struct location* frame) { struct symt** psym = NULL; struct location* pframe; dwarf2_traverse_context_t lctx; enum location_error err; unsigned int i; - const dwarf2_cuhead_t* head = get_cuhead_from_func(func);
- if (!head) - { - FIXME("Shouldn't happen\n"); - return loc_err_internal; - } for (i=0; i<vector_length(&func->vchildren); i++) { psym = vector_at(&func->vchildren, i); @@ -3663,7 +3658,7 @@ static void dwarf2_location_compute(struct process* pcs, /* instruction pointer relative to compiland's start */ ip = pcs->ctx_frame.InstructionOffset - ((struct symt_compiland*)func->container)->address;
- if ((err = loc_compute_frame(pcs, modfmt, func, ip, &frame)) == 0) + if ((err = loc_compute_frame(pcs, modfmt, func, ip, head, &frame)) == 0) { switch (loc->kind) {
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 73 +++++++++++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 31 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 5f4ff8ad5d3..4edba930698 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -3568,41 +3568,30 @@ static void apply_frame_state(const struct module* module, struct cpu_stack_walk *context = new_context; }
-/*********************************************************************** - * dwarf2_virtual_unwind - * - */ -BOOL dwarf2_virtual_unwind(struct cpu_stack_walk *csw, ULONG_PTR ip, - union ctx *context, DWORD64 *cfa) +static BOOL dwarf2_fetch_frame_info(struct module* module, struct cpu* cpu, LONG_PTR ip, struct frame_info* info) { - struct module_pair pair; - struct frame_info info; dwarf2_traverse_context_t cie_ctx, fde_ctx; struct module_format* modfmt; const unsigned char* end; DWORD_PTR delta;
- if (!(pair.pcs = process_find_by_handle(csw->hProcess)) || - !(pair.requested = module_find_by_addr(pair.pcs, ip, DMT_UNKNOWN)) || - !module_get_debug(&pair)) - return FALSE; - modfmt = pair.effective->format_info[DFI_DWARF]; + modfmt = module->format_info[DFI_DWARF]; if (!modfmt) return FALSE; - memset(&info, 0, sizeof(info)); + memset(info, 0, sizeof(*info)); fde_ctx.data = modfmt->u.dwarf2_info->eh_frame.address; fde_ctx.end_data = fde_ctx.data + modfmt->u.dwarf2_info->eh_frame.size; /* let offsets relative to the eh_frame sections be correctly computed, as we'll map * in this process the IMAGE section at a different address as the one expected by * the image */ - delta = pair.effective->module.BaseOfImage + modfmt->u.dwarf2_info->eh_frame.rva - + delta = module->module.BaseOfImage + modfmt->u.dwarf2_info->eh_frame.rva - (DWORD_PTR)modfmt->u.dwarf2_info->eh_frame.address; - if (!dwarf2_get_cie(ip, pair.effective, delta, &fde_ctx, &cie_ctx, &info, TRUE)) + if (!dwarf2_get_cie(ip, module, delta, &fde_ctx, &cie_ctx, info, TRUE)) { fde_ctx.data = modfmt->u.dwarf2_info->debug_frame.address; fde_ctx.end_data = fde_ctx.data + modfmt->u.dwarf2_info->debug_frame.size; - delta = pair.effective->reloc_delta; - if (!dwarf2_get_cie(ip, pair.effective, delta, &fde_ctx, &cie_ctx, &info, FALSE)) + delta = module->reloc_delta; + if (!dwarf2_get_cie(ip, module, delta, &fde_ctx, &cie_ctx, info, FALSE)) { TRACE("Couldn't find information for %lx\n", ip); return FALSE; @@ -3610,23 +3599,45 @@ 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", - ip, info.ip, info.code_align, info.data_align, - 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 (ip == info.ip) return FALSE; - execute_cfa_instructions(pair.effective, &cie_ctx, ip, &info); + ip, info->ip, info->code_align, info->data_align, + cpu->fetch_regname(cpu->map_dwarf_register(info->retaddr_reg, module, TRUE)));
- if (info.aug_z_format) /* get length of augmentation data */ + if (ip != info->ip) { - ULONG_PTR len = dwarf2_leb128_as_unsigned(&fde_ctx); - end = fde_ctx.data + len; + execute_cfa_instructions(module, &cie_ctx, ip, info); + + if (info->aug_z_format) /* get length of augmentation data */ + { + ULONG_PTR len = dwarf2_leb128_as_unsigned(&fde_ctx); + end = fde_ctx.data + len; + } + else end = NULL; + dwarf2_parse_augmentation_ptr(&fde_ctx, info->lsda_encoding, modfmt->u.dwarf2_info->word_size); /* handler_data */ + if (end) fde_ctx.data = end; + + execute_cfa_instructions(module, &fde_ctx, ip, info); } - else end = NULL; - dwarf2_parse_augmentation_ptr(&fde_ctx, info.lsda_encoding, modfmt->u.dwarf2_info->word_size); /* handler_data */ - if (end) fde_ctx.data = end; + return TRUE; +}
- execute_cfa_instructions(pair.effective, &fde_ctx, ip, &info); +/*********************************************************************** + * dwarf2_virtual_unwind + * + */ +BOOL dwarf2_virtual_unwind(struct cpu_stack_walk *csw, ULONG_PTR ip, + union ctx *context, DWORD64 *cfa) +{ + struct module_pair pair; + struct frame_info info; + + if (!(pair.pcs = process_find_by_handle(csw->hProcess)) || + !(pair.requested = module_find_by_addr(pair.pcs, ip, DMT_UNKNOWN)) || + !module_get_debug(&pair)) + return FALSE; + if (!dwarf2_fetch_frame_info(pair.effective, csw->cpu, ip, &info)) return FALSE; + + /* if at very beginning of function, return and use default unwinder */ + if (ip == info.ip) return FALSE;
/* if there is no information about retaddr, use default unwinder */ if (info.state.rules[info.retaddr_reg] == RULE_UNSET) return FALSE;
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- 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,
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 9e0df966b3c..0397ffe90b2 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -2400,9 +2400,13 @@ static void dwarf2_load_one_entry(dwarf2_debug_info_t* di) case DW_TAG_imported_unit: dwarf2_parse_imported_unit(di); break; - /* silence a couple of C++ defines */ + /* keep it silent until we need DW_OP_call_xxx support */ + case DW_TAG_dwarf_procedure: + /* silence a couple of non-C language defines (mainly C++ but others too) */ case DW_TAG_imported_module: case DW_TAG_imported_declaration: + case DW_TAG_interface_type: + case DW_TAG_module: case DW_TAG_ptr_to_member_type: break; default:
it happens to be generated for some inline functions, that we badly support yet
--- dlls/dbghelp/dwarf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 0397ffe90b2..f05186eb9c0 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -1236,7 +1236,7 @@ static BOOL dwarf2_read_range(dwarf2_parse_context_t* ctx, const dwarf2_debug_in if (high > *phigh) *phigh = high; } if (*plow == UMAX || *phigh == 0) {FIXME("no entry found\n"); return FALSE;} - if (*plow == *phigh) {FIXME("entry found, but low=high\n"); return FALSE;} + if (*plow == *phigh) {WARN("entry found, but low=high %lx %lx\n", low, high); return FALSE;}
return TRUE; } @@ -2002,7 +2002,7 @@ static void dwarf2_parse_inlined_subroutine(dwarf2_subprogram_t* subpgm,
if (!dwarf2_read_range(subpgm->ctx, di, &low_pc, &high_pc)) { - FIXME("cannot read range\n"); + WARN("cannot read range\n"); return; }
--- dlls/dbghelp/dbghelp_private.h | 4 ++++ dlls/dbghelp/dwarf.c | 15 +++++++++++---- dlls/dbghelp/symbol.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 4 deletions(-)
diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index 2d4efafd041..0587ce13914 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -756,6 +756,10 @@ extern struct symt_data* enum DataKind dt, const struct location* loc, struct symt_block* block, struct symt* type, const char* name) DECLSPEC_HIDDEN; +extern struct symt_data* + symt_add_func_constant(struct module* module, + struct symt_function* func, struct symt_block* block, + struct symt* type, const char* name, VARIANT* v) DECLSPEC_HIDDEN; extern struct symt_block* symt_open_func_block(struct module* module, struct symt_function* func, diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index f05186eb9c0..33c3b7fc467 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -1880,8 +1880,7 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, else if (dwarf2_find_attribute(di, DW_AT_const_value, &value)) { VARIANT v; - if (subpgm->func) WARN("Unsupported constant %s in function\n", debugstr_a(name.u.string)); - if (is_pmt) FIXME("Unsupported constant (parameter) %s in function\n", debugstr_a(name.u.string)); + switch (value.form) { case DW_FORM_data1: @@ -1936,8 +1935,16 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, debugstr_a(name.u.string), value.form); v.n1.n2.vt = VT_EMPTY; } - di->symt = &symt_new_constant(subpgm->ctx->module_ctx->module, subpgm->ctx->compiland, - name.u.string, param_type, &v)->symt; + if (subpgm->func) + { + if (is_pmt) FIXME("Unsupported constant (parameter) %s in function '%s'\n", debugstr_a(name.u.string), subpgm->func->hash_elt.name); + di->symt = &symt_add_func_constant(subpgm->ctx->module_ctx->module, + subpgm->func, block, + param_type, name.u.string, &v)->symt; + } + else + di->symt = &symt_new_constant(subpgm->ctx->module_ctx->module, subpgm->ctx->compiland, + name.u.string, param_type, &v)->symt; } else { diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c index 29376812653..467a376b574 100644 --- a/dlls/dbghelp/symbol.c +++ b/dlls/dbghelp/symbol.c @@ -409,6 +409,42 @@ struct symt_data* symt_add_func_local(struct module* module, return locsym; }
+/****************************************************************** + * symt_add_func_local + * + * Adds a new (local) constant to a given function + */ +struct symt_data* symt_add_func_constant(struct module* module, + struct symt_function* func, + struct symt_block* block, + struct symt* type, const char* name, + VARIANT* v) +{ + struct symt_data* locsym; + struct symt** p; + + TRACE_(dbghelp_symt)("Adding local constant (%s:%s): %s %p\n", + debugstr_w(module->modulename), func->hash_elt.name, + name, type); + + assert(func); + assert(func->symt.tag == SymTagFunction); + + locsym = pool_alloc(&module->pool, sizeof(*locsym)); + locsym->symt.tag = SymTagData; + locsym->hash_elt.name = pool_strdup(&module->pool, name); + locsym->hash_elt.next = NULL; + locsym->kind = DataIsConstant; + locsym->container = block ? &block->symt : &func->symt; + locsym->type = type; + locsym->u.value = *v; + if (block) + p = vector_add(&block->vchildren, &module->pool); + else + p = vector_add(&func->vchildren, &module->pool); + *p = &locsym->symt; + return locsym; +}
struct symt_block* symt_open_func_block(struct module* module, struct symt_function* func,
--- dlls/dbghelp/dwarf.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 33c3b7fc467..51789f8591e 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -1948,18 +1948,22 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, } else { - /* variable has been optimized away... report anyway */ - loc.kind = loc_error; - loc.reg = loc_err_no_location; if (subpgm->func) { + /* local variable has been optimized away... report anyway */ + loc.kind = loc_error; + loc.reg = loc_err_no_location; symt_add_func_local(subpgm->ctx->module_ctx->module, subpgm->func, is_pmt ? DataIsParam : DataIsLocal, &loc, block, param_type, name.u.string); } else { - WARN("dropping global variable %s which has been optimized away\n", debugstr_a(name.u.string)); + struct attribute is_decl; + /* only warn when di doesn't represent a declaration */ + if (!dwarf2_find_attribute(di, DW_AT_declaration, &is_decl) || + !is_decl.u.uvalue || is_decl.gotten_from != attr_direct) + WARN("dropping global variable %s which has been optimized away\n", debugstr_a(name.u.string)); } } if (is_pmt && subpgm->func && symt_check_tag(subpgm->func->type, SymTagFunctionType))
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 51789f8591e..430544196c5 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -2710,18 +2710,14 @@ static BOOL dwarf2_parse_compilation_unit_head(dwarf2_parse_context_t* ctx, if (max_supported_dwarf_version == 0) { char* env = getenv("DBGHELP_DWARF_VERSION"); - LONG v = env ? atol(env) : 2; - max_supported_dwarf_version = (v >= 2 && v <= 4) ? v : 2; + LONG v = env ? atol(env) : 4; + max_supported_dwarf_version = (v >= 2 && v <= 4) ? v : 4; }
if (ctx->head.version < 2 || ctx->head.version > max_supported_dwarf_version) { - if (max_supported_dwarf_version > 2) - WARN("%u DWARF version unsupported. Wine dbghelp only support DWARF 2 up to %u.\n", - ctx->head.version, max_supported_dwarf_version); - else - WARN("%u DWARF version unsupported. Wine dbghelp only support DWARF 2.\n", - ctx->head.version); + WARN("DWARF version %d isn't supported. Wine dbghelp only supports DWARF 2 up to %u.\n", + ctx->head.version, max_supported_dwarf_version); return FALSE; }
- added support in CROSSDEBUG for choosing which dwarf version is used for cross compiling Wine - added DEBUGFORMAT option to pick dwarf version for regular compilation
Default for both is still 2
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- configure | 168 +++++++++++++++++++++++++++++++++++++++++++++++++++------- configure.ac | 15 +++-- 2 files changed, 158 insertions(+), 25 deletions(-)
diff --git a/configure b/configure index 7c2f53f5655..a984df5fa15 100755 --- a/configure +++ b/configure @@ -631,6 +631,7 @@ RT_LIBS POLL_LIBS TOOLSEXT MSVCRTFLAGS +DEBUGFORMAT EXTRACFLAGS VKD3D_SHADER_LIBS VKD3D_SHADER_CFLAGS @@ -7013,7 +7014,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -7059,7 +7060,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -7083,7 +7084,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -7128,7 +7129,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -7152,7 +7153,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -10491,14 +10492,138 @@ fi ;; then for ac_flag in $CROSSCFLAGS; do case $ac_flag in - -gdwarf*) CROSSDEBUG=dwarf ;; + -gdwarf*) CROSSDEBUG=$ac_flag ;; -gcodeview) CROSSDEBUG=pdb ;; -g) CROSSDEBUG=${CROSSDEBUG:-dwarf} ;; esac done fi case $CROSSDEBUG in - *dwarf) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the cross-compiler supports -gdwarf-2" >&5 + *dwarf-3) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the cross-compiler supports -gdwarf-3" >&5 +$as_echo_n "checking whether the cross-compiler supports -gdwarf-3... " >&6; } +if ${ac_cv_crosscflags__gdwarf_3+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_wine_try_cflags_saved=$CFLAGS +ac_wine_try_cflags_saved_cc=$CC +ac_wine_try_cflags_saved_exeext=$ac_exeext +CFLAGS="$CFLAGS $EXTRACROSSCFLAGS -nostartfiles -nodefaultlibs -gdwarf-3" +CC="$CROSSCC" +ac_exeext=".exe" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int __cdecl mainCRTStartup(void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_crosscflags__gdwarf_3=yes +else + ac_cv_crosscflags__gdwarf_3=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +CFLAGS=$ac_wine_try_cflags_saved +CC=$ac_wine_try_cflags_saved_cc +ac_exeext=$ac_wine_try_cflags_saved_exeext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_crosscflags__gdwarf_3" >&5 +$as_echo "$ac_cv_crosscflags__gdwarf_3" >&6; } +if test "x$ac_cv_crosscflags__gdwarf_3" = xyes; then : + EXTRACROSSCFLAGS="$EXTRACROSSCFLAGS -gdwarf-3" +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the cross-compiler supports -gstrict-dwarf" >&5 +$as_echo_n "checking whether the cross-compiler supports -gstrict-dwarf... " >&6; } +if ${ac_cv_crosscflags__gstrict_dwarf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_wine_try_cflags_saved=$CFLAGS +ac_wine_try_cflags_saved_cc=$CC +ac_wine_try_cflags_saved_exeext=$ac_exeext +CFLAGS="$CFLAGS $EXTRACROSSCFLAGS -nostartfiles -nodefaultlibs -gstrict-dwarf" +CC="$CROSSCC" +ac_exeext=".exe" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int __cdecl mainCRTStartup(void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_crosscflags__gstrict_dwarf=yes +else + ac_cv_crosscflags__gstrict_dwarf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +CFLAGS=$ac_wine_try_cflags_saved +CC=$ac_wine_try_cflags_saved_cc +ac_exeext=$ac_wine_try_cflags_saved_exeext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_crosscflags__gstrict_dwarf" >&5 +$as_echo "$ac_cv_crosscflags__gstrict_dwarf" >&6; } +if test "x$ac_cv_crosscflags__gstrict_dwarf" = xyes; then : + EXTRACROSSCFLAGS="$EXTRACROSSCFLAGS -gstrict-dwarf" +fi ;; + *dwarf-4) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the cross-compiler supports -gdwarf-4" >&5 +$as_echo_n "checking whether the cross-compiler supports -gdwarf-4... " >&6; } +if ${ac_cv_crosscflags__gdwarf_4+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_wine_try_cflags_saved=$CFLAGS +ac_wine_try_cflags_saved_cc=$CC +ac_wine_try_cflags_saved_exeext=$ac_exeext +CFLAGS="$CFLAGS $EXTRACROSSCFLAGS -nostartfiles -nodefaultlibs -gdwarf-4" +CC="$CROSSCC" +ac_exeext=".exe" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int __cdecl mainCRTStartup(void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_crosscflags__gdwarf_4=yes +else + ac_cv_crosscflags__gdwarf_4=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +CFLAGS=$ac_wine_try_cflags_saved +CC=$ac_wine_try_cflags_saved_cc +ac_exeext=$ac_wine_try_cflags_saved_exeext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_crosscflags__gdwarf_4" >&5 +$as_echo "$ac_cv_crosscflags__gdwarf_4" >&6; } +if test "x$ac_cv_crosscflags__gdwarf_4" = xyes; then : + EXTRACROSSCFLAGS="$EXTRACROSSCFLAGS -gdwarf-4" +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the cross-compiler supports -gstrict-dwarf" >&5 +$as_echo_n "checking whether the cross-compiler supports -gstrict-dwarf... " >&6; } +if ${ac_cv_crosscflags__gstrict_dwarf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_wine_try_cflags_saved=$CFLAGS +ac_wine_try_cflags_saved_cc=$CC +ac_wine_try_cflags_saved_exeext=$ac_exeext +CFLAGS="$CFLAGS $EXTRACROSSCFLAGS -nostartfiles -nodefaultlibs -gstrict-dwarf" +CC="$CROSSCC" +ac_exeext=".exe" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int __cdecl mainCRTStartup(void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_crosscflags__gstrict_dwarf=yes +else + ac_cv_crosscflags__gstrict_dwarf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +CFLAGS=$ac_wine_try_cflags_saved +CC=$ac_wine_try_cflags_saved_cc +ac_exeext=$ac_wine_try_cflags_saved_exeext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_crosscflags__gstrict_dwarf" >&5 +$as_echo "$ac_cv_crosscflags__gstrict_dwarf" >&6; } +if test "x$ac_cv_crosscflags__gstrict_dwarf" = xyes; then : + EXTRACROSSCFLAGS="$EXTRACROSSCFLAGS -gstrict-dwarf" +fi ;; + *dwarf|*dwarf-2) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the cross-compiler supports -gdwarf-2" >&5 $as_echo_n "checking whether the cross-compiler supports -gdwarf-2... " >&6; } if ${ac_cv_crosscflags__gdwarf_2+:} false; then : $as_echo_n "(cached) " >&6 @@ -10529,7 +10654,7 @@ $as_echo "$ac_cv_crosscflags__gdwarf_2" >&6; } if test "x$ac_cv_crosscflags__gdwarf_2" = xyes; then : EXTRACROSSCFLAGS="$EXTRACROSSCFLAGS -gdwarf-2" fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the cross-compiler supports -gstrict-dwarf" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the cross-compiler supports -gstrict-dwarf" >&5 $as_echo_n "checking whether the cross-compiler supports -gstrict-dwarf... " >&6; } if ${ac_cv_crosscflags__gstrict_dwarf+:} false; then : $as_echo_n "(cached) " >&6 @@ -10560,7 +10685,7 @@ $as_echo "$ac_cv_crosscflags__gstrict_dwarf" >&6; } if test "x$ac_cv_crosscflags__gstrict_dwarf" = xyes; then : EXTRACROSSCFLAGS="$EXTRACROSSCFLAGS -gstrict-dwarf" fi ;; - pdb) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the cross-compiler supports -gcodeview" >&5 + pdb) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the cross-compiler supports -gcodeview" >&5 $as_echo_n "checking whether the cross-compiler supports -gcodeview... " >&6; } if ${ac_cv_crosscflags__gcodeview+:} false; then : $as_echo_n "(cached) " >&6 @@ -17543,32 +17668,35 @@ $as_echo "$wine_cv_64bit_compare_swap" >&6; } *) EXTRACFLAGS="$EXTRACFLAGS $wine_cv_64bit_compare_swap" ;; esac
- for ac_flag in $CFLAGS; do + + for ac_flag in $CFLAGS; do case $ac_flag in - -g) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports -gdwarf-2" >&5 -$as_echo_n "checking whether the compiler supports -gdwarf-2... " >&6; } -if ${ac_cv_cflags__gdwarf_2+:} false; then : + -g) as_ac_var=`$as_echo "ac_cv_cflags_-g${DEBUGFORMAT:-dwarf-2}" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports -g${DEBUGFORMAT:-dwarf-2}" >&5 +$as_echo_n "checking whether the compiler supports -g${DEBUGFORMAT:-dwarf-2}... " >&6; } +if eval ${$as_ac_var+:} false; then : $as_echo_n "(cached) " >&6 else ac_wine_try_cflags_saved=$CFLAGS -CFLAGS="$CFLAGS -gdwarf-2" +CFLAGS="$CFLAGS -g${DEBUGFORMAT:-dwarf-2}" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main(int argc, char **argv) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_cflags__gdwarf_2=yes + eval "$as_ac_var=yes" else - ac_cv_cflags__gdwarf_2=no + eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CFLAGS=$ac_wine_try_cflags_saved fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cflags__gdwarf_2" >&5 -$as_echo "$ac_cv_cflags__gdwarf_2" >&6; } -if test "x$ac_cv_cflags__gdwarf_2" = xyes; then : - EXTRACFLAGS="$EXTRACFLAGS -gdwarf-2" +eval ac_res=$$as_ac_var + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test "x$"$as_ac_var"" = x"yes"; then : + EXTRACFLAGS="$EXTRACFLAGS -g${DEBUGFORMAT:-dwarf-2}" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports -gstrict-dwarf" >&5 $as_echo_n "checking whether the compiler supports -gstrict-dwarf... " >&6; } diff --git a/configure.ac b/configure.ac index c0a126293c4..a019b4ac2d6 100644 --- a/configure.ac +++ b/configure.ac @@ -1036,16 +1036,20 @@ then then for ac_flag in $CROSSCFLAGS; do case $ac_flag in - -gdwarf*) CROSSDEBUG=dwarf ;; + -gdwarf*) CROSSDEBUG=$ac_flag ;; -gcodeview) CROSSDEBUG=pdb ;; -g) CROSSDEBUG=${CROSSDEBUG:-dwarf} ;; esac done fi case $CROSSDEBUG in - *dwarf) WINE_TRY_CROSSCFLAGS([-gdwarf-2]) - WINE_TRY_CROSSCFLAGS([-gstrict-dwarf]) ;; - pdb) WINE_TRY_CROSSCFLAGS([-gcodeview]) ;; + *dwarf-3) WINE_TRY_CROSSCFLAGS([-gdwarf-3]) + WINE_TRY_CROSSCFLAGS([-gstrict-dwarf]) ;; + *dwarf-4) WINE_TRY_CROSSCFLAGS([-gdwarf-4]) + WINE_TRY_CROSSCFLAGS([-gstrict-dwarf]) ;; + *dwarf|*dwarf-2) WINE_TRY_CROSSCFLAGS([-gdwarf-2]) + WINE_TRY_CROSSCFLAGS([-gstrict-dwarf]) ;; + pdb) WINE_TRY_CROSSCFLAGS([-gcodeview]) ;; esac
WINE_TRY_CROSSCFLAGS([-fexcess-precision=standard],[AC_SUBST(EXCESS_PRECISION_CFLAGS,"-fexcess-precision=standard")]) @@ -2040,9 +2044,10 @@ char*f(const char *h,char n) {return strchr(h,n);}]])],[ac_cv_c_logicalop_noisy= esac
dnl Default to dwarf-2 debug info + AC_SUBST(DEBUGFORMAT) for ac_flag in $CFLAGS; do case $ac_flag in - -g) WINE_TRY_CFLAGS([-gdwarf-2]) + -g) WINE_TRY_CFLAGS([-g${DEBUGFORMAT:-dwarf-2}]) WINE_TRY_CFLAGS([-gstrict-dwarf]) ;; esac done