mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-15 01:49:16 +00:00
dbghelp: Store address range as FAM in symt_inlinesite.
Signed-off-by: Eric Pouech <eric.pouech@gmail.com>
This commit is contained in:
parent
a6f1f7be7e
commit
c576b0c73f
|
@ -294,7 +294,8 @@ struct symt_function
|
|||
struct symt_inlinesite
|
||||
{
|
||||
struct symt_function func;
|
||||
struct vector vranges; /* of addr_range: where the inline site is actually defined */
|
||||
unsigned num_ranges;
|
||||
struct addr_range ranges[];
|
||||
};
|
||||
|
||||
struct symt_hierarchy_point
|
||||
|
@ -850,7 +851,8 @@ extern struct symt_inlinesite*
|
|||
struct symt_function* func,
|
||||
struct symt* parent,
|
||||
const char* name,
|
||||
struct symt* type) DECLSPEC_HIDDEN;
|
||||
struct symt* type,
|
||||
unsigned num_ranges) DECLSPEC_HIDDEN;
|
||||
extern void symt_add_func_line(struct module* module,
|
||||
struct symt_function* func,
|
||||
unsigned source_idx, int line_num,
|
||||
|
@ -880,11 +882,8 @@ extern struct symt_hierarchy_point*
|
|||
enum SymTagEnum point,
|
||||
const struct location* loc,
|
||||
const char* name) DECLSPEC_HIDDEN;
|
||||
extern BOOL symt_add_inlinesite_range(struct module* module,
|
||||
struct symt_inlinesite* inlined,
|
||||
ULONG_PTR low, ULONG_PTR high) DECLSPEC_HIDDEN;
|
||||
extern struct symt_thunk*
|
||||
symt_new_thunk(struct module* module,
|
||||
symt_new_thunk(struct module* module,
|
||||
struct symt_compiland* parent,
|
||||
const char* name, THUNK_ORDINAL ord,
|
||||
ULONG_PTR addr, ULONG_PTR size) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -2117,12 +2117,11 @@ static void dwarf2_parse_inlined_subroutine(dwarf2_subprogram_t* subpgm,
|
|||
struct vector* children;
|
||||
dwarf2_debug_info_t*child;
|
||||
unsigned int i;
|
||||
struct addr_range* adranges;
|
||||
unsigned num_adranges;
|
||||
unsigned num_ranges;
|
||||
|
||||
TRACE("%s\n", dwarf2_debug_di(di));
|
||||
|
||||
if ((adranges = dwarf2_get_ranges(di, &num_adranges)) == NULL)
|
||||
if (!(num_ranges = dwarf2_get_num_ranges(di)))
|
||||
{
|
||||
WARN("cannot read ranges\n");
|
||||
return;
|
||||
|
@ -2141,16 +2140,17 @@ static void dwarf2_parse_inlined_subroutine(dwarf2_subprogram_t* subpgm,
|
|||
subpgm->top_func,
|
||||
subpgm->current_block ? &subpgm->current_block->symt : &subpgm->current_func->symt,
|
||||
dwarf2_get_cpp_name(di, name.u.string),
|
||||
&sig_type->symt);
|
||||
&sig_type->symt, num_ranges);
|
||||
subpgm->current_func = (struct symt_function*)inlined;
|
||||
subpgm->current_block = NULL;
|
||||
|
||||
for (i = 0; i < num_adranges; ++i)
|
||||
symt_add_inlinesite_range(subpgm->ctx->module_ctx->module, inlined,
|
||||
adranges[i].low, adranges[i].high);
|
||||
if (!dwarf2_fill_ranges(di, inlined->ranges, num_ranges))
|
||||
{
|
||||
FIXME("Unexpected situation\n");
|
||||
inlined->num_ranges = 0;
|
||||
}
|
||||
/* temporary: update address field */
|
||||
inlined->func.address = adranges[0].low;
|
||||
free(adranges);
|
||||
inlined->func.address = inlined->ranges[0].low;
|
||||
|
||||
children = dwarf2_get_di_children(di);
|
||||
if (children) for (i = 0; i < vector_length(children); i++)
|
||||
|
@ -2616,10 +2616,9 @@ static void dwarf2_set_line_number(struct module* module, ULONG_PTR address,
|
|||
for (inlined = func->next_inlinesite; inlined; inlined = inlined->func.next_inlinesite)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < inlined->vranges.num_elts; ++i)
|
||||
for (i = 0; i < inlined->num_ranges; ++i)
|
||||
{
|
||||
struct addr_range* ar = (struct addr_range*)vector_at(&inlined->vranges, i);
|
||||
if (ar->low <= address && address < ar->high)
|
||||
if (inlined->ranges[i].low <= address && address < inlined->ranges[i].high)
|
||||
{
|
||||
symt_add_func_line(module, &inlined->func, *psrc, line, address);
|
||||
return; /* only add to lowest matching inline site */
|
||||
|
|
|
@ -2077,18 +2077,48 @@ static BOOL cv_dbgsubsect_find_inlinee(const struct msc_debug_info* msc_dbg,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static inline void inline_site_update_last_range(struct symt_inlinesite* inlined, ULONG_PTR hi)
|
||||
static inline void inline_site_update_last_range(struct symt_inlinesite* inlined, unsigned index, ULONG_PTR hi)
|
||||
{
|
||||
unsigned num = inlined->vranges.num_elts;
|
||||
if (num)
|
||||
if (index && index <= inlined->num_ranges)
|
||||
{
|
||||
struct addr_range* range = vector_at(&inlined->vranges, num - 1);
|
||||
struct addr_range* range = &inlined->ranges[index - 1];
|
||||
/* only change range if it has no span (code start without code end) */
|
||||
if (range->low == range->high)
|
||||
range->high = hi;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned inline_site_get_num_ranges(const unsigned char* annot,
|
||||
const unsigned char* last_annot)
|
||||
{
|
||||
struct cv_binannot cvba;
|
||||
unsigned num_ranges = 0;
|
||||
|
||||
cvba.annot = annot;
|
||||
cvba.last_annot = last_annot;
|
||||
|
||||
while (codeview_advance_binannot(&cvba))
|
||||
{
|
||||
switch (cvba.opcode)
|
||||
{
|
||||
case BA_OP_CodeOffset:
|
||||
case BA_OP_ChangeCodeLength:
|
||||
case BA_OP_ChangeFile:
|
||||
case BA_OP_ChangeLineOffset:
|
||||
break;
|
||||
case BA_OP_ChangeCodeOffset:
|
||||
case BA_OP_ChangeCodeOffsetAndLineOffset:
|
||||
case BA_OP_ChangeCodeLengthAndCodeOffset:
|
||||
num_ranges++;
|
||||
break;
|
||||
default:
|
||||
WARN("Unsupported op %d\n", cvba.opcode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return num_ranges;
|
||||
}
|
||||
|
||||
static struct symt_inlinesite* codeview_create_inline_site(const struct msc_debug_info* msc_dbg,
|
||||
const struct cv_module_snarf* cvmod,
|
||||
struct symt_function* top_func,
|
||||
|
@ -2102,7 +2132,8 @@ static struct symt_inlinesite* codeview_create_inline_site(const struct msc_debu
|
|||
struct symt_inlinesite* inlined;
|
||||
struct cv_binannot cvba;
|
||||
BOOL srcok;
|
||||
unsigned offset, line, srcfile;
|
||||
unsigned num_ranges;
|
||||
unsigned offset, index, line, srcfile;
|
||||
const struct CV_Checksum_t* chksms;
|
||||
|
||||
if (!cvmod->ipi_ctp || !(cvt = codeview_jump_to_type(cvmod->ipi_ctp, inlinee)))
|
||||
|
@ -2110,19 +2141,23 @@ static struct symt_inlinesite* codeview_create_inline_site(const struct msc_debu
|
|||
FIXME("Couldn't find type %x in IPI stream\n", inlinee);
|
||||
return NULL;
|
||||
}
|
||||
num_ranges = inline_site_get_num_ranges(annot, last_annot);
|
||||
if (!num_ranges) return NULL;
|
||||
|
||||
switch (cvt->generic.id)
|
||||
{
|
||||
case LF_FUNC_ID:
|
||||
inlined = symt_new_inlinesite(msc_dbg->module, top_func, container,
|
||||
cvt->func_id_v3.name,
|
||||
codeview_get_type(cvt->func_id_v3.type, FALSE));
|
||||
codeview_get_type(cvt->func_id_v3.type, FALSE),
|
||||
num_ranges);
|
||||
break;
|
||||
case LF_MFUNC_ID:
|
||||
/* FIXME we just declare a function, not a method */
|
||||
inlined = symt_new_inlinesite(msc_dbg->module, top_func, container,
|
||||
cvt->mfunc_id_v3.name,
|
||||
codeview_get_type(cvt->mfunc_id_v3.type, FALSE));
|
||||
codeview_get_type(cvt->mfunc_id_v3.type, FALSE),
|
||||
num_ranges);
|
||||
break;
|
||||
default:
|
||||
FIXME("unsupported inlinee kind %x\n", cvt->generic.id);
|
||||
|
@ -2144,6 +2179,7 @@ static struct symt_inlinesite* codeview_create_inline_site(const struct msc_debu
|
|||
|
||||
/* rescan all annotations and store ranges & line information */
|
||||
offset = 0;
|
||||
index = 0;
|
||||
cvba.annot = annot;
|
||||
cvba.last_annot = last_annot;
|
||||
|
||||
|
@ -2156,18 +2192,15 @@ static struct symt_inlinesite* codeview_create_inline_site(const struct msc_debu
|
|||
break;
|
||||
case BA_OP_ChangeCodeOffset:
|
||||
offset += cvba.arg1;
|
||||
inline_site_update_last_range(inlined, top_func->address + offset);
|
||||
inline_site_update_last_range(inlined, index, top_func->address + offset);
|
||||
if (srcok)
|
||||
symt_add_func_line(msc_dbg->module, &inlined->func, srcfile, line, top_func->address + offset);
|
||||
symt_add_inlinesite_range(msc_dbg->module, inlined, top_func->address + offset, top_func->address + offset);
|
||||
inlined->ranges[index ].low = top_func->address + offset;
|
||||
inlined->ranges[index++].high = top_func->address + offset;
|
||||
break;
|
||||
case BA_OP_ChangeCodeLength:
|
||||
/* this op doesn't seem widely used... */
|
||||
if (inlined->vranges.num_elts)
|
||||
{
|
||||
struct addr_range* range = vector_at(&inlined->vranges, inlined->vranges.num_elts - 1);
|
||||
inline_site_update_last_range(inlined, range->low + cvba.arg1);
|
||||
}
|
||||
inline_site_update_last_range(inlined, index, inlined->ranges[index - 1].low + cvba.arg1);
|
||||
break;
|
||||
case BA_OP_ChangeFile:
|
||||
chksms = CV_RECORD_GAP(hdr_files, cvba.arg1);
|
||||
|
@ -2180,31 +2213,35 @@ static struct symt_inlinesite* codeview_create_inline_site(const struct msc_debu
|
|||
case BA_OP_ChangeCodeOffsetAndLineOffset:
|
||||
line += binannot_getsigned(cvba.arg2);
|
||||
offset += cvba.arg1;
|
||||
inline_site_update_last_range(inlined, top_func->address + offset);
|
||||
inline_site_update_last_range(inlined, index, top_func->address + offset);
|
||||
if (srcok)
|
||||
symt_add_func_line(msc_dbg->module, &inlined->func, srcfile, line, top_func->address + offset);
|
||||
symt_add_inlinesite_range(msc_dbg->module, inlined, top_func->address + offset, top_func->address + offset);
|
||||
inlined->ranges[index ].low = top_func->address + offset;
|
||||
inlined->ranges[index++].high = top_func->address + offset;
|
||||
break;
|
||||
case BA_OP_ChangeCodeLengthAndCodeOffset:
|
||||
offset += cvba.arg2;
|
||||
inline_site_update_last_range(inlined, top_func->address + offset);
|
||||
inline_site_update_last_range(inlined, index, top_func->address + offset);
|
||||
if (srcok)
|
||||
symt_add_func_line(msc_dbg->module, &inlined->func, srcfile, line, top_func->address + offset);
|
||||
symt_add_inlinesite_range(msc_dbg->module, inlined, top_func->address + offset, top_func->address + offset + cvba.arg1);
|
||||
inlined->ranges[index ].low = top_func->address + offset;
|
||||
inlined->ranges[index++].high = top_func->address + offset + cvba.arg1;
|
||||
break;
|
||||
default:
|
||||
WARN("Unsupported op %d\n", cvba.opcode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (inlined->vranges.num_elts)
|
||||
if (index != num_ranges) /* sanity check */
|
||||
FIXME("Internal logic error\n");
|
||||
if (inlined->num_ranges)
|
||||
{
|
||||
struct addr_range* range = vector_at(&inlined->vranges, inlined->vranges.num_elts - 1);
|
||||
struct addr_range* range = &inlined->ranges[inlined->num_ranges - 1];
|
||||
if (range->low == range->high) WARN("pending empty range at end of %s inside %s\n",
|
||||
inlined->func.hash_elt.name,
|
||||
top_func->hash_elt.name);
|
||||
/* temporary: update address field */
|
||||
inlined->func.address = ((struct addr_range*)vector_at(&inlined->vranges, 0))->low;
|
||||
inlined->func.address = inlined->ranges[0].low;
|
||||
}
|
||||
return inlined;
|
||||
}
|
||||
|
|
|
@ -362,20 +362,21 @@ struct symt_inlinesite* symt_new_inlinesite(struct module* module,
|
|||
struct symt_function* func,
|
||||
struct symt* container,
|
||||
const char* name,
|
||||
struct symt* sig_type)
|
||||
struct symt* sig_type,
|
||||
unsigned num_ranges)
|
||||
{
|
||||
struct symt_inlinesite* sym;
|
||||
|
||||
TRACE_(dbghelp_symt)("Adding inline site %s\n", name);
|
||||
if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
|
||||
if ((sym = pool_alloc(&module->pool, offsetof(struct symt_inlinesite, ranges[num_ranges]))))
|
||||
{
|
||||
struct symt** p;
|
||||
assert(container);
|
||||
init_function_or_inlinesite(&sym->func, module, SymTagInlineSite, container, name, 0, 0, sig_type);
|
||||
vector_init(&sym->vranges, sizeof(struct addr_range), 2); /* FIXME: number of elts => to be set on input */
|
||||
/* chain inline sites */
|
||||
sym->func.next_inlinesite = func->next_inlinesite;
|
||||
func->next_inlinesite = sym;
|
||||
sym->num_ranges = num_ranges;
|
||||
if (container->tag == SymTagFunction || container->tag == SymTagInlineSite)
|
||||
p = vector_add(&((struct symt_function*)container)->vchildren, &module->pool);
|
||||
else
|
||||
|
@ -534,7 +535,7 @@ struct symt_block* symt_open_func_block(struct module* module,
|
|||
assert(num_ranges > 0);
|
||||
assert(!parent_block || parent_block->symt.tag == SymTagBlock);
|
||||
|
||||
block = pool_alloc(&module->pool, sizeof(*block) + num_ranges * sizeof(block->ranges[0]));
|
||||
block = pool_alloc(&module->pool, offsetof(struct symt_block, ranges[num_ranges]));
|
||||
block->symt.tag = SymTagBlock;
|
||||
block->num_ranges = num_ranges;
|
||||
block->container = parent_block ? &parent_block->symt : &func->symt;
|
||||
|
@ -579,42 +580,6 @@ struct symt_hierarchy_point* symt_add_function_point(struct module* module,
|
|||
return sym;
|
||||
}
|
||||
|
||||
/* low and high are absolute addresses */
|
||||
BOOL symt_add_inlinesite_range(struct module* module,
|
||||
struct symt_inlinesite* inlined,
|
||||
ULONG_PTR low, ULONG_PTR high)
|
||||
{
|
||||
struct addr_range* p;
|
||||
|
||||
p = vector_add(&inlined->vranges, &module->pool);
|
||||
p->low = low;
|
||||
p->high = high;
|
||||
if (TRUE)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* see dbghelp_private.h for the assumptions */
|
||||
for (i = 0; i < inlined->vranges.num_elts - 1; i++)
|
||||
{
|
||||
if (!addr_range_disjoint((struct addr_range*)vector_at(&inlined->vranges, i), p))
|
||||
{
|
||||
FIXME("Added addr_range isn't disjoint from siblings\n");
|
||||
}
|
||||
}
|
||||
for ( ; inlined->func.symt.tag != SymTagFunction; inlined = (struct symt_inlinesite*)symt_get_upper_inlined(inlined))
|
||||
{
|
||||
for (i = 0; i < inlined->vranges.num_elts; i++)
|
||||
{
|
||||
struct addr_range* ar = (struct addr_range*)vector_at(&inlined->vranges, i);
|
||||
if (!addr_range_disjoint(ar, p) && !addr_range_inside(ar, p))
|
||||
WARN("Added addr_range not compatible with parent\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
struct symt_thunk* symt_new_thunk(struct module* module,
|
||||
struct symt_compiland* compiland,
|
||||
const char* name, THUNK_ORDINAL ord,
|
||||
|
@ -1244,11 +1209,10 @@ struct symt_inlinesite* symt_find_lowest_inlined(struct symt_function* func, DWO
|
|||
assert(func->symt.tag == SymTagFunction);
|
||||
for (current = func->next_inlinesite; current; current = current->func.next_inlinesite)
|
||||
{
|
||||
for (i = 0; i < current->vranges.num_elts; ++i)
|
||||
for (i = 0; i < current->num_ranges; ++i)
|
||||
{
|
||||
struct addr_range* ar = (struct addr_range*)vector_at(¤t->vranges, i);
|
||||
/* first matching range gives the lowest inline site; see dbghelp_private.h for details */
|
||||
if (ar->low <= addr && addr < ar->high)
|
||||
if (current->ranges[i].low <= addr && addr < current->ranges[i].high)
|
||||
return current;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue