Commit 690c2e51 authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

dbghelp/dwarf: Generate proper inline functions.

parent ecb91941
......@@ -805,6 +805,13 @@ extern struct symt_function*
const char* name,
ULONG_PTR addr, ULONG_PTR size,
struct symt* type) DECLSPEC_HIDDEN;
extern struct symt_inlinesite*
symt_new_inlinesite(struct module* module,
struct symt_function* func,
struct symt* parent,
const char* name,
ULONG_PTR addr,
struct symt* type) DECLSPEC_HIDDEN;
extern void symt_add_func_line(struct module* module,
struct symt_function* func,
unsigned source_idx, int line_num,
......@@ -894,6 +901,15 @@ extern struct symt_pointer*
extern struct symt_typedef*
symt_new_typedef(struct module* module, struct symt* ref,
const char* name) DECLSPEC_HIDDEN;
extern struct symt*
symt_get_upper_inlined(struct symt_inlinesite* inlined) DECLSPEC_HIDDEN;
static inline struct symt_function*
symt_get_function_from_inlined(struct symt_inlinesite* inlined)
{
while (!symt_check_tag(&inlined->func.symt, SymTagFunction))
inlined = (struct symt_inlinesite*)symt_get_upper_inlined(inlined);
return &inlined->func;
}
/* Inline context encoding (different from what native does):
* bits 31:30: 3 ignore (includes INLINE_FRAME_CONTEXT_IGNORE=0xFFFFFFFF)
......
......@@ -318,6 +318,25 @@ struct symt_data* symt_new_global_variable(struct module* module,
return sym;
}
static void init_function_or_inlinesite(struct symt_function* sym,
struct module* module,
DWORD tag,
struct symt* container,
const char* name,
ULONG_PTR addr, ULONG_PTR size,
struct symt* sig_type)
{
assert(!sig_type || sig_type->tag == SymTagFunctionType);
sym->symt.tag = tag;
sym->hash_elt.name = pool_strdup(&module->pool, name);
sym->container = container;
sym->address = addr;
sym->type = sig_type;
sym->size = size;
vector_init(&sym->vlines, sizeof(struct line_info), 64);
vector_init(&sym->vchildren, sizeof(struct symt*), 8);
}
struct symt_function* symt_new_function(struct module* module,
struct symt_compiland* compiland,
const char* name,
......@@ -325,28 +344,48 @@ struct symt_function* symt_new_function(struct module* module,
struct symt* sig_type)
{
struct symt_function* sym;
struct symt** p;
TRACE_(dbghelp_symt)("Adding global function %s:%s @%lx-%lx\n",
debugstr_w(module->modulename), name, addr, addr + size - 1);
assert(!sig_type || sig_type->tag == SymTagFunctionType);
if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
{
sym->symt.tag = SymTagFunction;
sym->hash_elt.name = pool_strdup(&module->pool, name);
sym->container = &compiland->symt;
sym->address = addr;
sym->type = sig_type;
sym->size = size;
vector_init(&sym->vlines, sizeof(struct line_info), 64);
vector_init(&sym->vchildren, sizeof(struct symt*), 8);
struct symt** p;
init_function_or_inlinesite(sym, module, SymTagFunction, &compiland->symt, name, addr, size, sig_type);
sym->next_inlinesite = NULL; /* first of list */
symt_add_module_ht(module, (struct symt_ht*)sym);
if (compiland)
{
p = vector_add(&compiland->vchildren, &module->pool);
*p = &sym->symt;
}
return sym;
}
struct symt_inlinesite* symt_new_inlinesite(struct module* module,
struct symt_function* func,
struct symt* container,
const char* name,
ULONG_PTR addr,
struct symt* sig_type)
{
struct symt_inlinesite* sym;
TRACE_(dbghelp_symt)("Adding inline site %s @%lx\n", name, addr);
if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
{
struct symt** p;
assert(container);
init_function_or_inlinesite(&sym->func, module, SymTagInlineSite, container, name, addr, 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;
if (container->tag == SymTagFunction || container->tag == SymTagInlineSite)
p = vector_add(&((struct symt_function*)container)->vchildren, &module->pool);
else
{
assert(container->tag == SymTagBlock);
p = vector_add(&((struct symt_block*)container)->vchildren, &module->pool);
}
*p = &sym->func.symt;
}
return sym;
}
......@@ -1138,6 +1177,23 @@ void copy_symbolW(SYMBOL_INFOW* siw, const SYMBOL_INFO* si)
MultiByteToWideChar(CP_ACP, 0, si->Name, -1, siw->Name, siw->MaxNameLen);
}
/* from an inline function, get either the enclosing inlined function, or the top function when no inlined */
struct symt* symt_get_upper_inlined(struct symt_inlinesite* inlined)
{
struct symt* symt = &inlined->func.symt;
do
{
assert(symt);
if (symt->tag == SymTagBlock)
symt = ((struct symt_block*)symt)->container;
else
symt = ((struct symt_function*)symt)->container;
} while (symt->tag == SymTagBlock);
assert(symt->tag == SymTagFunction || symt->tag == SymTagInlineSite);
return symt;
}
/******************************************************************
* sym_enum
*
......
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