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;
|
DWORD_PTR rva;
|
||||||
} dwarf2_section_t;
|
} 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
|
typedef struct dwarf2_traverse_context_s
|
||||||
{
|
{
|
||||||
|
@ -944,6 +944,61 @@ static struct symt* dwarf2_lookup_type(dwarf2_parse_context_t* ctx,
|
||||||
return NULL;
|
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
|
* 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)
|
const dwarf2_debug_info_t* di)
|
||||||
{
|
{
|
||||||
struct symt_block* block;
|
struct symt_block* block;
|
||||||
struct attribute low_pc;
|
unsigned long low_pc, high_pc;
|
||||||
struct attribute high_pc;
|
|
||||||
|
|
||||||
TRACE("%s, for %s\n", dwarf2_debug_ctx(subpgm->ctx), dwarf2_debug_di(di));
|
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_read_range(subpgm->ctx, di, &low_pc, &high_pc))
|
||||||
if (!dwarf2_find_attribute(subpgm->ctx, di, DW_AT_high_pc, &high_pc)) high_pc.u.uvalue = 0;
|
{
|
||||||
|
FIXME("cannot read range\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
block = symt_open_func_block(subpgm->ctx->module, subpgm->func, parent_block,
|
block = symt_open_func_block(subpgm->ctx->module, subpgm->func, parent_block,
|
||||||
subpgm->ctx->load_offset + low_pc.u.uvalue - subpgm->func->address,
|
subpgm->ctx->load_offset + low_pc - subpgm->func->address,
|
||||||
high_pc.u.uvalue - low_pc.u.uvalue);
|
high_pc - low_pc);
|
||||||
|
|
||||||
if (di->abbrev->have_child) /** any interest to not have child ? */
|
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)
|
const dwarf2_debug_info_t* di)
|
||||||
{
|
{
|
||||||
struct symt_block* block;
|
struct symt_block* block;
|
||||||
struct attribute low_pc;
|
unsigned long low_pc, high_pc;
|
||||||
struct attribute high_pc;
|
|
||||||
|
|
||||||
TRACE("%s, for %s\n", dwarf2_debug_ctx(subpgm->ctx), dwarf2_debug_di(di));
|
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))
|
if (!dwarf2_read_range(subpgm->ctx, di, &low_pc, &high_pc))
|
||||||
low_pc.u.uvalue = 0;
|
{
|
||||||
if (!dwarf2_find_attribute(subpgm->ctx, di, DW_AT_high_pc, &high_pc))
|
FIXME("no range\n");
|
||||||
high_pc.u.uvalue = 0;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
block = symt_open_func_block(subpgm->ctx->module, subpgm->func, parent_block,
|
block = symt_open_func_block(subpgm->ctx->module, subpgm->func, parent_block,
|
||||||
subpgm->ctx->load_offset + low_pc.u.uvalue - subpgm->func->address,
|
subpgm->ctx->load_offset + low_pc - subpgm->func->address,
|
||||||
high_pc.u.uvalue - low_pc.u.uvalue);
|
high_pc - low_pc);
|
||||||
|
|
||||||
if (di->abbrev->have_child) /** any interest to not have child ? */
|
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 symt_compiland* compiland)
|
||||||
{
|
{
|
||||||
struct attribute name;
|
struct attribute name;
|
||||||
struct attribute low_pc;
|
unsigned long low_pc, high_pc;
|
||||||
struct attribute high_pc;
|
|
||||||
struct attribute is_decl;
|
struct attribute is_decl;
|
||||||
struct attribute inline_flags;
|
struct attribute inline_flags;
|
||||||
struct symt* ret_type;
|
struct symt* ret_type;
|
||||||
|
@ -1710,14 +1766,17 @@ static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dwarf2_find_attribute(ctx, di, DW_AT_low_pc, &low_pc)) low_pc.u.uvalue = 0;
|
if (!dwarf2_read_range(ctx, di, &low_pc, &high_pc))
|
||||||
if (!dwarf2_find_attribute(ctx, di, DW_AT_high_pc, &high_pc)) high_pc.u.uvalue = 0;
|
{
|
||||||
|
FIXME("cannot get range\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* As functions (defined as inline assembly) get debug info with dwarf
|
/* As functions (defined as inline assembly) get debug info with dwarf
|
||||||
* (not the case for stabs), we just drop Wine's thunks here...
|
* (not the case for stabs), we just drop Wine's thunks here...
|
||||||
* Actual thunks will be created in elf_module from the symbol table
|
* 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,
|
if (elf_is_in_thunk_area(ctx->load_offset + low_pc, ctx->thunks) >= 0)
|
||||||
ctx->thunks) >= 0)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!dwarf2_find_attribute(ctx, di, DW_AT_declaration, &is_decl))
|
if (!dwarf2_find_attribute(ctx, di, DW_AT_declaration, &is_decl))
|
||||||
is_decl.u.uvalue = 0;
|
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)
|
if (!is_decl.u.uvalue)
|
||||||
{
|
{
|
||||||
subpgm.func = symt_new_function(ctx->module, compiland, name.u.string,
|
subpgm.func = symt_new_function(ctx->module, compiland, name.u.string,
|
||||||
ctx->load_offset + low_pc.u.uvalue,
|
ctx->load_offset + low_pc, high_pc - low_pc,
|
||||||
high_pc.u.uvalue - low_pc.u.uvalue,
|
|
||||||
&sig_type->symt);
|
&sig_type->symt);
|
||||||
di->symt = &subpgm.func->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_section_t section[section_max];
|
||||||
dwarf2_traverse_context_t mod_ctx;
|
dwarf2_traverse_context_t mod_ctx;
|
||||||
struct image_section_map debug_sect, debug_str_sect, debug_abbrev_sect,
|
struct image_section_map debug_sect, debug_str_sect, debug_abbrev_sect,
|
||||||
debug_line_sect;
|
debug_line_sect, debug_ranges_sect;
|
||||||
BOOL ret = TRUE;
|
BOOL ret = TRUE;
|
||||||
struct module_format* dwarf2_modfmt;
|
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_abbrev], fmap, ".debug_abbrev", &debug_abbrev_sect);
|
||||||
dwarf2_init_section(§ion[section_string], fmap, ".debug_str", &debug_str_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_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 ||
|
if (section[section_debug].address == IMAGE_NO_MAP ||
|
||||||
section[section_abbrev].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_abbrev_sect);
|
||||||
image_unmap_section(&debug_str_sect);
|
image_unmap_section(&debug_str_sect);
|
||||||
image_unmap_section(&debug_line_sect);
|
image_unmap_section(&debug_line_sect);
|
||||||
|
image_unmap_section(&debug_ranges_sect);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue