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 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 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;
|
struct location loc;
|
||||||
const char* name; /* for labels */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct symt_public
|
struct symt_public
|
||||||
|
@ -548,7 +548,7 @@ extern struct symt_block*
|
||||||
symt_close_func_block(struct module* module,
|
symt_close_func_block(struct module* module,
|
||||||
struct symt_function* func,
|
struct symt_function* func,
|
||||||
struct symt_block* block, unsigned pc);
|
struct symt_block* block, unsigned pc);
|
||||||
extern struct symt_function_point*
|
extern struct symt_hierarchy_point*
|
||||||
symt_add_function_point(struct module* module,
|
symt_add_function_point(struct module* module,
|
||||||
struct symt_function* func,
|
struct symt_function* func,
|
||||||
enum SymTagEnum point,
|
enum SymTagEnum point,
|
||||||
|
@ -568,6 +568,10 @@ extern struct symt_data*
|
||||||
struct symt_compiland* parent,
|
struct symt_compiland* parent,
|
||||||
const char* name, struct symt* type,
|
const char* name, struct symt* type,
|
||||||
const VARIANT* v);
|
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 */
|
/* type.c */
|
||||||
extern void symt_init_basic(struct module* module);
|
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);
|
psym = vector_at(&func->vchildren, i);
|
||||||
if ((*psym)->tag == SymTagCustom)
|
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 */
|
/* First, recompute the frame information, if needed */
|
||||||
switch (pframe->kind)
|
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,
|
symt_add_function_point(msc_dbg->module, curr_func, SymTagLabel, &loc,
|
||||||
terminate_string(&sym->label_v1.p_name));
|
terminate_string(&sym->label_v1.p_name));
|
||||||
}
|
}
|
||||||
else
|
else symt_new_label(msc_dbg->module, compiland,
|
||||||
FIXME("No current function for label %s\n",
|
terminate_string(&sym->label_v1.p_name),
|
||||||
terminate_string(&sym->label_v1.p_name));
|
codeview_get_address(msc_dbg, sym->label_v1.segment, sym->label_v1.offset));
|
||||||
break;
|
break;
|
||||||
case S_LABEL_V3:
|
case S_LABEL_V3:
|
||||||
if (curr_func)
|
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,
|
symt_add_function_point(msc_dbg->module, curr_func, SymTagLabel,
|
||||||
&loc, sym->label_v3.name);
|
&loc, sym->label_v3.name);
|
||||||
}
|
}
|
||||||
else
|
else symt_new_label(msc_dbg->module, compiland, sym->label_v3.name,
|
||||||
FIXME("No current function for label %s\n", sym->label_v3.name);
|
codeview_get_address(msc_dbg, sym->label_v3.segment, sym->label_v3.offset));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_CONSTANT_V1:
|
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;
|
GET_ENTRY(block->container, struct symt_block, symt) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct symt_function_point* symt_add_function_point(struct module* module,
|
struct symt_hierarchy_point* symt_add_function_point(struct module* module,
|
||||||
struct symt_function* func,
|
struct symt_function* func,
|
||||||
enum SymTagEnum point,
|
enum SymTagEnum point,
|
||||||
const struct location* loc,
|
const struct location* loc,
|
||||||
const char* name)
|
const char* name)
|
||||||
{
|
{
|
||||||
struct symt_function_point* sym;
|
struct symt_hierarchy_point*sym;
|
||||||
struct symt** p;
|
struct symt** p;
|
||||||
|
|
||||||
if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
|
if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
|
||||||
{
|
{
|
||||||
sym->symt.tag = point;
|
sym->symt.tag = point;
|
||||||
sym->parent = func;
|
sym->parent = &func->symt;
|
||||||
sym->loc = *loc;
|
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 = vector_add(&func->vchildren, &module->pool);
|
||||||
*p = &sym->symt;
|
*p = &sym->symt;
|
||||||
}
|
}
|
||||||
|
@ -478,6 +478,34 @@ struct symt_data* symt_new_constant(struct module* module,
|
||||||
return sym;
|
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 */
|
/* expect sym_info->MaxNameLen to be set before being called */
|
||||||
static void symt_fill_sym_info(const struct module_pair* pair,
|
static void symt_fill_sym_info(const struct module_pair* pair,
|
||||||
const struct symt_function* func,
|
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 SymTagFunction: return ((const struct symt_function*)sym)->hash_elt.name;
|
||||||
case SymTagPublicSymbol: return ((const struct symt_public*)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 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;
|
case SymTagThunk: return ((const struct symt_thunk*)sym)->hash_elt.name;
|
||||||
/* hierarchy tree */
|
/* hierarchy tree */
|
||||||
case SymTagEnum: return ((const struct symt_enum*)sym)->name;
|
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 SymTagFuncDebugStart:
|
||||||
case SymTagFuncDebugEnd:
|
case SymTagFuncDebugEnd:
|
||||||
case SymTagLabel:
|
case SymTagLabel:
|
||||||
X(ULONG64) = ((const struct symt_function_point*)type)->parent->address +
|
if (!symt_get_info(((const struct symt_hierarchy_point*)type)->parent,
|
||||||
((const struct symt_function_point*)type)->loc.offset;
|
req, pInfo))
|
||||||
|
return FALSE;
|
||||||
|
X(ULONG64) += ((const struct symt_hierarchy_point*)type)->loc.offset;
|
||||||
break;
|
break;
|
||||||
case SymTagThunk:
|
case SymTagThunk:
|
||||||
X(ULONG64) = ((const struct symt_thunk*)type)->address;
|
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:
|
case SymTagThunk:
|
||||||
X(DWORD64) = ((const struct symt_thunk*)type)->size;
|
X(DWORD64) = ((const struct symt_thunk*)type)->size;
|
||||||
break;
|
break;
|
||||||
|
case SymTagLabel:
|
||||||
|
X(DWORD64) = 0;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
FIXME("Unsupported sym-tag %s for get-length\n",
|
FIXME("Unsupported sym-tag %s for get-length\n",
|
||||||
symt_get_tag_str(type->tag));
|
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));
|
symt_get_tag_str(type->tag));
|
||||||
case SymTagPublicSymbol:
|
case SymTagPublicSymbol:
|
||||||
case SymTagThunk:
|
case SymTagThunk:
|
||||||
|
case SymTagLabel:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue