dbghelp: Added support for labels outside functions (and used it in msc parsing).
This commit is contained in:
parent
aaa2862bf9
commit
a4dfe1b042
|
@ -206,12 +206,12 @@ struct symt_function
|
|||
struct vector vchildren; /* locals, params, blocks, start/end, labels */
|
||||
};
|
||||
|
||||
struct symt_function_point
|
||||
struct symt_hierarchy_point
|
||||
{
|
||||
struct symt symt; /* either SymTagFunctionDebugStart, SymTagFunctionDebugEnd, SymTagLabel */
|
||||
struct symt_function* parent;
|
||||
struct hash_table_elt hash_elt; /* if label (and in compiland's hash table if global) */
|
||||
struct symt* parent; /* symt_function or symt_compiland */
|
||||
struct location loc;
|
||||
const char* name; /* for labels */
|
||||
};
|
||||
|
||||
struct symt_public
|
||||
|
@ -548,7 +548,7 @@ extern struct symt_block*
|
|||
symt_close_func_block(struct module* module,
|
||||
struct symt_function* func,
|
||||
struct symt_block* block, unsigned pc);
|
||||
extern struct symt_function_point*
|
||||
extern struct symt_hierarchy_point*
|
||||
symt_add_function_point(struct module* module,
|
||||
struct symt_function* func,
|
||||
enum SymTagEnum point,
|
||||
|
@ -568,6 +568,10 @@ extern struct symt_data*
|
|||
struct symt_compiland* parent,
|
||||
const char* name, struct symt* type,
|
||||
const VARIANT* v);
|
||||
extern struct symt_hierarchy_point*
|
||||
symt_new_label(struct module* module,
|
||||
struct symt_compiland* compiland,
|
||||
const char* name, unsigned long address);
|
||||
|
||||
/* type.c */
|
||||
extern void symt_init_basic(struct module* module);
|
||||
|
|
|
@ -2070,7 +2070,7 @@ static enum location_error loc_compute_frame(struct process* pcs,
|
|||
psym = vector_at(&func->vchildren, i);
|
||||
if ((*psym)->tag == SymTagCustom)
|
||||
{
|
||||
pframe = &((struct symt_function_point*)*psym)->loc;
|
||||
pframe = &((struct symt_hierarchy_point*)*psym)->loc;
|
||||
|
||||
/* First, recompute the frame information, if needed */
|
||||
switch (pframe->kind)
|
||||
|
|
|
@ -1588,9 +1588,9 @@ static int codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* root
|
|||
symt_add_function_point(msc_dbg->module, curr_func, SymTagLabel, &loc,
|
||||
terminate_string(&sym->label_v1.p_name));
|
||||
}
|
||||
else
|
||||
FIXME("No current function for label %s\n",
|
||||
terminate_string(&sym->label_v1.p_name));
|
||||
else symt_new_label(msc_dbg->module, compiland,
|
||||
terminate_string(&sym->label_v1.p_name),
|
||||
codeview_get_address(msc_dbg, sym->label_v1.segment, sym->label_v1.offset));
|
||||
break;
|
||||
case S_LABEL_V3:
|
||||
if (curr_func)
|
||||
|
@ -1600,8 +1600,8 @@ static int codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* root
|
|||
symt_add_function_point(msc_dbg->module, curr_func, SymTagLabel,
|
||||
&loc, sym->label_v3.name);
|
||||
}
|
||||
else
|
||||
FIXME("No current function for label %s\n", sym->label_v3.name);
|
||||
else symt_new_label(msc_dbg->module, compiland, sym->label_v3.name,
|
||||
codeview_get_address(msc_dbg, sym->label_v3.segment, sym->label_v3.offset));
|
||||
break;
|
||||
|
||||
case S_CONSTANT_V1:
|
||||
|
|
|
@ -374,21 +374,21 @@ struct symt_block* symt_close_func_block(struct module* module,
|
|||
GET_ENTRY(block->container, struct symt_block, symt) : NULL;
|
||||
}
|
||||
|
||||
struct symt_function_point* symt_add_function_point(struct module* module,
|
||||
struct symt_function* func,
|
||||
enum SymTagEnum point,
|
||||
const struct location* loc,
|
||||
const char* name)
|
||||
struct symt_hierarchy_point* symt_add_function_point(struct module* module,
|
||||
struct symt_function* func,
|
||||
enum SymTagEnum point,
|
||||
const struct location* loc,
|
||||
const char* name)
|
||||
{
|
||||
struct symt_function_point* sym;
|
||||
struct symt_hierarchy_point*sym;
|
||||
struct symt** p;
|
||||
|
||||
if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
|
||||
{
|
||||
sym->symt.tag = point;
|
||||
sym->parent = func;
|
||||
sym->parent = &func->symt;
|
||||
sym->loc = *loc;
|
||||
sym->name = name ? pool_strdup(&module->pool, name) : NULL;
|
||||
sym->hash_elt.name = name ? pool_strdup(&module->pool, name) : NULL;
|
||||
p = vector_add(&func->vchildren, &module->pool);
|
||||
*p = &sym->symt;
|
||||
}
|
||||
|
@ -478,6 +478,34 @@ struct symt_data* symt_new_constant(struct module* module,
|
|||
return sym;
|
||||
}
|
||||
|
||||
struct symt_hierarchy_point* symt_new_label(struct module* module,
|
||||
struct symt_compiland* compiland,
|
||||
const char* name, unsigned long address)
|
||||
{
|
||||
struct symt_hierarchy_point* sym;
|
||||
|
||||
TRACE_(dbghelp_symt)("Adding global label value %s:%s\n",
|
||||
debugstr_w(module->module.ModuleName), name);
|
||||
|
||||
if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
|
||||
{
|
||||
sym->symt.tag = SymTagLabel;
|
||||
sym->hash_elt.name = pool_strdup(&module->pool, name);
|
||||
hash_table_add(&module->ht_symbols, &sym->hash_elt);
|
||||
module->sortlist_valid = FALSE;
|
||||
sym->loc.kind = loc_absolute;
|
||||
sym->loc.offset = address;
|
||||
sym->parent = compiland ? &compiland->symt : NULL;
|
||||
if (compiland)
|
||||
{
|
||||
struct symt** p;
|
||||
p = vector_add(&compiland->vchildren, &module->pool);
|
||||
*p = &sym->symt;
|
||||
}
|
||||
}
|
||||
return sym;
|
||||
}
|
||||
|
||||
/* expect sym_info->MaxNameLen to be set before being called */
|
||||
static void symt_fill_sym_info(const struct module_pair* pair,
|
||||
const struct symt_function* func,
|
||||
|
|
|
@ -83,7 +83,7 @@ const char* symt_get_name(const struct symt* sym)
|
|||
case SymTagFunction: return ((const struct symt_function*)sym)->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_function_point*)sym)->name;
|
||||
case SymTagLabel: return ((const struct symt_hierarchy_point*)sym)->hash_elt.name;
|
||||
case SymTagThunk: return ((const struct symt_thunk*)sym)->hash_elt.name;
|
||||
/* hierarchy tree */
|
||||
case SymTagEnum: return ((const struct symt_enum*)sym)->name;
|
||||
|
@ -518,8 +518,10 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
|
|||
case SymTagFuncDebugStart:
|
||||
case SymTagFuncDebugEnd:
|
||||
case SymTagLabel:
|
||||
X(ULONG64) = ((const struct symt_function_point*)type)->parent->address +
|
||||
((const struct symt_function_point*)type)->loc.offset;
|
||||
if (!symt_get_info(((const struct symt_hierarchy_point*)type)->parent,
|
||||
req, pInfo))
|
||||
return FALSE;
|
||||
X(ULONG64) += ((const struct symt_hierarchy_point*)type)->loc.offset;
|
||||
break;
|
||||
case SymTagThunk:
|
||||
X(ULONG64) = ((const struct symt_thunk*)type)->address;
|
||||
|
@ -648,6 +650,9 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
|
|||
case SymTagThunk:
|
||||
X(DWORD64) = ((const struct symt_thunk*)type)->size;
|
||||
break;
|
||||
case SymTagLabel:
|
||||
X(DWORD64) = 0;
|
||||
break;
|
||||
default:
|
||||
FIXME("Unsupported sym-tag %s for get-length\n",
|
||||
symt_get_tag_str(type->tag));
|
||||
|
@ -768,6 +773,7 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
|
|||
symt_get_tag_str(type->tag));
|
||||
case SymTagPublicSymbol:
|
||||
case SymTagThunk:
|
||||
case SymTagLabel:
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue