dbghelp: Extend support for inlined functions and handle them as generic blocks inside functions
(except for parameters which are converted into local variables). Rewrote dwarf2_find_attribute so that it takes into account the abstract origin information when available. A+
This commit is contained in:
parent
497b2e4ea5
commit
305621d5cf
|
@ -330,7 +330,7 @@ static const char* dwarf2_debug_ctx(const dwarf2_parse_context_t* ctx)
|
||||||
return wine_dbg_sprintf("ctx(%p,%s)", ctx, ctx->module->module.ModuleName);
|
return wine_dbg_sprintf("ctx(%p,%s)", ctx, ctx->module->module.ModuleName);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* dwarf2_debug_di(dwarf2_debug_info_t* di)
|
static const char* dwarf2_debug_di(const dwarf2_debug_info_t* di)
|
||||||
{
|
{
|
||||||
return wine_dbg_sprintf("debug_info(abbrev:%p,symt:%p)",
|
return wine_dbg_sprintf("debug_info(abbrev:%p,symt:%p)",
|
||||||
di->abbrev, di->symt);
|
di->abbrev, di->symt);
|
||||||
|
@ -442,43 +442,37 @@ static void dwarf2_swallow_attribute(dwarf2_traverse_context_t* ctx,
|
||||||
ctx->data += step;
|
ctx->data += step;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL dwarf2_find_attribute(const dwarf2_parse_context_t* ctx,
|
static void dwarf2_fill_attr(const dwarf2_parse_context_t* ctx,
|
||||||
const dwarf2_debug_info_t* di,
|
const dwarf2_abbrev_entry_attr_t* abbrev_attr,
|
||||||
unsigned at, struct attribute* attr)
|
const unsigned char* data,
|
||||||
|
struct attribute* attr)
|
||||||
{
|
{
|
||||||
unsigned i;
|
|
||||||
dwarf2_abbrev_entry_attr_t* abbrev_attr;
|
|
||||||
|
|
||||||
for (i = 0, abbrev_attr = di->abbrev->attrs; abbrev_attr; i++, abbrev_attr = abbrev_attr->next)
|
|
||||||
{
|
|
||||||
if (abbrev_attr->attribute == at)
|
|
||||||
{
|
|
||||||
attr->form = abbrev_attr->form;
|
attr->form = abbrev_attr->form;
|
||||||
switch (attr->form)
|
switch (attr->form)
|
||||||
{
|
{
|
||||||
case DW_FORM_ref_addr:
|
case DW_FORM_ref_addr:
|
||||||
case DW_FORM_addr:
|
case DW_FORM_addr:
|
||||||
attr->u.uvalue = dwarf2_get_addr(di->data[i], ctx->word_size);
|
attr->u.uvalue = dwarf2_get_addr(data, ctx->word_size);
|
||||||
TRACE("addr<0x%lx>\n", attr->u.uvalue);
|
TRACE("addr<0x%lx>\n", attr->u.uvalue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_FORM_flag:
|
case DW_FORM_flag:
|
||||||
attr->u.uvalue = dwarf2_get_byte(di->data[i]);
|
attr->u.uvalue = dwarf2_get_byte(data);
|
||||||
TRACE("flag<0x%lx>\n", attr->u.uvalue);
|
TRACE("flag<0x%lx>\n", attr->u.uvalue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_FORM_data1:
|
case DW_FORM_data1:
|
||||||
attr->u.uvalue = dwarf2_get_byte(di->data[i]);
|
attr->u.uvalue = dwarf2_get_byte(data);
|
||||||
TRACE("data1<%lu>\n", attr->u.uvalue);
|
TRACE("data1<%lu>\n", attr->u.uvalue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_FORM_data2:
|
case DW_FORM_data2:
|
||||||
attr->u.uvalue = dwarf2_get_u2(di->data[i]);
|
attr->u.uvalue = dwarf2_get_u2(data);
|
||||||
TRACE("data2<%lu>\n", attr->u.uvalue);
|
TRACE("data2<%lu>\n", attr->u.uvalue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_FORM_data4:
|
case DW_FORM_data4:
|
||||||
attr->u.uvalue = dwarf2_get_u4(di->data[i]);
|
attr->u.uvalue = dwarf2_get_u4(data);
|
||||||
TRACE("data4<%lu>\n", attr->u.uvalue);
|
TRACE("data4<%lu>\n", attr->u.uvalue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -487,17 +481,17 @@ static BOOL dwarf2_find_attribute(const dwarf2_parse_context_t* ctx,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_FORM_ref1:
|
case DW_FORM_ref1:
|
||||||
attr->u.uvalue = ctx->ref_offset + dwarf2_get_byte(di->data[i]);
|
attr->u.uvalue = ctx->ref_offset + dwarf2_get_byte(data);
|
||||||
TRACE("ref1<0x%lx>\n", attr->u.uvalue);
|
TRACE("ref1<0x%lx>\n", attr->u.uvalue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_FORM_ref2:
|
case DW_FORM_ref2:
|
||||||
attr->u.uvalue = ctx->ref_offset + dwarf2_get_u2(di->data[i]);
|
attr->u.uvalue = ctx->ref_offset + dwarf2_get_u2(data);
|
||||||
TRACE("ref2<0x%lx>\n", attr->u.uvalue);
|
TRACE("ref2<0x%lx>\n", attr->u.uvalue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_FORM_ref4:
|
case DW_FORM_ref4:
|
||||||
attr->u.uvalue = ctx->ref_offset + dwarf2_get_u4(di->data[i]);
|
attr->u.uvalue = ctx->ref_offset + dwarf2_get_u4(data);
|
||||||
TRACE("ref4<0x%lx>\n", attr->u.uvalue);
|
TRACE("ref4<0x%lx>\n", attr->u.uvalue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -506,54 +500,85 @@ static BOOL dwarf2_find_attribute(const dwarf2_parse_context_t* ctx,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_FORM_sdata:
|
case DW_FORM_sdata:
|
||||||
attr->u.svalue = dwarf2_get_leb128_as_signed(di->data[i], NULL);
|
attr->u.svalue = dwarf2_get_leb128_as_signed(data, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_FORM_ref_udata:
|
case DW_FORM_ref_udata:
|
||||||
attr->u.uvalue = dwarf2_get_leb128_as_unsigned(di->data[i], NULL);
|
attr->u.uvalue = dwarf2_get_leb128_as_unsigned(data, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_FORM_udata:
|
case DW_FORM_udata:
|
||||||
attr->u.uvalue = dwarf2_get_leb128_as_unsigned(di->data[i], NULL);
|
attr->u.uvalue = dwarf2_get_leb128_as_unsigned(data, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_FORM_string:
|
case DW_FORM_string:
|
||||||
attr->u.string = (const char *)di->data[i];
|
attr->u.string = (const char *)data;
|
||||||
TRACE("string<%s>\n", attr->u.string);
|
TRACE("string<%s>\n", attr->u.string);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_FORM_strp:
|
case DW_FORM_strp:
|
||||||
{
|
{
|
||||||
unsigned long offset = dwarf2_get_u4(di->data[i]);
|
unsigned long offset = dwarf2_get_u4(data);
|
||||||
attr->u.string = (const char*)ctx->sections[section_string].address + offset;
|
attr->u.string = (const char*)ctx->sections[section_string].address + offset;
|
||||||
}
|
}
|
||||||
TRACE("strp<%s>\n", attr->u.string);
|
TRACE("strp<%s>\n", attr->u.string);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_FORM_block:
|
case DW_FORM_block:
|
||||||
attr->u.block.size = dwarf2_get_leb128_as_unsigned(di->data[i], &attr->u.block.ptr);
|
attr->u.block.size = dwarf2_get_leb128_as_unsigned(data, &attr->u.block.ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_FORM_block1:
|
case DW_FORM_block1:
|
||||||
attr->u.block.size = dwarf2_get_byte(di->data[i]);
|
attr->u.block.size = dwarf2_get_byte(data);
|
||||||
attr->u.block.ptr = di->data[i] + 1;
|
attr->u.block.ptr = data + 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_FORM_block2:
|
case DW_FORM_block2:
|
||||||
attr->u.block.size = dwarf2_get_u2(di->data[i]);
|
attr->u.block.size = dwarf2_get_u2(data);
|
||||||
attr->u.block.ptr = di->data[i] + 2;
|
attr->u.block.ptr = data + 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_FORM_block4:
|
case DW_FORM_block4:
|
||||||
attr->u.block.size = dwarf2_get_u4(di->data[i]);
|
attr->u.block.size = dwarf2_get_u4(data);
|
||||||
attr->u.block.ptr = di->data[i] + 4;
|
attr->u.block.ptr = data + 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
FIXME("Unhandled attribute form %lx\n", abbrev_attr->form);
|
FIXME("Unhandled attribute form %lx\n", abbrev_attr->form);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL dwarf2_find_attribute(const dwarf2_parse_context_t* ctx,
|
||||||
|
const dwarf2_debug_info_t* di,
|
||||||
|
unsigned at, struct attribute* attr)
|
||||||
|
{
|
||||||
|
unsigned i, ai = 0;
|
||||||
|
dwarf2_abbrev_entry_attr_t* abbrev_attr;
|
||||||
|
dwarf2_abbrev_entry_attr_t* abstract_abbrev_attr;
|
||||||
|
|
||||||
|
while (di)
|
||||||
|
{
|
||||||
|
abstract_abbrev_attr = NULL;
|
||||||
|
for (i = 0, abbrev_attr = di->abbrev->attrs; abbrev_attr; i++, abbrev_attr = abbrev_attr->next)
|
||||||
|
{
|
||||||
|
if (abbrev_attr->attribute == at)
|
||||||
|
{
|
||||||
|
dwarf2_fill_attr(ctx, abbrev_attr, di->data[i], attr);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
if (abbrev_attr->attribute == DW_AT_abstract_origin &&
|
||||||
|
at != DW_AT_sibling)
|
||||||
|
{
|
||||||
|
abstract_abbrev_attr = abbrev_attr;
|
||||||
|
ai = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* do we have an abstract origin debug entry to look into ? */
|
||||||
|
if (!abstract_abbrev_attr) break;
|
||||||
|
dwarf2_fill_attr(ctx, abstract_abbrev_attr, di->data[ai], attr);
|
||||||
|
if (!(di = sparse_array_find(&ctx->debug_info_table, attr->u.uvalue)))
|
||||||
|
FIXME("Should have found the debug info entry\n");
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1101,7 +1126,8 @@ static void dwarf2_parse_udt_member(dwarf2_parse_context_t* ctx,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
loc.offset = 0;
|
loc.offset = 0;
|
||||||
if (!dwarf2_find_attribute(ctx, di, DW_AT_bit_size, &bit_size)) bit_size.u.uvalue = 0;
|
if (!dwarf2_find_attribute(ctx, di, DW_AT_bit_size, &bit_size))
|
||||||
|
bit_size.u.uvalue = 0;
|
||||||
if (dwarf2_find_attribute(ctx, di, DW_AT_bit_offset, &bit_offset))
|
if (dwarf2_find_attribute(ctx, di, DW_AT_bit_offset, &bit_offset))
|
||||||
{
|
{
|
||||||
/* FIXME: we should only do this when implementation is LSB (which is
|
/* FIXME: we should only do this when implementation is LSB (which is
|
||||||
|
@ -1250,12 +1276,14 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm,
|
||||||
struct symt* param_type;
|
struct symt* param_type;
|
||||||
struct attribute name, value;
|
struct attribute name, value;
|
||||||
struct location loc;
|
struct location loc;
|
||||||
BOOL is_pmt = di->abbrev->tag == DW_TAG_formal_parameter;
|
BOOL is_pmt;
|
||||||
|
|
||||||
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));
|
||||||
|
|
||||||
|
is_pmt = !block && di->abbrev->tag == DW_TAG_formal_parameter;
|
||||||
param_type = dwarf2_lookup_type(subpgm->ctx, di);
|
param_type = dwarf2_lookup_type(subpgm->ctx, di);
|
||||||
dwarf2_find_name(subpgm->ctx, di, &name, "parameter");
|
|
||||||
|
dwarf2_find_name(subpgm->ctx, di, &name, NULL);
|
||||||
if (dwarf2_compute_location_attr(subpgm->ctx, di, DW_AT_location,
|
if (dwarf2_compute_location_attr(subpgm->ctx, di, DW_AT_location,
|
||||||
&loc, &subpgm->frame))
|
&loc, &subpgm->frame))
|
||||||
{
|
{
|
||||||
|
@ -1314,7 +1342,7 @@ static void dwarf2_parse_subprogram_label(dwarf2_subprogram_t* subpgm,
|
||||||
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_find_attribute(subpgm->ctx, di, DW_AT_low_pc, &low_pc)) low_pc.u.uvalue = 0;
|
||||||
dwarf2_find_name(subpgm->ctx, di, &name, "label");
|
dwarf2_find_name(subpgm->ctx, di, &name, NULL);
|
||||||
|
|
||||||
loc.kind = loc_absolute;
|
loc.kind = loc_absolute;
|
||||||
loc.offset = subpgm->ctx->module->module.BaseOfImage + low_pc.u.uvalue,
|
loc.offset = subpgm->ctx->module->module.BaseOfImage + low_pc.u.uvalue,
|
||||||
|
@ -1323,63 +1351,10 @@ static void dwarf2_parse_subprogram_label(dwarf2_subprogram_t* subpgm,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dwarf2_parse_subprogram_block(dwarf2_subprogram_t* subpgm,
|
static void dwarf2_parse_subprogram_block(dwarf2_subprogram_t* subpgm,
|
||||||
struct symt_block* block_parent,
|
struct symt_block* parent_block,
|
||||||
dwarf2_debug_info_t* di);
|
dwarf2_debug_info_t* di);
|
||||||
|
|
||||||
static void dwarf2_parse_inlined_subroutine(dwarf2_subprogram_t* subpgm,
|
static void dwarf2_parse_inlined_subroutine(dwarf2_subprogram_t* subpgm,
|
||||||
dwarf2_debug_info_t* di)
|
|
||||||
{
|
|
||||||
TRACE("%s, for %s\n", dwarf2_debug_ctx(subpgm->ctx), dwarf2_debug_di(di));
|
|
||||||
|
|
||||||
/* FIXME: attributes to handle:
|
|
||||||
DW_AT_low_pc:
|
|
||||||
DW_AT_high_pc:
|
|
||||||
DW_AT_name:
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (di->abbrev->have_child) /** any interest to not have child ? */
|
|
||||||
{
|
|
||||||
dwarf2_debug_info_t** pchild = NULL;
|
|
||||||
dwarf2_debug_info_t* child;
|
|
||||||
|
|
||||||
while ((pchild = vector_iter_up(&di->children, pchild)))
|
|
||||||
{
|
|
||||||
child = *pchild;
|
|
||||||
|
|
||||||
switch (child->abbrev->tag)
|
|
||||||
{
|
|
||||||
case DW_TAG_formal_parameter:
|
|
||||||
/* FIXME: this is not properly supported yet
|
|
||||||
* dwarf2_parse_subprogram_parameter(ctx, child, NULL);
|
|
||||||
*/
|
|
||||||
break;
|
|
||||||
case DW_TAG_variable:
|
|
||||||
/* FIXME:
|
|
||||||
* dwarf2_parse_variable(ctx, child);
|
|
||||||
*/
|
|
||||||
break;
|
|
||||||
case DW_TAG_lexical_block:
|
|
||||||
/* FIXME:
|
|
||||||
dwarf2_parse_subprogram_block(ctx, child, func);
|
|
||||||
*/
|
|
||||||
break;
|
|
||||||
case DW_TAG_inlined_subroutine:
|
|
||||||
/* FIXME */
|
|
||||||
dwarf2_parse_inlined_subroutine(subpgm, child);
|
|
||||||
break;
|
|
||||||
case DW_TAG_label:
|
|
||||||
dwarf2_parse_subprogram_label(subpgm, child);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
FIXME("Unhandled Tag type 0x%lx at %s, for %s\n",
|
|
||||||
child->abbrev->tag, dwarf2_debug_ctx(subpgm->ctx),
|
|
||||||
dwarf2_debug_di(di));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dwarf2_parse_subprogram_block(dwarf2_subprogram_t* subpgm,
|
|
||||||
struct symt_block* parent_block,
|
struct symt_block* parent_block,
|
||||||
dwarf2_debug_info_t* di)
|
dwarf2_debug_info_t* di)
|
||||||
{
|
{
|
||||||
|
@ -1406,8 +1381,60 @@ static void dwarf2_parse_subprogram_block(dwarf2_subprogram_t* subpgm,
|
||||||
|
|
||||||
switch (child->abbrev->tag)
|
switch (child->abbrev->tag)
|
||||||
{
|
{
|
||||||
|
case DW_TAG_formal_parameter:
|
||||||
|
case DW_TAG_variable:
|
||||||
|
dwarf2_parse_variable(subpgm, block, child);
|
||||||
|
break;
|
||||||
|
case DW_TAG_lexical_block:
|
||||||
|
dwarf2_parse_subprogram_block(subpgm, block, child);
|
||||||
|
break;
|
||||||
case DW_TAG_inlined_subroutine:
|
case DW_TAG_inlined_subroutine:
|
||||||
dwarf2_parse_inlined_subroutine(subpgm, child);
|
dwarf2_parse_inlined_subroutine(subpgm, block, child);
|
||||||
|
break;
|
||||||
|
case DW_TAG_label:
|
||||||
|
dwarf2_parse_subprogram_label(subpgm, child);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
FIXME("Unhandled Tag type 0x%lx at %s, for %s\n",
|
||||||
|
child->abbrev->tag, dwarf2_debug_ctx(subpgm->ctx),
|
||||||
|
dwarf2_debug_di(di));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
symt_close_func_block(subpgm->ctx->module, subpgm->func, block, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dwarf2_parse_subprogram_block(dwarf2_subprogram_t* subpgm,
|
||||||
|
struct symt_block* parent_block,
|
||||||
|
dwarf2_debug_info_t* di)
|
||||||
|
{
|
||||||
|
struct symt_block* block;
|
||||||
|
struct attribute low_pc;
|
||||||
|
struct attribute 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;
|
||||||
|
|
||||||
|
block = symt_open_func_block(subpgm->ctx->module, subpgm->func, parent_block,
|
||||||
|
low_pc.u.uvalue, high_pc.u.uvalue - low_pc.u.uvalue);
|
||||||
|
|
||||||
|
if (di->abbrev->have_child) /** any interest to not have child ? */
|
||||||
|
{
|
||||||
|
dwarf2_debug_info_t** pchild = NULL;
|
||||||
|
dwarf2_debug_info_t* child;
|
||||||
|
|
||||||
|
while ((pchild = vector_iter_up(&di->children, pchild)))
|
||||||
|
{
|
||||||
|
child = *pchild;
|
||||||
|
|
||||||
|
switch (child->abbrev->tag)
|
||||||
|
{
|
||||||
|
case DW_TAG_inlined_subroutine:
|
||||||
|
dwarf2_parse_inlined_subroutine(subpgm, block, child);
|
||||||
break;
|
break;
|
||||||
case DW_TAG_variable:
|
case DW_TAG_variable:
|
||||||
dwarf2_parse_variable(subpgm, block, child);
|
dwarf2_parse_variable(subpgm, block, child);
|
||||||
|
@ -1461,6 +1488,17 @@ static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx,
|
||||||
|
|
||||||
TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
|
TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
|
||||||
|
|
||||||
|
/* if it's an abstract representation of an inline function, there should be
|
||||||
|
* a concrete object that we'll handle
|
||||||
|
*/
|
||||||
|
if (dwarf2_find_attribute(ctx, di, DW_AT_inline, &inline_flags))
|
||||||
|
{
|
||||||
|
dwarf2_find_name(ctx, di, &name, "subprogram");
|
||||||
|
TRACE("Function %s declared as inlined (%ld)... skipping\n",
|
||||||
|
name.u.string, inline_flags.u.uvalue);
|
||||||
|
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_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_find_attribute(ctx, di, DW_AT_high_pc, &high_pc)) high_pc.u.uvalue = 0;
|
||||||
/* As functions (defined as inline assembly) get debug info with dwarf
|
/* As functions (defined as inline assembly) get debug info with dwarf
|
||||||
|
@ -1470,9 +1508,10 @@ static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx,
|
||||||
if (elf_is_in_thunk_area(ctx->module->module.BaseOfImage + low_pc.u.uvalue,
|
if (elf_is_in_thunk_area(ctx->module->module.BaseOfImage + low_pc.u.uvalue,
|
||||||
ctx->thunks) >= 0)
|
ctx->thunks) >= 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!dwarf2_find_attribute(ctx, di, DW_AT_declaration, &is_decl)) is_decl.u.uvalue = 0;
|
if (!dwarf2_find_attribute(ctx, di, DW_AT_declaration, &is_decl))
|
||||||
if (!dwarf2_find_attribute(ctx, di, DW_AT_inline, &inline_flags)) inline_flags.u.uvalue = 0;
|
is_decl.u.uvalue = 0;
|
||||||
dwarf2_find_name(ctx, di, &name, "subprogram");
|
|
||||||
|
dwarf2_find_name(ctx, di, &name, NULL);
|
||||||
ret_type = dwarf2_lookup_type(ctx, di);
|
ret_type = dwarf2_lookup_type(ctx, di);
|
||||||
|
|
||||||
/* FIXME: assuming C source code */
|
/* FIXME: assuming C source code */
|
||||||
|
@ -1518,7 +1557,7 @@ static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx,
|
||||||
dwarf2_parse_subprogram_block(&subpgm, NULL, child);
|
dwarf2_parse_subprogram_block(&subpgm, NULL, child);
|
||||||
break;
|
break;
|
||||||
case DW_TAG_inlined_subroutine:
|
case DW_TAG_inlined_subroutine:
|
||||||
dwarf2_parse_inlined_subroutine(&subpgm, child);
|
dwarf2_parse_inlined_subroutine(&subpgm, NULL, child);
|
||||||
break;
|
break;
|
||||||
case DW_TAG_subprogram:
|
case DW_TAG_subprogram:
|
||||||
/* FIXME: likely a declaration (to be checked)
|
/* FIXME: likely a declaration (to be checked)
|
||||||
|
|
Loading…
Reference in New Issue