Commit b9290c98 authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

dbghelp: Introduce symt_inlinesite (SymTagInlineSite) to support inline sites.

parent fd5c709c
......@@ -216,16 +216,63 @@ struct symt_data
} u;
};
/* We must take into account that most debug formats (dwarf and pdb) report for
* code (esp. inlined functions) inside functions the following way:
* - block
* + is represented by a contiguous area of memory,
* or at least have lo/hi addresses to encompass it's contents
* + but most importantly, block A's lo/hi range is always embedded within
* its parent (block or function)
* - inline site:
* + is most of the times represented by a set of ranges (instead of a
* contiguous block)
* + native dbghelp only exports the start address, not its size
* + the set of ranges isn't always embedded in enclosing block (if any)
* + the set of ranges is always embedded in top function
* - (top) function
* + is described as a contiguous block of memory
*
* On top of the items above (taken as assumptions), we also assume that:
* - a range in inline site A, is disjoint from all the other ranges in
* inline site A
* - a range in inline site A, is either disjoint or embedded into any of
* the ranges of inline sites parent of A
*
* Therefore, we also store all inline sites inside a function:
* - available as a linked list to simplify the walk among them
* - this linked list shall preserve the weak order of the lexical-parent
* relationship (eg for any inline site A, which has inline site B
* as lexical parent, then A is present before B in the linked list)
* - hence (from the assumptions above), when looking up which inline site
* contains a given address, the first range containing that address found
* while walking the list of inline sites is the right one.
*/
struct symt_function
{
struct symt symt;
struct symt symt; /* SymTagFunction (or SymTagInlineSite when embedded in symt_inlinesite) */
struct hash_table_elt hash_elt; /* if global symbol */
ULONG_PTR address;
struct symt* container; /* compiland */
struct symt* type; /* points to function_signature */
ULONG_PTR size;
struct vector vlines;
struct vector vchildren; /* locals, params, blocks, start/end, labels */
struct vector vchildren; /* locals, params, blocks, start/end, labels, inline sites */
struct symt_inlinesite* next_inlinesite;/* linked list of inline sites in this function */
};
/* FIXME: this could be optimized later on by using relative offsets and smaller integral sizes */
struct addr_range
{
DWORD64 low; /* absolute address of first byte of the range */
DWORD64 high; /* absolute address of first byte after the range */
};
/* a symt_inlinesite* can be casted to a symt_function* to access all function bits */
struct symt_inlinesite
{
struct symt_function func;
struct vector vranges; /* of addr_range: where the inline site is actually defined */
};
struct symt_hierarchy_point
......
......@@ -2438,7 +2438,7 @@ static void dwarf2_set_line_number(struct module* module, ULONG_PTR address,
TRACE("%s %lx %s %u\n",
debugstr_w(module->modulename), address, debugstr_a(source_get(module, *psrc)), line);
symt = symt_find_nearest(module, address);
if (symt && symt_check_tag(&symt->symt, SymTagFunction))
if (symt_check_tag(&symt->symt, SymTagFunction))
{
func = (struct symt_function*)symt;
symt_add_func_line(module, func, *psrc, line, address - func->address);
......
......@@ -1446,7 +1446,7 @@ static void codeview_snarf_linetab(const struct msc_debug_info* msc_dbg, const B
{
func = (struct symt_function*)symt_find_nearest(msc_dbg->module, addr);
/* FIXME: at least labels support line numbers */
if (!func || func->symt.tag != SymTagFunction)
if (!symt_check_tag(&func->symt, SymTagFunction) && !symt_check_tag(&func->symt, SymTagInlineSite))
{
WARN("--not a func at %04x:%08x %lx tag=%d\n",
ltb->seg, ltb->offsets[k], addr, func ? func->symt.tag : -1);
......@@ -1509,7 +1509,7 @@ static void codeview_snarf_linetab2(const struct msc_debug_info* msc_dbg, const
source = source_new(msc_dbg->module, NULL, strimage + fd->offset);
func = (struct symt_function*)symt_find_nearest(msc_dbg->module, addr);
/* FIXME: at least labels support line numbers */
if (!func || func->symt.tag != SymTagFunction)
if (!symt_check_tag(&func->symt, SymTagFunction) && !symt_check_tag(&func->symt, SymTagInlineSite))
{
WARN("--not a func at %04x:%08x %lx tag=%d\n",
lines_blk->seg, lines_blk->start, addr, func ? func->symt.tag : -1);
......
......@@ -366,7 +366,7 @@ void symt_add_func_line(struct module* module, struct symt_function* func,
func, func->hash_elt.name, offset,
source_get(module, source_idx), line_num);
assert(func->symt.tag == SymTagFunction);
assert(func->symt.tag == SymTagFunction || func->symt.tag == SymTagInlineSite);
for (i=vector_length(&func->vlines)-1; i>=0; i--)
{
......@@ -424,8 +424,7 @@ struct symt_data* symt_add_func_local(struct module* module,
debugstr_w(module->modulename), func->hash_elt.name,
name, type);
assert(func);
assert(func->symt.tag == SymTagFunction);
assert(symt_check_tag(&func->symt, SymTagFunction) || symt_check_tag(&func->symt, SymTagInlineSite));
assert(dt == DataIsParam || dt == DataIsLocal);
locsym = pool_alloc(&module->pool, sizeof(*locsym));
......@@ -462,8 +461,7 @@ struct symt_data* symt_add_func_constant(struct module* module,
debugstr_w(module->modulename), func->hash_elt.name,
name, type);
assert(func);
assert(func->symt.tag == SymTagFunction);
assert(symt_check_tag(&func->symt, SymTagFunction) || symt_check_tag(&func->symt, SymTagInlineSite));
locsym = pool_alloc(&module->pool, sizeof(*locsym));
locsym->symt.tag = SymTagData;
......@@ -489,8 +487,7 @@ struct symt_block* symt_open_func_block(struct module* module,
struct symt_block* block;
struct symt** p;
assert(func);
assert(func->symt.tag == SymTagFunction);
assert(symt_check_tag(&func->symt, SymTagFunction) || symt_check_tag(&func->symt, SymTagInlineSite));
assert(!parent_block || parent_block->symt.tag == SymTagBlock);
block = pool_alloc(&module->pool, sizeof(*block));
......@@ -512,8 +509,7 @@ struct symt_block* symt_close_func_block(struct module* module,
const struct symt_function* func,
struct symt_block* block, unsigned pc)
{
assert(func);
assert(func->symt.tag == SymTagFunction);
assert(symt_check_tag(&func->symt, SymTagFunction) || symt_check_tag(&func->symt, SymTagInlineSite));
if (pc) block->size = func->address + pc - block->address;
return (block->container->tag == SymTagBlock) ?
......@@ -781,6 +777,7 @@ static void symt_fill_sym_info(struct module_pair* pair,
}
break;
case SymTagFunction:
case SymTagInlineSite:
symt_get_address(sym, &sym_info->Address);
break;
case SymTagThunk:
......@@ -1061,6 +1058,7 @@ static BOOL symt_enum_locals_helper(struct module_pair* pair,
case SymTagFuncDebugStart:
case SymTagFuncDebugEnd:
case SymTagCustom:
case SymTagInlineSite:
break;
default:
FIXME("Unknown type: %u (%x)\n", lsym->tag, lsym->tag);
......
......@@ -95,6 +95,7 @@ const char* symt_get_name(const struct symt* sym)
/* lexical tree */
case SymTagData: return ((const struct symt_data*)sym)->hash_elt.name;
case SymTagFunction: return ((const struct symt_function*)sym)->hash_elt.name;
case SymTagInlineSite: return ((const struct symt_inlinesite*)sym)->func.hash_elt.name;
case SymTagPublicSymbol: return ((const struct symt_public*)sym)->hash_elt.name;
case SymTagBaseType: return ((const struct symt_basic*)sym)->hash_elt.name;
case SymTagLabel: return ((const struct symt_hierarchy_point*)sym)->hash_elt.name;
......@@ -153,6 +154,9 @@ BOOL symt_get_address(const struct symt* type, ULONG64* addr)
case SymTagFunction:
*addr = ((const struct symt_function*)type)->address;
break;
case SymTagInlineSite:
*addr = ((const struct symt_inlinesite*)type)->func.address;
break;
case SymTagPublicSymbol:
*addr = ((const struct symt_public*)type)->address;
break;
......@@ -572,6 +576,7 @@ BOOL symt_get_info(struct module* module, const struct symt* type,
case SymTagEnum: v = &((const struct symt_enum*)type)->vchildren; break;
case SymTagFunctionType: v = &((const struct symt_function_signature*)type)->vchildren; break;
case SymTagFunction: v = &((const struct symt_function*)type)->vchildren; break;
case SymTagInlineSite: v = &((const struct symt_inlinesite*)type)->func.vchildren; break;
case SymTagBlock: v = &((const struct symt_block*)type)->vchildren; break;
case SymTagPointerType:
case SymTagArrayType:
......@@ -644,6 +649,9 @@ BOOL symt_get_info(struct module* module, const struct symt* type,
case SymTagFunction:
X(DWORD) = vector_length(&((const struct symt_function*)type)->vchildren);
break;
case SymTagInlineSite:
X(DWORD) = vector_length(&((const struct symt_inlinesite*)type)->func.vchildren);
break;
case SymTagBlock:
X(DWORD) = vector_length(&((const struct symt_block*)type)->vchildren);
break;
......@@ -745,6 +753,7 @@ BOOL symt_get_info(struct module* module, const struct symt* type,
case SymTagCompiland:
case SymTagFunctionType:
case SymTagFunctionArgType:
case SymTagInlineSite: /* native doesn't expose it, perhaps because of non-contiguous range */
case SymTagLabel:
case SymTagFuncDebugStart:
case SymTagFuncDebugEnd:
......@@ -767,6 +776,9 @@ BOOL symt_get_info(struct module* module, const struct symt* type,
case SymTagFunction:
X(DWORD) = symt_ptr2index(module, ((const struct symt_function*)type)->container);
break;
case SymTagInlineSite:
X(DWORD) = symt_ptr2index(module, ((const struct symt_inlinesite*)type)->func.container);
break;
case SymTagThunk:
X(DWORD) = symt_ptr2index(module, ((const struct symt_thunk*)type)->container);
break;
......@@ -846,6 +858,7 @@ BOOL symt_get_info(struct module* module, const struct symt* type,
case SymTagFuncDebugStart:
case SymTagFuncDebugEnd:
case SymTagLabel:
case SymTagInlineSite:
case SymTagCustom:
return FALSE;
}
......@@ -899,6 +912,9 @@ BOOL symt_get_info(struct module* module, const struct symt* type,
case SymTagFunction:
X(DWORD) = symt_ptr2index(module, ((const struct symt_function*)type)->type);
break;
case SymTagInlineSite:
X(DWORD) = symt_ptr2index(module, ((const struct symt_inlinesite*)type)->func.type);
break;
case SymTagEnum:
X(DWORD) = symt_ptr2index(module, ((const struct symt_enum*)type)->base_type);
break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment