dbghelp: Use AT_range attribute (for function, block... addresses) when AT_low_pc and AT_high_pc are not present.
This commit is contained in:
parent
52dc1bcd37
commit
60fbda43cb
|
@ -163,7 +163,7 @@ typedef struct dwarf2_section_s
|
|||
DWORD_PTR rva;
|
||||
} dwarf2_section_t;
|
||||
|
||||
enum dwarf2_sections {section_debug, section_string, section_abbrev, section_line, section_max};
|
||||
enum dwarf2_sections {section_debug, section_string, section_abbrev, section_line, section_ranges, section_max};
|
||||
|
||||
typedef struct dwarf2_traverse_context_s
|
||||
{
|
||||
|
@ -944,6 +944,61 @@ static struct symt* dwarf2_lookup_type(dwarf2_parse_context_t* ctx,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* dwarf2_read_range
|
||||
*
|
||||
* read a range for a given debug_info (either using AT_range attribute, in which
|
||||
* case we don't return all the details, or using AT_low_pc & AT_high_pc attributes)
|
||||
* in all cases, range is relative to beginning of compilation unit
|
||||
*/
|
||||
static BOOL dwarf2_read_range(dwarf2_parse_context_t* ctx, const dwarf2_debug_info_t* di,
|
||||
unsigned long* plow, unsigned long* phigh)
|
||||
{
|
||||
struct attribute range;
|
||||
|
||||
if (dwarf2_find_attribute(ctx, di, DW_AT_ranges, &range))
|
||||
{
|
||||
dwarf2_traverse_context_t traverse;
|
||||
unsigned long low, high;
|
||||
|
||||
traverse.data = ctx->sections[section_ranges].address + range.u.uvalue;
|
||||
traverse.end_data = ctx->sections[section_ranges].address +
|
||||
ctx->sections[section_ranges].size;
|
||||
traverse.word_size = ctx->module->format_info[DFI_DWARF]->u.dwarf2_info->word_size;
|
||||
|
||||
*plow = ULONG_MAX;
|
||||
*phigh = 0;
|
||||
while (traverse.data + 2 * traverse.word_size < traverse.end_data)
|
||||
{
|
||||
low = dwarf2_parse_addr(&traverse);
|
||||
high = dwarf2_parse_addr(&traverse);
|
||||
if (low == 0 && high == 0) break;
|
||||
if (low == ULONG_MAX) FIXME("unsupported yet (base address selection)\n");
|
||||
if (low < *plow) *plow = low;
|
||||
if (high > *phigh) *phigh = high;
|
||||
}
|
||||
if (*plow == ULONG_MAX || *phigh == 0) {FIXME("no entry found\n"); return FALSE;}
|
||||
if (*plow == *phigh) {FIXME("entry found, but low=high\n"); return FALSE;}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct attribute low_pc;
|
||||
struct attribute high_pc;
|
||||
|
||||
if (!dwarf2_find_attribute(ctx, di, DW_AT_low_pc, &low_pc) ||
|
||||
!dwarf2_find_attribute(ctx, di, DW_AT_high_pc, &high_pc))
|
||||
{
|
||||
FIXME("missing low or high value\n");
|
||||
return FALSE;
|
||||
}
|
||||
*plow = low_pc.u.uvalue;
|
||||
*phigh = high_pc.u.uvalue;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* dwarf2_read_one_debug_info
|
||||
*
|
||||
|
@ -1563,17 +1618,19 @@ static void dwarf2_parse_inlined_subroutine(dwarf2_subprogram_t* subpgm,
|
|||
const dwarf2_debug_info_t* di)
|
||||
{
|
||||
struct symt_block* block;
|
||||
struct attribute low_pc;
|
||||
struct attribute high_pc;
|
||||
unsigned long low_pc, high_pc;
|
||||
|
||||
TRACE("%s, for %s\n", dwarf2_debug_ctx(subpgm->ctx), dwarf2_debug_di(di));
|
||||
|
||||
if (!dwarf2_find_attribute(subpgm->ctx, di, DW_AT_low_pc, &low_pc)) low_pc.u.uvalue = 0;
|
||||
if (!dwarf2_find_attribute(subpgm->ctx, di, DW_AT_high_pc, &high_pc)) high_pc.u.uvalue = 0;
|
||||
if (!dwarf2_read_range(subpgm->ctx, di, &low_pc, &high_pc))
|
||||
{
|
||||
FIXME("cannot read range\n");
|
||||
return;
|
||||
}
|
||||
|
||||
block = symt_open_func_block(subpgm->ctx->module, subpgm->func, parent_block,
|
||||
subpgm->ctx->load_offset + low_pc.u.uvalue - subpgm->func->address,
|
||||
high_pc.u.uvalue - low_pc.u.uvalue);
|
||||
subpgm->ctx->load_offset + low_pc - subpgm->func->address,
|
||||
high_pc - low_pc);
|
||||
|
||||
if (di->abbrev->have_child) /** any interest to not have child ? */
|
||||
{
|
||||
|
@ -1614,19 +1671,19 @@ static void dwarf2_parse_subprogram_block(dwarf2_subprogram_t* subpgm,
|
|||
const dwarf2_debug_info_t* di)
|
||||
{
|
||||
struct symt_block* block;
|
||||
struct attribute low_pc;
|
||||
struct attribute high_pc;
|
||||
unsigned long low_pc, high_pc;
|
||||
|
||||
TRACE("%s, for %s\n", dwarf2_debug_ctx(subpgm->ctx), dwarf2_debug_di(di));
|
||||
|
||||
if (!dwarf2_find_attribute(subpgm->ctx, di, DW_AT_low_pc, &low_pc))
|
||||
low_pc.u.uvalue = 0;
|
||||
if (!dwarf2_find_attribute(subpgm->ctx, di, DW_AT_high_pc, &high_pc))
|
||||
high_pc.u.uvalue = 0;
|
||||
if (!dwarf2_read_range(subpgm->ctx, di, &low_pc, &high_pc))
|
||||
{
|
||||
FIXME("no range\n");
|
||||
return;
|
||||
}
|
||||
|
||||
block = symt_open_func_block(subpgm->ctx->module, subpgm->func, parent_block,
|
||||
subpgm->ctx->load_offset + low_pc.u.uvalue - subpgm->func->address,
|
||||
high_pc.u.uvalue - low_pc.u.uvalue);
|
||||
subpgm->ctx->load_offset + low_pc - subpgm->func->address,
|
||||
high_pc - low_pc);
|
||||
|
||||
if (di->abbrev->have_child) /** any interest to not have child ? */
|
||||
{
|
||||
|
@ -1683,8 +1740,7 @@ static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx,
|
|||
struct symt_compiland* compiland)
|
||||
{
|
||||
struct attribute name;
|
||||
struct attribute low_pc;
|
||||
struct attribute high_pc;
|
||||
unsigned long low_pc, high_pc;
|
||||
struct attribute is_decl;
|
||||
struct attribute inline_flags;
|
||||
struct symt* ret_type;
|
||||
|
@ -1710,14 +1766,17 @@ static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (!dwarf2_find_attribute(ctx, di, DW_AT_low_pc, &low_pc)) low_pc.u.uvalue = 0;
|
||||
if (!dwarf2_find_attribute(ctx, di, DW_AT_high_pc, &high_pc)) high_pc.u.uvalue = 0;
|
||||
if (!dwarf2_read_range(ctx, di, &low_pc, &high_pc))
|
||||
{
|
||||
FIXME("cannot get range\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* As functions (defined as inline assembly) get debug info with dwarf
|
||||
* (not the case for stabs), we just drop Wine's thunks here...
|
||||
* Actual thunks will be created in elf_module from the symbol table
|
||||
*/
|
||||
if (elf_is_in_thunk_area(ctx->load_offset + low_pc.u.uvalue,
|
||||
ctx->thunks) >= 0)
|
||||
if (elf_is_in_thunk_area(ctx->load_offset + low_pc, ctx->thunks) >= 0)
|
||||
return NULL;
|
||||
if (!dwarf2_find_attribute(ctx, di, DW_AT_declaration, &is_decl))
|
||||
is_decl.u.uvalue = 0;
|
||||
|
@ -1733,8 +1792,7 @@ static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx,
|
|||
if (!is_decl.u.uvalue)
|
||||
{
|
||||
subpgm.func = symt_new_function(ctx->module, compiland, name.u.string,
|
||||
ctx->load_offset + low_pc.u.uvalue,
|
||||
high_pc.u.uvalue - low_pc.u.uvalue,
|
||||
ctx->load_offset + low_pc, high_pc - low_pc,
|
||||
&sig_type->symt);
|
||||
di->symt = &subpgm.func->symt;
|
||||
}
|
||||
|
@ -3119,7 +3177,7 @@ BOOL dwarf2_parse(struct module* module, unsigned long load_offset,
|
|||
dwarf2_section_t section[section_max];
|
||||
dwarf2_traverse_context_t mod_ctx;
|
||||
struct image_section_map debug_sect, debug_str_sect, debug_abbrev_sect,
|
||||
debug_line_sect;
|
||||
debug_line_sect, debug_ranges_sect;
|
||||
BOOL ret = TRUE;
|
||||
struct module_format* dwarf2_modfmt;
|
||||
|
||||
|
@ -3130,6 +3188,7 @@ BOOL dwarf2_parse(struct module* module, unsigned long load_offset,
|
|||
dwarf2_init_section(§ion[section_abbrev], fmap, ".debug_abbrev", &debug_abbrev_sect);
|
||||
dwarf2_init_section(§ion[section_string], fmap, ".debug_str", &debug_str_sect);
|
||||
dwarf2_init_section(§ion[section_line], fmap, ".debug_line", &debug_line_sect);
|
||||
dwarf2_init_section(§ion[section_ranges], fmap, ".debug_ranges", &debug_ranges_sect);
|
||||
|
||||
if (section[section_debug].address == IMAGE_NO_MAP ||
|
||||
section[section_abbrev].address == IMAGE_NO_MAP ||
|
||||
|
@ -3192,6 +3251,7 @@ leave:
|
|||
image_unmap_section(&debug_abbrev_sect);
|
||||
image_unmap_section(&debug_str_sect);
|
||||
image_unmap_section(&debug_line_sect);
|
||||
image_unmap_section(&debug_ranges_sect);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue