mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-11-14 18:20:11 -08:00
use callee info to disambiguate overlapping sibling inline sites
This commit is contained in:
1 parent
8b52934c66
commit
3c719de3f5
3 files changed
+59
-11
No files matched your search
+1
-1
@@ -2409,7 +2409,7 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer
|
||||
LNK_ObjLineMap *line_map = line_maps[obj->input_idx];
|
||||
|
||||
// is reference inline site?
|
||||
LNK_InlineSite *inline_site = lnk_inline_site_from_section_offset(line_map, safe_cast_u32(section_number), reloc->apply_off);
|
||||
LNK_InlineSite *inline_site = lnk_inline_site_from_section_offset(line_map, safe_cast_u32(section_number), reloc->apply_off, symbol);
|
||||
if (inline_site && inline_site->name.size) {
|
||||
CV_Line *line_inline = lnk_line_from_inline_site(inline_site, reloc->apply_off);
|
||||
if (line_inline) {
|
||||
|
||||
+49
-3
@@ -1349,6 +1349,20 @@ lnk_line_map_from_obj(Arena *arena, LNK_Obj *obj)
|
||||
radsort(inline_site->lines, inline_site->line_count, cv_c13_voff_map_is_before);
|
||||
}
|
||||
}
|
||||
} else if (symbol.kind == CV_SymKind_CALLEES) {
|
||||
if (inline_site_stack_count && symbol.data.size >= sizeof(CV_SymFunctionList)) {
|
||||
CV_SymFunctionList *func_list = (CV_SymFunctionList *)symbol.data.str;
|
||||
U64 callee_count = Min(func_list->count, (symbol.data.size - sizeof(*func_list)) / sizeof(CV_ItemId));
|
||||
CV_ItemId *callees = (CV_ItemId *)(func_list + 1);
|
||||
|
||||
LNK_InlineSite *inline_site = &map->inline_sites[inline_site_stack[inline_site_stack_count - 1]];
|
||||
inline_site->callee_count = callee_count;
|
||||
inline_site->callee_names = push_array(arena, String8, callee_count);
|
||||
for EachIndex(callee_idx, callee_count) {
|
||||
String8 *callee_name = hash_map_search_u64_string(&inlinee_hm, callees[callee_idx]);
|
||||
inline_site->callee_names[callee_idx] = callee_name ? *callee_name : str8_zero();
|
||||
}
|
||||
}
|
||||
} else if (symbol.kind == CV_SymKind_INLINESITE_END) {
|
||||
if (inline_site_stack_count > 0) {
|
||||
inline_site_stack_count -= 1;
|
||||
@@ -1449,10 +1463,11 @@ lnk_lines_from_section_offset(LNK_ObjLineMap *map, U32 section_number, U32 offse
|
||||
}
|
||||
|
||||
internal LNK_InlineSite *
|
||||
lnk_inline_site_from_section_offset(LNK_ObjLineMap *map, U32 section_number, U32 offset)
|
||||
lnk_inline_site_from_section_offset(LNK_ObjLineMap *map, U32 section_number, U32 offset, LNK_Symbol *callee_symbol)
|
||||
{
|
||||
U64 key = Compose64Bit(section_number, offset);
|
||||
|
||||
// find upper bound
|
||||
U64 min = 0;
|
||||
U64 opl = map->inline_range_count;
|
||||
while (min < opl) {
|
||||
@@ -1464,21 +1479,52 @@ lnk_inline_site_from_section_offset(LNK_ObjLineMap *map, U32 section_number, U32
|
||||
}
|
||||
}
|
||||
|
||||
LNK_InlineSite *site = 0;
|
||||
// hacky demangle
|
||||
String8 callee_name = callee_symbol ? callee_symbol->name : str8_zero();
|
||||
if (str8_starts_with(callee_name, str8_lit("__imp_"))) {
|
||||
callee_name = str8_skip(callee_name, 6);
|
||||
}
|
||||
if (str8_starts_with(callee_name, str8_lit("?"))) {
|
||||
U64 name_opl = str8_find_needle(callee_name, 1, str8_lit("@"), 0);
|
||||
callee_name = str8_substr(callee_name, r1u64(1, name_opl));
|
||||
}
|
||||
|
||||
// scan back to the lower bound and match inline sites
|
||||
LNK_InlineSite *site = 0;
|
||||
LNK_InlineSite *callee_site = 0;
|
||||
B32 callee_site_is_ambiguous = 0;
|
||||
while (min > 0) {
|
||||
LNK_InlineRange *range = &map->inline_ranges[--min];
|
||||
if (key < range->key_max) {
|
||||
LNK_InlineSite *candidate = &map->inline_sites[range->site_idx];
|
||||
|
||||
if (site == 0 || site->depth < candidate->depth) {
|
||||
site = candidate;
|
||||
}
|
||||
|
||||
for EachIndex(callee_idx, candidate->callee_count) {
|
||||
String8 pdb_callee_name = candidate->callee_names[callee_idx];
|
||||
if (str8_match(callee_name, pdb_callee_name, 0)) {
|
||||
|
||||
// candidate matches callee
|
||||
if (callee_site == 0 || callee_site->depth < candidate->depth) {
|
||||
callee_site = candidate;
|
||||
callee_site_is_ambiguous = 0;
|
||||
} else if (candidate->depth == callee_site->depth && candidate != callee_site) {
|
||||
callee_site_is_ambiguous = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (min == 0 || map->inline_ranges[min - 1].prefix_max <= key) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return site;
|
||||
return (callee_site && !callee_site_is_ambiguous) ? callee_site : site;
|
||||
}
|
||||
|
||||
internal CV_Line *
|
||||
|
||||
@@ -115,12 +115,14 @@ typedef struct LNK_LineTable
|
||||
|
||||
typedef struct LNK_InlineSite
|
||||
{
|
||||
U32 parent_idx_plus_one;
|
||||
U32 depth;
|
||||
CV_ItemId inlinee;
|
||||
String8 name;
|
||||
U64 line_count;
|
||||
CV_Line *lines;
|
||||
U32 parent_idx_plus_one;
|
||||
U32 depth;
|
||||
CV_ItemId inlinee;
|
||||
String8 name;
|
||||
U64 callee_count;
|
||||
String8 *callee_names;
|
||||
U64 line_count;
|
||||
CV_Line *lines;
|
||||
} LNK_InlineSite;
|
||||
|
||||
typedef struct LNK_InlineRange
|
||||
@@ -254,6 +256,6 @@ internal U32 lnk_symbol_from_section_offset(LNK_ObjSymbolMap *map
|
||||
// CodeView map
|
||||
internal LNK_ObjLineMap * lnk_line_map_from_obj(Arena *arena, LNK_Obj *obj);
|
||||
internal CV_Line * lnk_lines_from_section_offset(LNK_ObjLineMap *map, U32 section_number, U32 offset, U64 *line_count_out);
|
||||
internal LNK_InlineSite * lnk_inline_site_from_section_offset(LNK_ObjLineMap *map, U32 section_number, U32 offset);
|
||||
internal LNK_InlineSite * lnk_inline_site_from_section_offset(LNK_ObjLineMap *map, U32 section_number, U32 offset, LNK_Symbol *callee_symbol);
|
||||
internal CV_Line * lnk_line_from_inline_site(LNK_InlineSite *site, U32 offset);
|
||||
|
||||
Reference in new issue
Block a user