processless debug info loading/unloading; separate modules from dbg infos in eval; keep dbg infos around after debugging via config, correllate to new modules, evict when necessary, when generating new versions

This commit is contained in:
Ryan Fleury
2025-10-22 16:39:29 -07:00
parent f9d1ffa5fc
commit c8c25c0f98
21 changed files with 1289 additions and 899 deletions
+26 -9
View File
@@ -3189,7 +3189,7 @@ ctrl_thread__entry_point(void *p)
CTRL_Entity *module = ctrl_entity_from_handle(entity_ctx, msg->entity); CTRL_Entity *module = ctrl_entity_from_handle(entity_ctx, msg->entity);
CTRL_Entity *debug_info_path = ctrl_entity_child_from_kind(module, CTRL_EntityKind_DebugInfoPath); CTRL_Entity *debug_info_path = ctrl_entity_child_from_kind(module, CTRL_EntityKind_DebugInfoPath);
DI_Key old_dbgi_key = di_key_from_path_timestamp(debug_info_path->string, debug_info_path->timestamp); DI_Key old_dbgi_key = di_key_from_path_timestamp(debug_info_path->string, debug_info_path->timestamp);
di_close(old_dbgi_key); di_close(old_dbgi_key, 0);
MutexScopeW(ctrl_state->ctrl_thread_entity_ctx_rw_mutex) MutexScopeW(ctrl_state->ctrl_thread_entity_ctx_rw_mutex)
{ {
ctrl_entity_equip_string(ctrl_state->ctrl_thread_entity_store, debug_info_path, path_normalized_from_string(scratch.arena, path)); ctrl_entity_equip_string(ctrl_state->ctrl_thread_entity_store, debug_info_path, path_normalized_from_string(scratch.arena, path));
@@ -4112,7 +4112,7 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg,
out_evt->entity = module_handle; out_evt->entity = module_handle;
out_evt->string = module_path; out_evt->string = module_path;
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module_ent); DI_Key dbgi_key = ctrl_dbgi_key_from_module(module_ent);
di_close(dbgi_key); di_close(dbgi_key, 0);
}break; }break;
case DMN_EventKind_DebugString: case DMN_EventKind_DebugString:
{ {
@@ -4274,15 +4274,19 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_UserBreakpointList *user_bps, C
U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr); U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr);
////////////////////////////// //////////////////////////////
//- rjf: gather evaluation modules //- rjf: gather evaluation debug infos & modules
// //
U64 eval_modules_count = Max(1, entity_ctx->entity_kind_counts[CTRL_EntityKind_Module]); U64 eval_modules_count = Max(1, entity_ctx->entity_kind_counts[CTRL_EntityKind_Module]);
E_Module *eval_modules = push_array(arena, E_Module, eval_modules_count); E_Module *eval_modules = push_array(arena, E_Module, eval_modules_count);
E_Module *eval_modules_primary = &eval_modules[0]; E_Module *eval_modules_primary = &eval_modules[0];
eval_modules_primary->rdi = &rdi_parsed_nil;
eval_modules_primary->vaddr_range = r1u64(0, max_U64); eval_modules_primary->vaddr_range = r1u64(0, max_U64);
U64 eval_dbg_infos_count = Max(1, entity_ctx->entity_kind_counts[CTRL_EntityKind_Module]);
E_DbgInfo *eval_dbg_infos = push_array(arena, E_DbgInfo, eval_dbg_infos_count);
E_DbgInfo *eval_dbg_infos_primary = &eval_dbg_infos[0];
MemoryCopyStruct(eval_dbg_infos_primary, &e_dbg_info_nil);
{ {
U64 eval_module_idx = 0; U64 eval_module_idx = 0;
U64 eval_dbg_info_idx = 0;
for(CTRL_Entity *machine = entity_ctx->root->first; for(CTRL_Entity *machine = entity_ctx->root->first;
machine != &ctrl_entity_nil; machine != &ctrl_entity_nil;
machine = machine->next) machine = machine->next)
@@ -4392,10 +4396,18 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_UserBreakpointList *user_bps, C
rdi = di_rdi_from_key(scope->access, dbgi_key, 1, max_U64); rdi = di_rdi_from_key(scope->access, dbgi_key, 1, max_U64);
} }
//- rjf: fill debug info
eval_dbg_infos[eval_dbg_info_idx].dbgi_key = dbgi_key;
eval_dbg_infos[eval_dbg_info_idx].rdi = rdi;
if(mod == module)
{
eval_dbg_infos_primary = &eval_dbg_infos[eval_dbg_info_idx];
}
eval_dbg_info_idx += 1;
//- rjf: fill evaluation module info //- rjf: fill evaluation module info
eval_modules[eval_module_idx].arch = arch; eval_modules[eval_module_idx].arch = arch;
eval_modules[eval_module_idx].dbgi_key = dbgi_key; eval_modules[eval_module_idx].dbg_info_num= (U32)eval_dbg_info_idx;
eval_modules[eval_module_idx].rdi = rdi;
eval_modules[eval_module_idx].vaddr_range = mod->vaddr_range; eval_modules[eval_module_idx].vaddr_range = mod->vaddr_range;
eval_modules[eval_module_idx].space = e_space_make(CTRL_EvalSpaceKind_Entity); eval_modules[eval_module_idx].space = e_space_make(CTRL_EvalSpaceKind_Entity);
eval_modules[eval_module_idx].space.u64_0 = (U64)process; eval_modules[eval_module_idx].space.u64_0 = (U64)process;
@@ -4427,6 +4439,11 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_UserBreakpointList *user_bps, C
ctx->thread_reg_space = e_space_make(CTRL_EvalSpaceKind_Entity); ctx->thread_reg_space = e_space_make(CTRL_EvalSpaceKind_Entity);
ctx->thread_reg_space.u64_0 = (U64)thread; ctx->thread_reg_space.u64_0 = (U64)thread;
//- rjf: fill debug infos
ctx->dbg_infos = eval_dbg_infos;
ctx->dbg_infos_count = eval_dbg_infos_count;
ctx->primary_dbg_info = eval_dbg_infos_primary;
//- rjf: fill modules //- rjf: fill modules
ctx->modules = eval_modules; ctx->modules = eval_modules;
ctx->modules_count = eval_modules_count; ctx->modules_count = eval_modules_count;
@@ -4445,8 +4462,8 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_UserBreakpointList *user_bps, C
E_IRCtx *ctx = &scope->ir_ctx; E_IRCtx *ctx = &scope->ir_ctx;
ctx->regs_map = ctrl_string2reg_from_arch(arch); ctx->regs_map = ctrl_string2reg_from_arch(arch);
ctx->reg_alias_map = ctrl_string2alias_from_arch(arch); ctx->reg_alias_map = ctrl_string2alias_from_arch(arch);
ctx->locals_map = e_push_locals_map_from_rdi_voff(arena, eval_modules_primary->rdi, thread_rip_voff); ctx->locals_map = e_push_locals_map_from_rdi_voff(arena, eval_dbg_infos_primary->rdi, thread_rip_voff);
ctx->member_map = e_push_member_map_from_rdi_voff(arena, eval_modules_primary->rdi, thread_rip_voff); ctx->member_map = e_push_member_map_from_rdi_voff(arena, eval_dbg_infos_primary->rdi, thread_rip_voff);
ctx->macro_map = push_array(arena, E_String2ExprMap, 1); ctx->macro_map = push_array(arena, E_String2ExprMap, 1);
ctx->macro_map[0] = e_string2expr_map_make(arena, 512); ctx->macro_map[0] = e_string2expr_map_make(arena, 512);
ctx->auto_hook_map = push_array(arena, E_AutoHookMap, 1); ctx->auto_hook_map = push_array(arena, E_AutoHookMap, 1);
@@ -4469,7 +4486,7 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_UserBreakpointList *user_bps, C
// TODO(rjf): need to compute this out here somehow... ctx->frame_base[0] = ; // TODO(rjf): need to compute this out here somehow... ctx->frame_base[0] = ;
ctx->tls_base = push_array(arena, U64, 1); ctx->tls_base = push_array(arena, U64, 1);
} }
e_select_interpret_ctx(&scope->interpret_ctx, eval_modules_primary->rdi, thread_rip_voff); e_select_interpret_ctx(&scope->interpret_ctx, eval_dbg_infos_primary->rdi, thread_rip_voff);
ProfEnd(); ProfEnd();
return scope; return scope;
+10
View File
@@ -1500,6 +1500,16 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
evt->code = event->u64_code; evt->code = event->u64_code;
}break; }break;
case CTRL_EventKind_NewModule:
{
D_EventNode *n = push_array(arena, D_EventNode, 1);
SLLQueuePush(result.first, result.last, n);
result.count += 1;
D_Event *evt = &n->v;
evt->kind = D_EventKind_ModuleLoad;
evt->module = event->entity;
}break;
//- rjf: debug strings //- rjf: debug strings
case CTRL_EventKind_DebugString: case CTRL_EventKind_DebugString:
+2
View File
@@ -86,6 +86,7 @@ struct D_TrapNet
typedef enum D_EventKind typedef enum D_EventKind
{ {
D_EventKind_Null, D_EventKind_Null,
D_EventKind_ModuleLoad,
D_EventKind_ProcessEnd, D_EventKind_ProcessEnd,
D_EventKind_Stop, D_EventKind_Stop,
D_EventKind_COUNT D_EventKind_COUNT
@@ -107,6 +108,7 @@ struct D_Event
{ {
D_EventKind kind; D_EventKind kind;
D_EventCause cause; D_EventCause cause;
CTRL_Handle module;
CTRL_Handle thread; CTRL_Handle thread;
U64 vaddr; U64 vaddr;
U64 code; U64 code;
+35 -2
View File
@@ -313,7 +313,7 @@ di_open(DI_Key key)
} }
internal void internal void
di_close(DI_Key key) di_close(DI_Key key, B32 force_closed)
{ {
//- rjf: unpack key //- rjf: unpack key
U64 hash = u64_hash_from_str8(str8_struct(&key)); U64 hash = u64_hash_from_str8(str8_struct(&key));
@@ -340,8 +340,15 @@ di_close(DI_Key key)
} }
} }
if(node) if(node)
{
if(force_closed)
{
node->refcount = 0;
}
else
{ {
node->refcount -= 1; node->refcount -= 1;
}
if(node->refcount == 0) if(node->refcount == 0)
{ {
for(;;) for(;;)
@@ -754,8 +761,31 @@ di_async_tick(void)
threads_available = (max_threads >= needed_threads); threads_available = (max_threads >= needed_threads);
} }
//- rjf: if this conversion will overwrite an RDI we already have in cache,
// then we need to evict the old one from the cache.
B32 ready_to_launch_conversion = (threads_available && !og_is_rdi && rdi_is_stale && t->thread_count != 0 && t->status != DI_LoadTaskStatus_Active);
if(ready_to_launch_conversion)
{
U64 path2key_hash = u64_hash_from_str8(og_path);
U64 path2key_slot_idx = path2key_hash%di_shared->path2key_slots_count;
DI_KeySlot *path2key_slot = &di_shared->path2key_slots[path2key_slot_idx];
Stripe *path2key_stripe = stripe_from_slot_idx(&di_shared->path2key_stripes, path2key_slot_idx);
RWMutexScope(path2key_stripe->rw_mutex, 0)
{
// NOTE(rjf): we need to iterate from last -> first, since we want to evict the
// most recent key.
for(DI_KeyPathNode *n = path2key_slot->last; n != 0; n = n->prev)
{
if(str8_match(n->path, og_path, 0) && !di_key_match(key, n->key))
{
di_close(n->key, 1);
}
}
}
}
//- rjf: launch conversion processes //- rjf: launch conversion processes
if(threads_available && !og_is_rdi && rdi_is_stale && t->thread_count != 0 && t->status != DI_LoadTaskStatus_Active) if(ready_to_launch_conversion)
{ {
B32 should_compress = 0; B32 should_compress = 0;
OS_ProcessLaunchParams params = {0}; OS_ProcessLaunchParams params = {0};
@@ -961,7 +991,10 @@ di_async_tick(void)
MemoryCopyStruct(&node->rdi, &rdi_parsed); MemoryCopyStruct(&node->rdi, &rdi_parsed);
node->completion_count += 1; node->completion_count += 1;
node->working_count -= 1; node->working_count -= 1;
if(node->rdi.raw_data_size != 0)
{
ins_atomic_u64_inc_eval(&di_shared->load_gen); ins_atomic_u64_inc_eval(&di_shared->load_gen);
}
ins_atomic_u64_inc_eval(&di_shared->load_count); ins_atomic_u64_inc_eval(&di_shared->load_count);
} }
else else
+1 -1
View File
@@ -323,7 +323,7 @@ internal DI_Key di_key_from_path_timestamp(String8 path, U64 min_timestamp);
//~ rjf: Debug Info Opening / Closing //~ rjf: Debug Info Opening / Closing
internal void di_open(DI_Key key); internal void di_open(DI_Key key);
internal void di_close(DI_Key key); internal void di_close(DI_Key key, B32 force_closed);
//////////////////////////////// ////////////////////////////////
//~ rjf: Debug Info Lookups //~ rjf: Debug Info Lookups
+17 -1
View File
@@ -678,6 +678,8 @@ e_select_base_ctx(E_BaseCtx *ctx)
//- rjf: select base context //- rjf: select base context
if(ctx->modules == 0) { ctx->modules = &e_module_nil; } if(ctx->modules == 0) { ctx->modules = &e_module_nil; }
if(ctx->primary_module == 0) { ctx->primary_module = &e_module_nil; } if(ctx->primary_module == 0) { ctx->primary_module = &e_module_nil; }
if(ctx->dbg_infos == 0) { ctx->dbg_infos = &e_dbg_info_nil; }
if(ctx->primary_dbg_info == 0) { ctx->primary_dbg_info = &e_dbg_info_nil; }
e_base_ctx = ctx; e_base_ctx = ctx;
//- rjf: reset the evaluation cache //- rjf: reset the evaluation cache
@@ -718,7 +720,7 @@ e_select_base_ctx(E_BaseCtx *ctx)
.id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(folder), .id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(folder),
.num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(folder), .num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(folder),
}); });
e_cache->thread_ip_procedure = rdi_procedure_from_voff(e_base_ctx->primary_module->rdi, e_base_ctx->thread_ip_voff); e_cache->thread_ip_procedure = rdi_procedure_from_voff(e_base_ctx->primary_dbg_info->rdi, e_base_ctx->thread_ip_voff);
e_cache->used_expr_map = push_array(e_cache->arena, E_UsedExprMap, 1); e_cache->used_expr_map = push_array(e_cache->arena, E_UsedExprMap, 1);
e_cache->used_expr_map->slots_count = 64; e_cache->used_expr_map->slots_count = 64;
e_cache->used_expr_map->slots = push_array(e_cache->arena, E_UsedExprSlot, e_cache->used_expr_map->slots_count); e_cache->used_expr_map->slots = push_array(e_cache->arena, E_UsedExprSlot, e_cache->used_expr_map->slots_count);
@@ -744,6 +746,20 @@ e_select_ir_ctx(E_IRCtx *ctx)
e_ir_ctx = ctx; e_ir_ctx = ctx;
} }
////////////////////////////////
//~ rjf: Context Accessors
internal E_DbgInfo *
e_dbg_info_from_module(E_Module *module)
{
E_DbgInfo *result = &e_dbg_info_nil;
if(0 < module->dbg_info_num && module->dbg_info_num <= e_base_ctx->dbg_infos_count)
{
result = &e_base_ctx->dbg_infos[module->dbg_info_num-1];
}
return result;
}
//////////////////////////////// ////////////////////////////////
//~ rjf: Cache Accessing Functions //~ rjf: Cache Accessing Functions
+23 -3
View File
@@ -564,15 +564,24 @@ struct E_ConsTypeSlot
E_ConsTypeNode *last; E_ConsTypeNode *last;
}; };
////////////////////////////////
//~ rjf: Debug Info
typedef struct E_DbgInfo E_DbgInfo;
struct E_DbgInfo
{
DI_Key dbgi_key;
RDI_Parsed *rdi;
};
//////////////////////////////// ////////////////////////////////
//~ rjf: Modules //~ rjf: Modules
typedef struct E_Module E_Module; typedef struct E_Module E_Module;
struct E_Module struct E_Module
{ {
DI_Key dbgi_key;
RDI_Parsed *rdi;
Rng1U64 vaddr_range; Rng1U64 vaddr_range;
U32 dbg_info_num;
Arch arch; Arch arch;
E_Space space; E_Space space;
}; };
@@ -760,6 +769,11 @@ struct E_BaseCtx
Arch thread_arch; Arch thread_arch;
U64 thread_unwind_count; U64 thread_unwind_count;
// rjf: debug infos
E_DbgInfo *dbg_infos;
U64 dbg_infos_count;
E_DbgInfo *primary_dbg_info;
// rjf: modules // rjf: modules
E_Module *modules; E_Module *modules;
U64 modules_count; U64 modules_count;
@@ -1111,7 +1125,8 @@ read_only global E_String2ExprMap e_string2expr_map_nil = {0};
read_only global E_Expr e_expr_nil = {&e_expr_nil, &e_expr_nil, &e_expr_nil, &e_expr_nil, &e_expr_nil}; read_only global E_Expr e_expr_nil = {&e_expr_nil, &e_expr_nil, &e_expr_nil, &e_expr_nil, &e_expr_nil};
read_only global E_IRNode e_irnode_nil = {&e_irnode_nil, &e_irnode_nil, &e_irnode_nil}; read_only global E_IRNode e_irnode_nil = {&e_irnode_nil, &e_irnode_nil, &e_irnode_nil};
read_only global E_Eval e_eval_nil = {{0}, {0}, {0}, &e_expr_nil, {&e_irnode_nil}}; read_only global E_Eval e_eval_nil = {{0}, {0}, {0}, &e_expr_nil, {&e_irnode_nil}};
read_only global E_Module e_module_nil = {{0}, &rdi_parsed_nil}; read_only global E_DbgInfo e_dbg_info_nil = {{0}, &rdi_parsed_nil};
read_only global E_Module e_module_nil = {0};
read_only global E_CacheBundle e_cache_bundle_nil = {0, {0}, {0}, {0}, {{0}, 0, &e_expr_nil, &e_expr_nil}, {&e_irnode_nil}}; read_only global E_CacheBundle e_cache_bundle_nil = {0, {0}, {0}, {0}, {{0}, 0, &e_expr_nil, &e_expr_nil}, {&e_irnode_nil}};
thread_static E_BaseCtx *e_base_ctx = 0; thread_static E_BaseCtx *e_base_ctx = 0;
thread_static E_IRCtx *e_ir_ctx = 0; thread_static E_IRCtx *e_ir_ctx = 0;
@@ -1203,6 +1218,11 @@ internal void e_select_cache(E_Cache *cache);
internal void e_select_base_ctx(E_BaseCtx *ctx); internal void e_select_base_ctx(E_BaseCtx *ctx);
internal void e_select_ir_ctx(E_IRCtx *ctx); internal void e_select_ir_ctx(E_IRCtx *ctx);
////////////////////////////////
//~ rjf: Context Accessors
internal E_DbgInfo *e_dbg_info_from_module(E_Module *module);
//////////////////////////////// ////////////////////////////////
//~ rjf: Base Cache Accessing Functions //~ rjf: Base Cache Accessing Functions
// //
+44 -32
View File
@@ -968,28 +968,27 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist);
E_Interpretation interpretation = e_interpret(bytecode); E_Interpretation interpretation = e_interpret(bytecode);
E_Module *module = &e_module_nil; E_Module *module = &e_module_nil;
U32 rdi_idx = 0;
for EachIndex(idx, e_base_ctx->modules_count) for EachIndex(idx, e_base_ctx->modules_count)
{ {
E_Module *m = &e_base_ctx->modules[idx]; E_Module *m = &e_base_ctx->modules[idx];
if(e_space_match(interpretation.space, m->space) && contains_1u64(m->vaddr_range, interpretation.value.u64)) if(e_space_match(interpretation.space, m->space) && contains_1u64(m->vaddr_range, interpretation.value.u64))
{ {
module = m; module = m;
rdi_idx = (U32)idx;
break; break;
} }
} }
if(module != &e_module_nil) if(module != &e_module_nil)
{ {
E_DbgInfo *dbg_info = e_dbg_info_from_module(module);
U64 voff = interpretation.value.u64 - module->vaddr_range.min; U64 voff = interpretation.value.u64 - module->vaddr_range.min;
U64 new_vaddr = 0; U64 new_vaddr = 0;
RDI_Procedure *p = rdi_procedure_from_voff(module->rdi, voff); RDI_Procedure *p = rdi_procedure_from_voff(dbg_info->rdi, voff);
RDI_GlobalVariable *g = rdi_global_variable_from_voff(module->rdi, voff); RDI_GlobalVariable *g = rdi_global_variable_from_voff(dbg_info->rdi, voff);
U32 type_idx = 0; U32 type_idx = 0;
if(p->name_string_idx != 0) if(p->name_string_idx != 0)
{ {
type_idx = p->type_idx; type_idx = p->type_idx;
new_vaddr = module->vaddr_range.min + rdi_first_voff_from_procedure(module->rdi, p); new_vaddr = module->vaddr_range.min + rdi_first_voff_from_procedure(dbg_info->rdi, p);
} }
else if(g->name_string_idx != 0) else if(g->name_string_idx != 0)
{ {
@@ -998,10 +997,10 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
} }
if(type_idx != 0) if(type_idx != 0)
{ {
RDI_TypeNode *t = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); RDI_TypeNode *t = rdi_element_from_name_idx(dbg_info->rdi, TypeNodes, type_idx);
result.root = e_irtree_const_u(arena, new_vaddr); result.root = e_irtree_const_u(arena, new_vaddr);
result.mode = E_Mode_Value; result.mode = E_Mode_Value;
result.type_key = e_type_key_ext(e_type_kind_from_rdi(t->kind), type_idx, rdi_idx); result.type_key = e_type_key_ext(e_type_kind_from_rdi(t->kind), type_idx, module->dbg_info_num);
} }
} }
}break; }break;
@@ -1797,12 +1796,12 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("member"), 0))) if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("member"), 0)))
{ {
E_Module *module = e_base_ctx->primary_module; E_Module *module = e_base_ctx->primary_module;
U32 module_idx = (U32)(module - e_base_ctx->modules); E_DbgInfo *dbg_info = e_dbg_info_from_module(module);
RDI_Parsed *rdi = module->rdi; RDI_Parsed *rdi = dbg_info->rdi;
RDI_Procedure *procedure = e_cache->thread_ip_procedure; RDI_Procedure *procedure = e_cache->thread_ip_procedure;
RDI_UDT *udt = rdi_container_udt_from_procedure(rdi, procedure); RDI_UDT *udt = rdi_container_udt_from_procedure(rdi, procedure);
RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, udt->self_type_idx); RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, udt->self_type_idx);
E_TypeKey container_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, module_idx); E_TypeKey container_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, module->dbg_info_num);
E_Member member = e_type_member_from_key_name__cached(container_type_key, string); E_Member member = e_type_member_from_key_name__cached(container_type_key, string);
if(member.kind != E_MemberKind_Null) if(member.kind != E_MemberKind_Null)
{ {
@@ -1816,8 +1815,8 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("local"), 0))) if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("local"), 0)))
{ {
E_Module *module = e_base_ctx->primary_module; E_Module *module = e_base_ctx->primary_module;
U32 module_idx = (U32)(module - e_base_ctx->modules); E_DbgInfo *dbg_info = e_dbg_info_from_module(module);
RDI_Parsed *rdi = module->rdi; RDI_Parsed *rdi = dbg_info->rdi;
U64 local_num = e_num_from_string(e_ir_ctx->locals_map, string__redirected); U64 local_num = e_num_from_string(e_ir_ctx->locals_map, string__redirected);
if(local_num != 0) if(local_num != 0)
{ {
@@ -1825,7 +1824,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
// rjf: extract local's type key // rjf: extract local's type key
RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, local->type_idx); RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, local->type_idx);
mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), local->type_idx, module_idx); mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), local->type_idx, module->dbg_info_num);
// rjf: extract local's location block // rjf: extract local's location block
B32 got_location_block = 0; B32 got_location_block = 0;
@@ -1892,13 +1891,14 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
Access *access = access_open(); Access *access = access_open();
// rjf: find match // rjf: find match
DI_Match match = di_match_from_string(string, 0, e_base_ctx->primary_module->dbgi_key, 0); DI_Match match = di_match_from_string(string, 0, e_base_ctx->primary_dbg_info->dbgi_key, 0);
if(match.idx == 0) if(match.idx == 0)
{ {
String8List namespaceified_strings = {0}; String8List namespaceified_strings = {0};
{ {
E_Module *module = e_base_ctx->primary_module; E_Module *module = e_base_ctx->primary_module;
RDI_Parsed *rdi = module->rdi; E_DbgInfo *dbg_info = e_dbg_info_from_module(module);
RDI_Parsed *rdi = dbg_info->rdi;
RDI_Procedure *procedure = e_cache->thread_ip_procedure; RDI_Procedure *procedure = e_cache->thread_ip_procedure;
U64 name_size = 0; U64 name_size = 0;
U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size);
@@ -1921,7 +1921,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
} }
for(String8Node *n = namespaceified_strings.first; n != 0; n = n->next) for(String8Node *n = namespaceified_strings.first; n != 0; n = n->next)
{ {
match = di_match_from_string(n->string, 0, e_base_ctx->primary_module->dbgi_key, 0); match = di_match_from_string(n->string, 0, e_base_ctx->primary_dbg_info->dbgi_key, 0);
if(match.idx != 0) if(match.idx != 0)
{ {
break; break;
@@ -1932,17 +1932,27 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
// rjf: match -> RDI // rjf: match -> RDI
RDI_Parsed *rdi = di_rdi_from_key(access, match.key, 0, 0); RDI_Parsed *rdi = di_rdi_from_key(access, match.key, 0, 0);
// rjf: find dbg info from rdi
E_DbgInfo *dbg_info = &e_dbg_info_nil;
U32 dbg_info_num = 0;
for EachIndex(idx, e_base_ctx->dbg_infos_count)
{
if(e_base_ctx->dbg_infos[idx].rdi == rdi)
{
dbg_info = &e_base_ctx->dbg_infos[idx];
dbg_info_num = idx+1;
break;
}
}
// rjf: find module from dbgi key // rjf: find module from dbgi key
U32 dbgi_idx = 0;
E_Module *module = &e_module_nil; E_Module *module = &e_module_nil;
for EachIndex(idx, e_base_ctx->modules_count) for EachIndex(idx, e_base_ctx->modules_count)
{ {
if(e_base_ctx->modules[idx].rdi == rdi) if(e_base_ctx->modules[idx].dbg_info_num == dbg_info_num)
{ {
module = &e_base_ctx->modules[idx]; module = &e_base_ctx->modules[idx];
dbgi_idx = (U32)idx; if(module == e_base_ctx->primary_module || e_space_match(module->space, e_base_ctx->primary_module->space))
if(module == e_base_ctx->primary_module ||
e_space_match(module->space, e_base_ctx->primary_module->space))
{ {
break; break;
} }
@@ -1950,7 +1960,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
} }
// rjf: form result // rjf: form result
if(match.idx != 0 && module != &e_module_nil) if(match.idx != 0 && dbg_info != &e_dbg_info_nil)
{ {
switch(match.section_kind) switch(match.section_kind)
{ {
@@ -1963,7 +1973,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
E_OpList oplist = {0}; E_OpList oplist = {0};
e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + global_var->voff)); e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + global_var->voff));
string_mapped = 1; string_mapped = 1;
mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, dbgi_idx); mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, dbg_info_num);
mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); mapped_bytecode = e_bytecode_from_oplist(arena, &oplist);
mapped_bytecode_mode = E_Mode_Offset; mapped_bytecode_mode = E_Mode_Offset;
mapped_bytecode_space = module->space; mapped_bytecode_space = module->space;
@@ -1976,7 +1986,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
E_OpList oplist = {0}; E_OpList oplist = {0};
e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(thread_var->tls_off)); e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(thread_var->tls_off));
string_mapped = 1; string_mapped = 1;
mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, dbgi_idx); mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, dbg_info_num);
mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); mapped_bytecode = e_bytecode_from_oplist(arena, &oplist);
mapped_bytecode_mode = E_Mode_Offset; mapped_bytecode_mode = E_Mode_Offset;
mapped_bytecode_space = module->space; mapped_bytecode_space = module->space;
@@ -1999,7 +2009,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
E_OpList oplist = {0}; E_OpList oplist = {0};
e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(value)); e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(value));
string_mapped = 1; string_mapped = 1;
mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, dbgi_idx); mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, dbg_info_num);
mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); mapped_bytecode = e_bytecode_from_oplist(arena, &oplist);
mapped_bytecode_mode = E_Mode_Value; mapped_bytecode_mode = E_Mode_Value;
mapped_bytecode_space = module->space; mapped_bytecode_space = module->space;
@@ -2017,7 +2027,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
E_OpList oplist = {0}; E_OpList oplist = {0};
e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff));
string_mapped = 1; string_mapped = 1;
mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, dbgi_idx); mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, dbg_info_num);
mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); mapped_bytecode = e_bytecode_from_oplist(arena, &oplist);
mapped_bytecode_mode = E_Mode_Value; mapped_bytecode_mode = E_Mode_Value;
mapped_bytecode_space = module->space; mapped_bytecode_space = module->space;
@@ -2026,7 +2036,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
{ {
U32 type_idx = match.idx; U32 type_idx = match.idx;
RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx);
mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, dbgi_idx); mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, dbg_info_num);
string_mapped = 1; string_mapped = 1;
}break; }break;
} }
@@ -2111,9 +2121,10 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
if(!generated && mapped_location_block != 0) if(!generated && mapped_location_block != 0)
{ {
E_Module *module = mapped_location_block_module; E_Module *module = mapped_location_block_module;
E_DbgInfo *dbg_info = e_dbg_info_from_module(module);
E_Space space = module->space; E_Space space = module->space;
Arch arch = module->arch; Arch arch = module->arch;
RDI_Parsed *rdi = module->rdi; RDI_Parsed *rdi = dbg_info->rdi;
RDI_LocationBlock *block = mapped_location_block; RDI_LocationBlock *block = mapped_location_block;
U64 all_location_data_size = 0; U64 all_location_data_size = 0;
U8 *all_location_data = rdi_table_from_name(rdi, LocationData, &all_location_data_size); U8 *all_location_data = rdi_table_from_name(rdi, LocationData, &all_location_data_size);
@@ -2466,17 +2477,18 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
if(e_space_read(interpret.space, &vtable_vaddr, r1u64(class_base_vaddr, class_base_vaddr+addr_size))) if(e_space_read(interpret.space, &vtable_vaddr, r1u64(class_base_vaddr, class_base_vaddr+addr_size)))
{ {
Arch arch = e_base_ctx->primary_module->arch; Arch arch = e_base_ctx->primary_module->arch;
U32 rdi_idx = 0; U32 dbg_info_num = 0;
RDI_Parsed *rdi = 0; RDI_Parsed *rdi = 0;
U64 module_base = 0; U64 module_base = 0;
for(U64 idx = 0; idx < e_base_ctx->modules_count; idx += 1) for(U64 idx = 0; idx < e_base_ctx->modules_count; idx += 1)
{ {
if(contains_1u64(e_base_ctx->modules[idx].vaddr_range, vtable_vaddr)) if(contains_1u64(e_base_ctx->modules[idx].vaddr_range, vtable_vaddr))
{ {
E_DbgInfo *dbg_info = e_dbg_info_from_module(&e_base_ctx->modules[idx]);
arch = e_base_ctx->modules[idx].arch; arch = e_base_ctx->modules[idx].arch;
rdi_idx = (U32)idx;
rdi = e_base_ctx->modules[idx].rdi;
module_base = e_base_ctx->modules[idx].vaddr_range.min; module_base = e_base_ctx->modules[idx].vaddr_range.min;
dbg_info_num = e_base_ctx->modules[idx].dbg_info_num;
rdi = dbg_info->rdi;
break; break;
} }
} }
@@ -2489,7 +2501,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
{ {
RDI_UDT *udt = rdi_element_from_name_idx(rdi, UDTs, global_var->container_idx); RDI_UDT *udt = rdi_element_from_name_idx(rdi, UDTs, global_var->container_idx);
RDI_TypeNode *type = rdi_element_from_name_idx(rdi, TypeNodes, udt->self_type_idx); RDI_TypeNode *type = rdi_element_from_name_idx(rdi, TypeNodes, udt->self_type_idx);
E_TypeKey derived_type_key = e_type_key_ext(e_type_kind_from_rdi(type->kind), udt->self_type_idx, rdi_idx); E_TypeKey derived_type_key = e_type_key_ext(e_type_kind_from_rdi(type->kind), udt->self_type_idx, dbg_info_num);
E_TypeKey ptr_to_derived_type_key = e_type_key_cons_ptr(arch, derived_type_key, 1, 0); E_TypeKey ptr_to_derived_type_key = e_type_key_cons_ptr(arch, derived_type_key, 1, 0);
result.type_key = ptr_to_derived_type_key; result.type_key = ptr_to_derived_type_key;
} }
+5 -5
View File
@@ -585,19 +585,19 @@ e_leaf_type_key_from_name(String8 name)
E_TypeKey key = e_leaf_builtin_type_key_from_name(name); E_TypeKey key = e_leaf_builtin_type_key_from_name(name);
if(!e_type_key_match(e_type_key_zero(), key)) if(!e_type_key_match(e_type_key_zero(), key))
{ {
DI_Match match = di_match_from_string(name, 0, e_base_ctx->primary_module->dbgi_key, 0); DI_Match match = di_match_from_string(name, 0, e_base_ctx->primary_dbg_info->dbgi_key, 0);
if(match.section_kind == RDI_SectionKind_TypeNodes) if(match.section_kind == RDI_SectionKind_TypeNodes)
{ {
Access *access = access_open(); Access *access = access_open();
RDI_Parsed *rdi = di_rdi_from_key(access, match.key, 0, 0); RDI_Parsed *rdi = di_rdi_from_key(access, match.key, 0, 0);
for EachIndex(idx, e_base_ctx->modules_count) for EachIndex(idx, e_base_ctx->dbg_infos_count)
{ {
E_Module *module = &e_base_ctx->modules[idx]; E_DbgInfo *dbg_info = &e_base_ctx->dbg_infos[idx];
if(module->rdi == rdi) if(dbg_info->rdi == rdi)
{ {
U32 type_idx = match.idx; U32 type_idx = match.idx;
RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx);
key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)idx); key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)idx+1);
break; break;
} }
} }
+37 -29
View File
@@ -271,7 +271,7 @@ e_type_key_basic(E_TypeKind kind)
} }
internal E_TypeKey internal E_TypeKey
e_type_key_ext(E_TypeKind kind, U32 type_idx, U32 rdi_idx) e_type_key_ext(E_TypeKind kind, U32 type_idx, U32 rdi_num)
{ {
E_TypeKey key = {E_TypeKeyKind_Ext}; E_TypeKey key = {E_TypeKeyKind_Ext};
key.u32[0] = (U32)kind; key.u32[0] = (U32)kind;
@@ -282,7 +282,7 @@ e_type_key_ext(E_TypeKind kind, U32 type_idx, U32 rdi_idx)
else else
{ {
key.u32[1] = type_idx; key.u32[1] = type_idx;
key.u32[2] = rdi_idx; key.u32[2] = rdi_num;
} }
return key; return key;
} }
@@ -646,10 +646,13 @@ e_type_byte_size_from_key(E_TypeKey key)
case E_TypeKeyKind_Ext: case E_TypeKeyKind_Ext:
{ {
U64 type_node_idx = key.u32[1]; U64 type_node_idx = key.u32[1];
U32 rdi_idx = key.u32[2]; U32 rdi_num = key.u32[2];
RDI_Parsed *rdi = e_base_ctx->modules[rdi_idx].rdi; if(0 < rdi_num && rdi_num <= e_base_ctx->dbg_infos_count)
{
RDI_Parsed *rdi = e_base_ctx->dbg_infos[rdi_num-1].rdi;
RDI_TypeNode *rdi_type = rdi_element_from_name_idx(rdi, TypeNodes, type_node_idx); RDI_TypeNode *rdi_type = rdi_element_from_name_idx(rdi, TypeNodes, type_node_idx);
result = rdi_type->byte_size; result = rdi_type->byte_size;
}
}break; }break;
case E_TypeKeyKind_Cons: case E_TypeKeyKind_Cons:
{ {
@@ -758,8 +761,12 @@ e_push_type_from_key(Arena *arena, E_TypeKey key)
case E_TypeKeyKind_Ext: case E_TypeKeyKind_Ext:
{ {
U64 type_node_idx = key.u32[1]; U64 type_node_idx = key.u32[1];
U32 rdi_idx = key.u32[2]; U32 rdi_num = key.u32[2];
RDI_Parsed *rdi = e_base_ctx->modules[rdi_idx].rdi; if(0 < rdi_num && rdi_num <= e_base_ctx->dbg_infos_count)
{
RDI_Parsed *rdi = e_base_ctx->dbg_infos[rdi_num-1].rdi;
RDI_TopLevelInfo *tli = rdi_element_from_name_idx(rdi, TopLevelInfo, 0);
Arch arch = arch_from_rdi_arch(tli->arch);
RDI_TypeNode *rdi_type = rdi_element_from_name_idx(rdi, TypeNodes, type_node_idx); RDI_TypeNode *rdi_type = rdi_element_from_name_idx(rdi, TypeNodes, type_node_idx);
if(rdi_type->kind != RDI_TypeKind_NULL) if(rdi_type->kind != RDI_TypeKind_NULL)
{ {
@@ -793,7 +800,7 @@ e_push_type_from_key(Arena *arena, E_TypeKey key)
member_type_kind = e_type_kind_from_rdi(member_type->kind); member_type_kind = e_type_kind_from_rdi(member_type->kind);
E_Member *dst = &members[member_idx-udt->member_first]; E_Member *dst = &members[member_idx-udt->member_first];
dst->kind = e_member_kind_from_rdi(src->kind); dst->kind = e_member_kind_from_rdi(src->kind);
dst->type_key = e_type_key_ext(member_type_kind, src->type_idx, rdi_idx); dst->type_key = e_type_key_ext(member_type_kind, src->type_idx, rdi_num);
dst->name.str = rdi_string_from_idx(rdi, src->name_string_idx, &dst->name.size); dst->name.str = rdi_string_from_idx(rdi, src->name_string_idx, &dst->name.size);
dst->off = (U64)src->off; dst->off = (U64)src->off;
} }
@@ -806,7 +813,7 @@ e_push_type_from_key(Arena *arena, E_TypeKey key)
type->name = push_str8_copy(arena, name); type->name = push_str8_copy(arena, name);
type->byte_size = (U64)rdi_type->byte_size; type->byte_size = (U64)rdi_type->byte_size;
type->count = members_count; type->count = members_count;
type->arch = e_base_ctx->modules[rdi_idx].arch; type->arch = arch;
type->members = members; type->members = members;
} }
@@ -823,7 +830,7 @@ e_push_type_from_key(Arena *arena, E_TypeKey key)
{ {
RDI_TypeNode *direct_type_node = rdi_element_from_name_idx(rdi, TypeNodes, rdi_type->user_defined.direct_type_idx); RDI_TypeNode *direct_type_node = rdi_element_from_name_idx(rdi, TypeNodes, rdi_type->user_defined.direct_type_idx);
E_TypeKind direct_type_kind = e_type_kind_from_rdi(direct_type_node->kind); E_TypeKind direct_type_kind = e_type_kind_from_rdi(direct_type_node->kind);
direct_type_key = e_type_key_ext(direct_type_kind, rdi_type->user_defined.direct_type_idx, rdi_idx); direct_type_key = e_type_key_ext(direct_type_kind, rdi_type->user_defined.direct_type_idx, rdi_num);
} }
// rjf: unpack members // rjf: unpack members
@@ -851,7 +858,7 @@ e_push_type_from_key(Arena *arena, E_TypeKey key)
type->name = push_str8_copy(arena, name); type->name = push_str8_copy(arena, name);
type->byte_size = (U64)rdi_type->byte_size; type->byte_size = (U64)rdi_type->byte_size;
type->count = enum_vals_count; type->count = enum_vals_count;
type->arch = e_base_ctx->modules[rdi_idx].arch; type->arch = arch;
type->enum_vals = enum_vals; type->enum_vals = enum_vals;
type->direct_type_key = direct_type_key; type->direct_type_key = direct_type_key;
} }
@@ -867,7 +874,7 @@ e_push_type_from_key(Arena *arena, E_TypeKey key)
{ {
RDI_TypeNode *direct_type_node = rdi_element_from_name_idx(rdi, TypeNodes, rdi_type->constructed.direct_type_idx); RDI_TypeNode *direct_type_node = rdi_element_from_name_idx(rdi, TypeNodes, rdi_type->constructed.direct_type_idx);
E_TypeKind direct_type_kind = e_type_kind_from_rdi(direct_type_node->kind); E_TypeKind direct_type_kind = e_type_kind_from_rdi(direct_type_node->kind);
direct_type_key = e_type_key_ext(direct_type_kind, rdi_type->constructed.direct_type_idx, rdi_idx); direct_type_key = e_type_key_ext(direct_type_kind, rdi_type->constructed.direct_type_idx, rdi_num);
direct_type_is_good = 1; direct_type_is_good = 1;
direct_type_byte_size = (U64)direct_type_node->byte_size; direct_type_byte_size = (U64)direct_type_node->byte_size;
} }
@@ -895,7 +902,7 @@ e_push_type_from_key(Arena *arena, E_TypeKey key)
type->direct_type_key = direct_type_key; type->direct_type_key = direct_type_key;
type->byte_size = direct_type_byte_size; type->byte_size = direct_type_byte_size;
type->flags = flags; type->flags = flags;
type->arch = e_base_ctx->modules[rdi_idx].arch; type->arch = arch;
}break; }break;
case RDI_TypeKind_Ptr: case RDI_TypeKind_Ptr:
case RDI_TypeKind_LRef: case RDI_TypeKind_LRef:
@@ -904,9 +911,9 @@ e_push_type_from_key(Arena *arena, E_TypeKey key)
type = push_array(arena, E_Type, 1); type = push_array(arena, E_Type, 1);
type->kind = kind; type->kind = kind;
type->direct_type_key = direct_type_key; type->direct_type_key = direct_type_key;
type->byte_size = bit_size_from_arch(e_base_ctx->modules[rdi_idx].arch)/8; type->byte_size = bit_size_from_arch(arch)/8;
type->count = 1; type->count = 1;
type->arch = e_base_ctx->modules[rdi_idx].arch; type->arch = arch;
}break; }break;
case RDI_TypeKind_Array: case RDI_TypeKind_Array:
@@ -916,7 +923,7 @@ e_push_type_from_key(Arena *arena, E_TypeKey key)
type->direct_type_key = direct_type_key; type->direct_type_key = direct_type_key;
type->count = rdi_type->constructed.count; type->count = rdi_type->constructed.count;
type->byte_size = direct_type_byte_size * type->count; type->byte_size = direct_type_byte_size * type->count;
type->arch = e_base_ctx->modules[rdi_idx].arch; type->arch = arch;
}break; }break;
case RDI_TypeKind_Function: case RDI_TypeKind_Function:
{ {
@@ -928,11 +935,11 @@ e_push_type_from_key(Arena *arena, E_TypeKey key)
{ {
type = push_array(arena, E_Type, 1); type = push_array(arena, E_Type, 1);
type->kind = kind; type->kind = kind;
type->byte_size = bit_size_from_arch(e_base_ctx->modules[rdi_idx].arch)/8; type->byte_size = bit_size_from_arch(arch)/8;
type->direct_type_key = direct_type_key; type->direct_type_key = direct_type_key;
type->count = count; type->count = count;
type->param_type_keys = push_array(arena, E_TypeKey, type->count); type->param_type_keys = push_array(arena, E_TypeKey, type->count);
type->arch = e_base_ctx->modules[rdi_idx].arch; type->arch = arch;
for(U32 idx = 0; idx < type->count; idx += 1) for(U32 idx = 0; idx < type->count; idx += 1)
{ {
U32 param_type_idx = idx_run[idx]; U32 param_type_idx = idx_run[idx];
@@ -940,7 +947,7 @@ e_push_type_from_key(Arena *arena, E_TypeKey key)
{ {
RDI_TypeNode *param_type_node = rdi_element_from_name_idx(rdi, TypeNodes, param_type_idx); RDI_TypeNode *param_type_node = rdi_element_from_name_idx(rdi, TypeNodes, param_type_idx);
E_TypeKind param_kind = e_type_kind_from_rdi(param_type_node->kind); E_TypeKind param_kind = e_type_kind_from_rdi(param_type_node->kind);
type->param_type_keys[idx] = e_type_key_ext(param_kind, param_type_idx, rdi_idx); type->param_type_keys[idx] = e_type_key_ext(param_kind, param_type_idx, rdi_num);
} }
else else
{ {
@@ -962,11 +969,11 @@ e_push_type_from_key(Arena *arena, E_TypeKey key)
{ {
type = push_array(arena, E_Type, 1); type = push_array(arena, E_Type, 1);
type->kind = kind; type->kind = kind;
type->byte_size = bit_size_from_arch(e_base_ctx->modules[rdi_idx].arch)/8; type->byte_size = bit_size_from_arch(arch)/8;
type->owner_type_key = direct_type_key; type->owner_type_key = direct_type_key;
type->count = count; type->count = count;
type->param_type_keys = push_array_no_zero(arena, E_TypeKey, type->count); type->param_type_keys = push_array_no_zero(arena, E_TypeKey, type->count);
type->arch = e_base_ctx->modules[rdi_idx].arch; type->arch = arch;
for(U32 idx = 0; idx < type->count; idx += 1) for(U32 idx = 0; idx < type->count; idx += 1)
{ {
U32 param_type_idx = idx_run[idx]; U32 param_type_idx = idx_run[idx];
@@ -974,7 +981,7 @@ e_push_type_from_key(Arena *arena, E_TypeKey key)
{ {
RDI_TypeNode *param_type_node = rdi_element_from_name_idx(rdi, TypeNodes, param_type_idx); RDI_TypeNode *param_type_node = rdi_element_from_name_idx(rdi, TypeNodes, param_type_idx);
E_TypeKind param_kind = e_type_kind_from_rdi(param_type_node->kind); E_TypeKind param_kind = e_type_kind_from_rdi(param_type_node->kind);
type->param_type_keys[idx] = e_type_key_ext(param_kind, param_type_idx, rdi_idx); type->param_type_keys[idx] = e_type_key_ext(param_kind, param_type_idx, rdi_num);
} }
else else
{ {
@@ -997,14 +1004,14 @@ e_push_type_from_key(Arena *arena, E_TypeKey key)
{ {
RDI_TypeNode *owner_type_node = rdi_element_from_name_idx(rdi, TypeNodes, rdi_type->constructed.owner_type_idx); RDI_TypeNode *owner_type_node = rdi_element_from_name_idx(rdi, TypeNodes, rdi_type->constructed.owner_type_idx);
E_TypeKind owner_type_kind = e_type_kind_from_rdi(owner_type_node->kind); E_TypeKind owner_type_kind = e_type_kind_from_rdi(owner_type_node->kind);
owner_type_key = e_type_key_ext(owner_type_kind, rdi_type->constructed.owner_type_idx, rdi_idx); owner_type_key = e_type_key_ext(owner_type_kind, rdi_type->constructed.owner_type_idx, rdi_num);
} }
type = push_array(arena, E_Type, 1); type = push_array(arena, E_Type, 1);
type->kind = kind; type->kind = kind;
type->byte_size = bit_size_from_arch(e_base_ctx->modules[rdi_idx].arch)/8; type->byte_size = bit_size_from_arch(arch)/8;
type->owner_type_key = owner_type_key; type->owner_type_key = owner_type_key;
type->direct_type_key = direct_type_key; type->direct_type_key = direct_type_key;
type->arch = e_base_ctx->modules[rdi_idx].arch; type->arch = arch;
}break; }break;
} }
} }
@@ -1023,7 +1030,7 @@ e_push_type_from_key(Arena *arena, E_TypeKey key)
{ {
RDI_TypeNode *direct_type_node = rdi_element_from_name_idx(rdi, TypeNodes, rdi_type->user_defined.direct_type_idx); RDI_TypeNode *direct_type_node = rdi_element_from_name_idx(rdi, TypeNodes, rdi_type->user_defined.direct_type_idx);
E_TypeKind direct_type_kind = e_type_kind_from_rdi(direct_type_node->kind); E_TypeKind direct_type_kind = e_type_kind_from_rdi(direct_type_node->kind);
direct_type_key = e_type_key_ext(direct_type_kind, rdi_type->user_defined.direct_type_idx, rdi_idx); direct_type_key = e_type_key_ext(direct_type_kind, rdi_type->user_defined.direct_type_idx, rdi_num);
direct_type_byte_size = direct_type_node->byte_size; direct_type_byte_size = direct_type_node->byte_size;
} }
@@ -1033,7 +1040,7 @@ e_push_type_from_key(Arena *arena, E_TypeKey key)
type->name = push_str8_copy(arena, name); type->name = push_str8_copy(arena, name);
type->byte_size = direct_type_byte_size; type->byte_size = direct_type_byte_size;
type->direct_type_key = direct_type_key; type->direct_type_key = direct_type_key;
type->arch = e_base_ctx->modules[rdi_idx].arch; type->arch = arch;
} }
//- rjf: bitfields //- rjf: bitfields
@@ -1046,7 +1053,7 @@ e_push_type_from_key(Arena *arena, E_TypeKey key)
{ {
RDI_TypeNode *direct_type_node = rdi_element_from_name_idx(rdi, TypeNodes, rdi_type->bitfield.direct_type_idx); RDI_TypeNode *direct_type_node = rdi_element_from_name_idx(rdi, TypeNodes, rdi_type->bitfield.direct_type_idx);
E_TypeKind direct_type_kind = e_type_kind_from_rdi(direct_type_node->kind); E_TypeKind direct_type_kind = e_type_kind_from_rdi(direct_type_node->kind);
direct_type_key = e_type_key_ext(direct_type_kind, rdi_type->bitfield.direct_type_idx, rdi_idx); direct_type_key = e_type_key_ext(direct_type_kind, rdi_type->bitfield.direct_type_idx, rdi_num);
direct_type_byte_size = direct_type_node->byte_size; direct_type_byte_size = direct_type_node->byte_size;
} }
@@ -1057,7 +1064,7 @@ e_push_type_from_key(Arena *arena, E_TypeKey key)
type->direct_type_key = direct_type_key; type->direct_type_key = direct_type_key;
type->off = (U32)rdi_type->bitfield.off; type->off = (U32)rdi_type->bitfield.off;
type->count = (U64)rdi_type->bitfield.size; type->count = (U64)rdi_type->bitfield.size;
type->arch = e_base_ctx->modules[rdi_idx].arch; type->arch = arch;
} }
//- rjf: incomplete types //- rjf: incomplete types
@@ -1071,10 +1078,11 @@ e_push_type_from_key(Arena *arena, E_TypeKey key)
type = push_array(arena, E_Type, 1); type = push_array(arena, E_Type, 1);
type->kind = kind; type->kind = kind;
type->name = push_str8_copy(arena, name); type->name = push_str8_copy(arena, name);
type->arch = e_base_ctx->modules[rdi_idx].arch; type->arch = arch;
} }
} }
}
}break; }break;
//- rjf: reg type keys //- rjf: reg type keys
+1 -1
View File
@@ -70,7 +70,7 @@ internal E_EnumValArray e_enum_val_array_from_list(Arena *arena, E_EnumValList *
//- rjf: basic key constructors //- rjf: basic key constructors
internal E_TypeKey e_type_key_zero(void); internal E_TypeKey e_type_key_zero(void);
internal E_TypeKey e_type_key_basic(E_TypeKind kind); internal E_TypeKey e_type_key_basic(E_TypeKind kind);
internal E_TypeKey e_type_key_ext(E_TypeKind kind, U32 type_idx, U32 rdi_idx); internal E_TypeKey e_type_key_ext(E_TypeKind kind, U32 type_idx, U32 rdi_num);
internal E_TypeKey e_type_key_reg(Arch arch, REGS_RegCode code); internal E_TypeKey e_type_key_reg(Arch arch, REGS_RegCode code);
internal E_TypeKey e_type_key_reg_alias(Arch arch, REGS_AliasCode code); internal E_TypeKey e_type_key_reg_alias(Arch arch, REGS_AliasCode code);
@@ -1906,17 +1906,16 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string)
{ {
U64 vaddr = ptr_data->value_eval.value.u64; U64 vaddr = ptr_data->value_eval.value.u64;
E_Module *module = &e_module_nil; E_Module *module = &e_module_nil;
U32 module_idx = 0;
for EachIndex(idx, e_base_ctx->modules_count) for EachIndex(idx, e_base_ctx->modules_count)
{ {
if(contains_1u64(e_base_ctx->modules[idx].vaddr_range, vaddr)) if(contains_1u64(e_base_ctx->modules[idx].vaddr_range, vaddr))
{ {
module = &e_base_ctx->modules[idx]; module = &e_base_ctx->modules[idx];
module_idx = (U32)idx;
break; break;
} }
} }
RDI_Parsed *rdi = module->rdi; E_DbgInfo *dbg_info = e_dbg_info_from_module(module);
RDI_Parsed *rdi = dbg_info->rdi;
U64 voff = vaddr - module->vaddr_range.min; U64 voff = vaddr - module->vaddr_range.min;
B32 good_symbol_match = 0; B32 good_symbol_match = 0;
@@ -1965,7 +1964,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string)
if(inline_site != 0) if(inline_site != 0)
{ {
RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, inline_site->type_idx); RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, inline_site->type_idx);
E_TypeKey type = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), inline_site->type_idx, module_idx); E_TypeKey type = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), inline_site->type_idx, module->dbg_info_num);
String8 name = {0}; String8 name = {0};
name.str = rdi_string_from_idx(rdi, inline_site->name_string_idx, &name.size); name.str = rdi_string_from_idx(rdi, inline_site->name_string_idx, &name.size);
if(inline_site->type_idx != 0) if(inline_site->type_idx != 0)
@@ -1995,7 +1994,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string)
U64 proc_idx = scope->proc_idx; U64 proc_idx = scope->proc_idx;
RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx); RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx);
RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, procedure->type_idx); RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, procedure->type_idx);
E_TypeKey type = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), procedure->type_idx, module_idx); E_TypeKey type = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), procedure->type_idx, module->dbg_info_num);
String8 name = {0}; String8 name = {0};
name.str = rdi_string_from_idx(rdi, procedure->name_string_idx, &name.size); name.str = rdi_string_from_idx(rdi, procedure->name_string_idx, &name.size);
if(procedure->type_idx != 0) if(procedure->type_idx != 0)
+2 -2
View File
@@ -181,7 +181,7 @@ raddbg_decode_utf8(char *str, unsigned __int64 max)
case 3: case 3:
if(2 < max) if(2 < max)
{ {
unsigned char cont_byte[2] = {str[1], str[2]}; unsigned char cont_byte[2] = {(unsigned char)str[1], (unsigned char)str[2]};
if(raddbg_utf8_class[cont_byte[0] >> 3] == 0 && if(raddbg_utf8_class[cont_byte[0] >> 3] == 0 &&
raddbg_utf8_class[cont_byte[1] >> 3] == 0) raddbg_utf8_class[cont_byte[1] >> 3] == 0)
{ {
@@ -194,7 +194,7 @@ raddbg_decode_utf8(char *str, unsigned __int64 max)
case 4: case 4:
if(3 < max) if(3 < max)
{ {
unsigned char cont_byte[3] = {str[1], str[2], str[3]}; unsigned char cont_byte[3] = {(unsigned char)str[1], (unsigned char)str[2], (unsigned char)str[3]};
if(raddbg_utf8_class[cont_byte[0] >> 3] == 0 && if(raddbg_utf8_class[cont_byte[0] >> 3] == 0 &&
raddbg_utf8_class[cont_byte[1] >> 3] == 0 && raddbg_utf8_class[cont_byte[1] >> 3] == 0 &&
raddbg_utf8_class[cont_byte[2] >> 3] == 0) raddbg_utf8_class[cont_byte[2] >> 3] == 0)
File diff suppressed because one or more lines are too long
+8 -4
View File
@@ -252,6 +252,8 @@ RD_CmdKind_ListBreakpoints,
RD_CmdKind_ClearOutput, RD_CmdKind_ClearOutput,
RD_CmdKind_AddWatchPin, RD_CmdKind_AddWatchPin,
RD_CmdKind_ToggleWatchPin, RD_CmdKind_ToggleWatchPin,
RD_CmdKind_LoadDebugInfo,
RD_CmdKind_UnloadDebugInfo,
RD_CmdKind_AddTypeView, RD_CmdKind_AddTypeView,
RD_CmdKind_AddFilePathMap, RD_CmdKind_AddFilePathMap,
RD_CmdKind_EditUserTheme, RD_CmdKind_EditUserTheme,
@@ -292,6 +294,7 @@ RD_CmdKind_OpenCallStack,
RD_CmdKind_OpenTargets, RD_CmdKind_OpenTargets,
RD_CmdKind_OpenBreakpoints, RD_CmdKind_OpenBreakpoints,
RD_CmdKind_OpenWatchPins, RD_CmdKind_OpenWatchPins,
RD_CmdKind_OpenDebugInfos,
RD_CmdKind_OpenThreads, RD_CmdKind_OpenThreads,
RD_CmdKind_OpenProcesses, RD_CmdKind_OpenProcesses,
RD_CmdKind_OpenMachines, RD_CmdKind_OpenMachines,
@@ -525,6 +528,7 @@ X(call_stack) \
X(targets) \ X(targets) \
X(breakpoints) \ X(breakpoints) \
X(watch_pins) \ X(watch_pins) \
X(debug_infos) \
X(threads) \ X(threads) \
X(processes) \ X(processes) \
X(machines) \ X(machines) \
@@ -589,10 +593,10 @@ Z(getting_started)\
.os_event = rd_regs()->os_event,\ .os_event = rd_regs()->os_event,\
C_LINKAGE_BEGIN C_LINKAGE_BEGIN
extern String8 rd_tab_fast_path_view_name_table[24]; extern String8 rd_tab_fast_path_view_name_table[25];
extern String8 rd_tab_fast_path_query_name_table[24]; extern String8 rd_tab_fast_path_query_name_table[25];
extern RD_VocabInfo rd_vocab_info_table[352]; extern RD_VocabInfo rd_vocab_info_table[357];
extern RD_NameSchemaInfo rd_name_schema_info_table[25]; extern RD_NameSchemaInfo rd_name_schema_info_table[26];
extern String8 rd_reg_slot_code_name_table[47]; extern String8 rd_reg_slot_code_name_table[47];
extern Rng1U64 rd_reg_slot_range_table[47]; extern Rng1U64 rd_reg_slot_range_table[47];
extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_old_name_table[8];
+21
View File
@@ -33,6 +33,7 @@ RD_WatchTabFastPathTable:
{Targets "Targets" targets 1 Target "Displays, and allows editing of, the list of all targets."} {Targets "Targets" targets 1 Target "Displays, and allows editing of, the list of all targets."}
{Breakpoints "Breakpoints" breakpoints 1 CircleFilled "Displays, and allows editing of, the list of all breakpoints."} {Breakpoints "Breakpoints" breakpoints 1 CircleFilled "Displays, and allows editing of, the list of all breakpoints."}
{WatchPins "Watch Pins" watch_pins 1 Pin "Displays, and allows editing of, the list of all watch pins."} {WatchPins "Watch Pins" watch_pins 1 Pin "Displays, and allows editing of, the list of all watch pins."}
{DebugInfos "Debug Info" debug_infos 1 Module "Displays, and allows editing of, the list of all debug info files that the debugger has loaded."}
{Threads "Threads" threads 1 Threads "Displays the list of all threads in all processes to which the debugger is attached."} {Threads "Threads" threads 1 Threads "Displays the list of all threads in all processes to which the debugger is attached."}
{Processes "Processes" processes 1 Scheduler "Displays the list of all processes to which the debugger is attached."} {Processes "Processes" processes 1 Scheduler "Displays the list of all processes to which the debugger is attached."}
{Machines "Machines" machines 1 Machine "Displays the list of all machines to which the debugger is connected."} {Machines "Machines" machines 1 Machine "Displays the list of all machines to which the debugger is connected."}
@@ -91,6 +92,7 @@ RD_VocabTable:
{type_view _ "Type View" _ Binoculars } {type_view _ "Type View" _ Binoculars }
{file_path_map _ "File Path Map" _ FileOutline } {file_path_map _ "File Path Map" _ FileOutline }
{watch_pin _ "Watch Pin" _ Pin } {watch_pin _ "Watch Pin" _ Pin }
{debug_info _ "Debug Info" "Debug Info" Module }
{watch watches "Watch" "Watches" Binoculars } {watch watches "Watch" "Watches" Binoculars }
{view _ "View" _ Binoculars } {view _ "View" _ Binoculars }
{breakpoint _ "Breakpoint" _ CircleFilled } {breakpoint _ "Breakpoint" _ CircleFilled }
@@ -196,6 +198,7 @@ RD_VocabTable:
{row_height "" "Row Height" "" Null } {row_height "" "Row Height" "" Null }
{tab_height "" "Tab Height" "" Null } {tab_height "" "Tab Height" "" Null }
{rgba "" "RGBA" "" Palette } {rgba "" "RGBA" "" Palette }
{path "" "Path" "" FileOutline }
} }
@struct RD_VocabInfo: @struct RD_VocabInfo:
@@ -657,6 +660,20 @@ RD_VocabTable:
```, ```,
} }
//- rjf: debug infos
{
debug_info,
```
@row_commands(enable_cfg, duplicate_cfg, remove_cfg)
@collection_commands(load_debug_info)
x:
{
'path': @no_relativize path,
@no_revert @no_expand @default(1) 'enabled': bool,
}
```,
}
//- rjf: file path maps //- rjf: file path maps
{ {
file_path_map, file_path_map,
@@ -1044,6 +1061,10 @@ RD_CmdTable: // | | | |
{AddWatchPin 1 1 0 0 "" Expr null Nil Null 0 0 0 0 1 1 1 Pin "add_watch_pin" "Add Watch Pin" "Places a watch pin at a given location (file path and line number or address)." "" "$watch_pins," } {AddWatchPin 1 1 0 0 "" Expr null Nil Null 0 0 0 0 1 1 1 Pin "add_watch_pin" "Add Watch Pin" "Places a watch pin at a given location (file path and line number or address)." "" "$watch_pins," }
{ToggleWatchPin 1 0 0 0 "" Expr null Nil Null 0 0 0 0 1 1 1 Pin "toggle_watch_pin" "Toggle Watch Pin" "Places or removes a watch pin at a given location (file path and line number or address)." "" "" } {ToggleWatchPin 1 0 0 0 "" Expr null Nil Null 0 0 0 0 1 1 1 Pin "toggle_watch_pin" "Toggle Watch Pin" "Places or removes a watch pin at a given location (file path and line number or address)." "" "" }
//- rjf: debug infos
{LoadDebugInfo 1 1 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Module "load_debug_info" "Load Debug Info" "Loads a debug info file." "" "$debug_infos," }
{UnloadDebugInfo 1 1 0 0 "query:debug_infos" Cfg null Nil Null 0 0 0 0 1 1 1 Module "unload_debug_info" "Unload Debug Info" "Unloads a debug info file." "" "$debug_infos," }
//- rjf: type views //- rjf: type views
{AddTypeView 0 0 0 0 "" String null Nil Null 0 0 0 0 0 0 0 Binoculars "add_type_view" "Add Type View" "Adds a new type view." "" "" } {AddTypeView 0 0 0 0 "" String null Nil Null 0 0 0 0 0 0 0 Binoculars "add_type_view" "Add Type View" "Adds a new type view." "" "" }
+233 -14
View File
@@ -3998,7 +3998,9 @@ rd_view_ui(Rng2F32 rect)
// rjf: apply type note // rjf: apply type note
if(!(cell_info.flags & RD_WatchCellFlag_NoEval) && if(!(cell_info.flags & RD_WatchCellFlag_NoEval) &&
cell->eval.space.kind == CTRL_EvalSpaceKind_Entity && e_type_kind_from_key(cell->eval.irtree.type_key) != E_TypeKind_Null &&
(cell->eval.space.kind == E_SpaceKind_Null ||
cell->eval.space.kind == CTRL_EvalSpaceKind_Entity) &&
row_info->callstack_thread == &ctrl_entity_nil && row_info->callstack_thread == &ctrl_entity_nil &&
e_type_kind_from_key(cell->eval.irtree.type_key) != E_TypeKind_Function) e_type_kind_from_key(cell->eval.irtree.type_key) != E_TypeKind_Function)
UI_FontSize(ui_top_font_size()*0.9f) UI_FontSize(ui_top_font_size()*0.9f)
@@ -9310,7 +9312,7 @@ rd_code_color_slot_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8
// rjf: try to map using asynchronous matching system // rjf: try to map using asynchronous matching system
if(!mapped && kind == TXT_TokenKind_Identifier) if(!mapped && kind == TXT_TokenKind_Identifier)
{ {
DI_Match match = di_match_from_string(string, 0, e_base_ctx->primary_module->dbgi_key, 0); DI_Match match = di_match_from_string(string, 0, di_key_zero(), 0);
RDI_SectionKind section_kind = match.section_kind; RDI_SectionKind section_kind = match.section_kind;
mapped = 1; mapped = 1;
switch(section_kind) switch(section_kind)
@@ -10310,6 +10312,73 @@ rd_frame(void)
scratch_end(scratch); scratch_end(scratch);
} }
//////////////////////////////
//- rjf: iterate all loaded debug infos, remove hot markers
//
if(rd_state->frame_depth == 1)
{
CFG_Node *transient = cfg_node_child_from_string(cfg_node_root(), str8_lit("transient"));
CFG_Node *loaded_debug_infos = cfg_node_child_from_string_or_alloc(rd_state->cfg, transient, str8_lit("loaded_debug_infos"));
for(CFG_Node *child = loaded_debug_infos->first; child != &cfg_nil_node; child = child->next)
{
cfg_node_release(rd_state->cfg, cfg_node_child_from_string(child, str8_lit("hot")));
}
}
//////////////////////////////
//- rjf: iterate all loaded debug infos, touch their dbgi load markers
//
if(rd_state->frame_depth == 1)
{
CFG_Node *transient = cfg_node_child_from_string(cfg_node_root(), str8_lit("transient"));
CFG_Node *loaded_debug_infos = cfg_node_child_from_string_or_alloc(rd_state->cfg, transient, str8_lit("loaded_debug_infos"));
CFG_NodePtrList dbg_infos = cfg_node_top_level_list_from_string(scratch.arena, str8_lit("debug_info"));
for EachNode(n, CFG_NodePtrNode, dbg_infos.first)
{
CFG_Node *di = n->v;
String8 path = rd_path_from_cfg(di);
CFG_Node *di_timestamp = cfg_node_child_from_string(di, str8_lit("timestamp"));
U64 timestamp = 0;
try_u64_from_str8_c_rules(di_timestamp->first->string, &timestamp);
String8 loaded_di_key = push_str8f(scratch.arena, "$%I64x `%S` `%I64u`", di->id, path, timestamp);
CFG_Node *loaded_di = cfg_node_child_from_string(loaded_debug_infos, loaded_di_key);
if(loaded_di == &cfg_nil_node)
{
loaded_di = cfg_node_new(rd_state->cfg, loaded_debug_infos, loaded_di_key);
CFG_Node *path_node = cfg_node_new(rd_state->cfg, loaded_di, str8_lit("path"));
cfg_node_new(rd_state->cfg, path_node, path);
CFG_Node *timestamp_node = cfg_node_new(rd_state->cfg, loaded_di, str8_lit("timestamp"));
cfg_node_new(rd_state->cfg, timestamp_node, di_timestamp->first->string);
DI_Key dbgi_key = di_key_from_path_timestamp(path, timestamp);
di_open(dbgi_key);
}
cfg_node_child_from_string_or_alloc(rd_state->cfg, loaded_di, str8_lit("hot"));
}
}
//////////////////////////////
//- rjf: iterate all loaded debug infos, close those without hot markers
//
if(rd_state->frame_depth == 1)
{
CFG_Node *transient = cfg_node_child_from_string(cfg_node_root(), str8_lit("transient"));
CFG_Node *loaded_debug_infos = cfg_node_child_from_string_or_alloc(rd_state->cfg, transient, str8_lit("loaded_debug_infos"));
for(CFG_Node *child = loaded_debug_infos->first, *next = &cfg_nil_node; child != &cfg_nil_node; child = next)
{
next = child->next;
if(cfg_node_child_from_string(child, str8_lit("hot")) == &cfg_nil_node)
{
CFG_Node *path_node = cfg_node_child_from_string(child, str8_lit("path"));
CFG_Node *timestamp_node = cfg_node_child_from_string(child, str8_lit("timestamp"));
U64 timestamp = 0;
try_u64_from_str8_c_rules(timestamp_node->first->string, &timestamp);
DI_Key dbgi_key = di_key_from_path_timestamp(path_node->first->string, timestamp);
di_close(dbgi_key, 0);
cfg_node_release(rd_state->cfg, child);
}
}
}
////////////////////////////// //////////////////////////////
//- rjf: garbage collect untouched immediate cfg trees //- rjf: garbage collect untouched immediate cfg trees
// //
@@ -10776,7 +10845,56 @@ rd_frame(void)
ProfScope("loop - consume events in core, tick engine, and repeat") for(U64 cmd_process_loop_idx = 0; cmd_process_loop_idx < 3; cmd_process_loop_idx += 1) ProfScope("loop - consume events in core, tick engine, and repeat") for(U64 cmd_process_loop_idx = 0; cmd_process_loop_idx < 3; cmd_process_loop_idx += 1)
{ {
//////////////////////////// ////////////////////////////
//- rjf: unpack eval-dependent info //- rjf: gather all unique debug info keys, build map
//
typedef struct DbgInfoNode DbgInfoNode;
struct DbgInfoNode
{
DbgInfoNode *hash_next;
DbgInfoNode *order_next;
DI_Key key;
U64 idx;
};
U64 dbg_info_slots_count = 4096;
DbgInfoNode **dbg_info_slots = push_array(scratch.arena, DbgInfoNode *, dbg_info_slots_count);
DbgInfoNode *first_dbg_info = 0;
DbgInfoNode *last_dbg_info = 0;
U64 dbg_infos_count = 0;
{
CFG_NodePtrList dbg_infos = cfg_node_top_level_list_from_string(scratch.arena, str8_lit("debug_info"));
for EachNode(n, CFG_NodePtrNode, dbg_infos.first)
{
CFG_Node *di = n->v;
String8 path = rd_path_from_cfg(di);
CFG_Node *timestamp_node = cfg_node_child_from_string(di, str8_lit("timestamp"));
U64 timestamp = 0;
try_u64_from_str8_c_rules(timestamp_node->first->string, &timestamp);
DI_Key key = di_key_from_path_timestamp(path, timestamp);
U64 hash = u64_hash_from_str8(str8_struct(&key));
U64 slot_idx = hash%dbg_info_slots_count;
DbgInfoNode *node = 0;
for(DbgInfoNode *n = dbg_info_slots[slot_idx]; n != 0; n = n->hash_next)
{
if(di_key_match(n->key, key))
{
node = n;
break;
}
}
if(node == 0)
{
node = push_array(scratch.arena, DbgInfoNode, 1);
SLLStackPush_N(dbg_info_slots[slot_idx], node, hash_next);
SLLQueuePush_N(first_dbg_info, last_dbg_info, node, order_next);
node->key = key;
node->idx = dbg_infos_count;
dbg_infos_count += 1;
}
}
}
////////////////////////////
//- rjf: unpack basic evaluation context
// //
ProfBegin("unpack eval-dependent info"); ProfBegin("unpack eval-dependent info");
CTRL_Entity *process = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->process); CTRL_Entity *process = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->process);
@@ -10787,32 +10905,67 @@ rd_frame(void)
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr); CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr);
U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr); U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr);
U64 tls_root_vaddr = ctrl_tls_root_vaddr_from_thread(&d_state->ctrl_entity_store->ctx, thread->handle); U64 tls_root_vaddr = ctrl_tls_root_vaddr_from_thread(&d_state->ctrl_entity_store->ctx, thread->handle);
ProfEnd();
////////////////////////////
//- rjf: produce all debug infos
//
U64 eval_dbg_infos_count = Max(1, dbg_infos_count);
E_DbgInfo *eval_dbg_infos = push_array(scratch.arena, E_DbgInfo, eval_dbg_infos_count);
E_DbgInfo *eval_dbg_infos_primary = &eval_dbg_infos[0];
MemoryCopyStruct(eval_dbg_infos_primary, &e_dbg_info_nil);
{
U64 idx = 0;
for(DbgInfoNode *n = first_dbg_info; n != 0; n = n->order_next)
{
eval_dbg_infos[idx].dbgi_key = n->key;
eval_dbg_infos[idx].rdi = di_rdi_from_key(rd_state->frame_access, n->key, 0, 0);
idx += 1;
}
}
////////////////////////////
//- rjf: produce all eval modules
//
CTRL_EntityArray all_modules = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Module); CTRL_EntityArray all_modules = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Module);
U64 eval_modules_count = Max(1, all_modules.count); U64 eval_modules_count = Max(1, all_modules.count);
E_Module *eval_modules = push_array(scratch.arena, E_Module, eval_modules_count); E_Module *eval_modules = push_array(scratch.arena, E_Module, eval_modules_count);
E_Module *eval_modules_primary = &eval_modules[0]; E_Module *eval_modules_primary = &eval_modules[0];
eval_modules_primary->rdi = &rdi_parsed_nil;
eval_modules_primary->vaddr_range = r1u64(0, max_U64); eval_modules_primary->vaddr_range = r1u64(0, max_U64);
DI_Key primary_dbgi_key = {0};
ProfScope("produce all eval modules") ProfScope("produce all eval modules")
{ {
for EachIndex(eval_module_idx, all_modules.count) for EachIndex(eval_module_idx, all_modules.count)
{ {
CTRL_Entity *m = all_modules.v[eval_module_idx]; CTRL_Entity *m = all_modules.v[eval_module_idx];
DI_Key dbgi_key = ctrl_dbgi_key_from_module(m); DI_Key dbgi_key = ctrl_dbgi_key_from_module(m);
eval_modules[eval_module_idx].arch = m->arch;
eval_modules[eval_module_idx].dbgi_key = dbgi_key; // rjf: dbgi key -> eval dbg info num
eval_modules[eval_module_idx].rdi = di_rdi_from_key(rd_state->frame_access, dbgi_key, 0, 0); U32 dbg_info_num = 0;
{
U64 hash = u64_hash_from_str8(str8_struct(&dbgi_key));
U64 slot_idx = hash%dbg_info_slots_count;
for(DbgInfoNode *n = dbg_info_slots[slot_idx]; n != 0; n = n->hash_next)
{
if(di_key_match(n->key, dbgi_key))
{
dbg_info_num = n->idx+1;
break;
}
}
}
// rjf: fill
eval_modules[eval_module_idx].vaddr_range = m->vaddr_range; eval_modules[eval_module_idx].vaddr_range = m->vaddr_range;
eval_modules[eval_module_idx].arch = m->arch;
eval_modules[eval_module_idx].dbg_info_num = dbg_info_num;
eval_modules[eval_module_idx].space = rd_eval_space_from_ctrl_entity(ctrl_entity_ancestor_from_kind(m, CTRL_EntityKind_Process), CTRL_EvalSpaceKind_Entity); eval_modules[eval_module_idx].space = rd_eval_space_from_ctrl_entity(ctrl_entity_ancestor_from_kind(m, CTRL_EntityKind_Process), CTRL_EvalSpaceKind_Entity);
if(module == m) if(module == m)
{ {
eval_modules_primary = &eval_modules[eval_module_idx]; eval_modules_primary = &eval_modules[eval_module_idx];
primary_dbgi_key = dbgi_key; eval_dbg_infos_primary = (0 < dbg_info_num && dbg_info_num <= eval_dbg_infos_count) ? &eval_dbg_infos[dbg_info_num-1] : &e_dbg_info_nil;
} }
} }
} }
ProfEnd();
//////////////////////////// ////////////////////////////
//- rjf: begin evaluation //- rjf: begin evaluation
@@ -10833,6 +10986,11 @@ rd_frame(void)
ctx->thread_arch = thread->arch; ctx->thread_arch = thread->arch;
ctx->thread_unwind_count = unwind_count; ctx->thread_unwind_count = unwind_count;
//- rjf: fill debug infos
ctx->dbg_infos = eval_dbg_infos;
ctx->dbg_infos_count = eval_dbg_infos_count;
ctx->primary_dbg_info = eval_dbg_infos_primary;
//- rjf: fill modules //- rjf: fill modules
ctx->modules = eval_modules; ctx->modules = eval_modules;
ctx->modules_count = eval_modules_count; ctx->modules_count = eval_modules_count;
@@ -10959,6 +11117,7 @@ rd_frame(void)
str8_lit("breakpoint"), str8_lit("breakpoint"),
str8_lit("watch_pin"), str8_lit("watch_pin"),
str8_lit("target"), str8_lit("target"),
str8_lit("debug_info"),
str8_lit("file_path_map"), str8_lit("file_path_map"),
str8_lit("type_view"), str8_lit("type_view"),
str8_lit("recent_project"), str8_lit("recent_project"),
@@ -11608,8 +11767,8 @@ rd_frame(void)
E_IRCtx *ctx = ir_ctx; E_IRCtx *ctx = ir_ctx;
ctx->regs_map = ctrl_string2reg_from_arch(eval_base_ctx->primary_module->arch); ctx->regs_map = ctrl_string2reg_from_arch(eval_base_ctx->primary_module->arch);
ctx->reg_alias_map = ctrl_string2alias_from_arch(eval_base_ctx->primary_module->arch); ctx->reg_alias_map = ctrl_string2alias_from_arch(eval_base_ctx->primary_module->arch);
ctx->locals_map = d_query_cached_locals_map_from_dbgi_key_voff(primary_dbgi_key, rip_voff); ctx->locals_map = d_query_cached_locals_map_from_dbgi_key_voff(eval_base_ctx->primary_dbg_info->dbgi_key, rip_voff);
ctx->member_map = d_query_cached_member_map_from_dbgi_key_voff(primary_dbgi_key, rip_voff); ctx->member_map = d_query_cached_member_map_from_dbgi_key_voff(eval_base_ctx->primary_dbg_info->dbgi_key, rip_voff);
ctx->macro_map = macro_map; ctx->macro_map = macro_map;
ctx->auto_hook_map = auto_hook_map; ctx->auto_hook_map = auto_hook_map;
} }
@@ -11631,7 +11790,7 @@ rd_frame(void)
ctx->tls_base = push_array(scratch.arena, U64, 1); ctx->tls_base = push_array(scratch.arena, U64, 1);
ctx->tls_base[0] = d_query_cached_tls_base_vaddr_from_process_root_rip(process, tls_root_vaddr, rip_vaddr); ctx->tls_base[0] = d_query_cached_tls_base_vaddr_from_process_root_rip(process, tls_root_vaddr, rip_vaddr);
} }
e_select_interpret_ctx(interpret_ctx, eval_modules_primary->rdi, rip_voff); e_select_interpret_ctx(interpret_ctx, eval_dbg_infos_primary->rdi, rip_voff);
//////////////////////////// ////////////////////////////
//- rjf: evaluate unpacked settings (must be used earlier than this point in the frame, //- rjf: evaluate unpacked settings (must be used earlier than this point in the frame,
@@ -13683,7 +13842,15 @@ rd_frame(void)
DI_Key voff_dbgi_key = {0}; DI_Key voff_dbgi_key = {0};
if(!name_resolved) if(!name_resolved)
{ {
DI_Match match = di_match_from_string(name, 0, e_base_ctx->primary_module->dbgi_key, 0); DI_Match match = {0};
if(match.idx == 0)
{
match = di_match_from_string(name, 0, e_base_ctx->primary_dbg_info->dbgi_key, rd_state->frame_eval_memread_endt_us);
}
if(match.idx == 0)
{
match = di_match_from_string(name, 0, di_key_zero(), rd_state->frame_eval_memread_endt_us);
}
if(match.section_kind == RDI_SectionKind_Procedures) if(match.section_kind == RDI_SectionKind_Procedures)
{ {
Access *access = access_open(); Access *access = access_open();
@@ -14812,6 +14979,21 @@ rd_frame(void)
} }
}break; }break;
//- rjf: debug infos
case RD_CmdKind_LoadDebugInfo:
{
CFG_Node *project = cfg_node_child_from_string(cfg_node_root(), str8_lit("project"));
CFG_Node *di = cfg_node_new(rd_state->cfg, project, str8_lit("debug_info"));
CFG_Node *path = cfg_node_new(rd_state->cfg, di, str8_lit("path"));
cfg_node_new(rd_state->cfg, path, rd_regs()->file_path);
}break;
case RD_CmdKind_UnloadDebugInfo:
{
CFG_Node *di = cfg_node_from_id(rd_regs()->cfg);
CFG_Node *path = cfg_node_child_from_string(di, str8_lit("path"));
cfg_node_release(rd_state->cfg, di);
}break;
//- rjf: type views //- rjf: type views
case RD_CmdKind_AddTypeView: case RD_CmdKind_AddTypeView:
{ {
@@ -15897,6 +16079,43 @@ rd_frame(void)
switch(evt->kind) switch(evt->kind)
{ {
default:{}break; default:{}break;
case D_EventKind_ModuleLoad:
{
CTRL_Entity *module = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, evt->module);
CTRL_Entity *debug_info_path = ctrl_entity_child_from_kind(module, CTRL_EntityKind_DebugInfoPath);
String8 new_path = debug_info_path->string;
if(new_path.size != 0 && os_file_path_exists(new_path))
{
CFG_NodePtrList dbg_infos = cfg_node_top_level_list_from_string(scratch.arena, str8_lit("debug_info"));
B32 path_found = 0;
CFG_Node *found_di = &cfg_nil_node;
for EachNode(n, CFG_NodePtrNode, dbg_infos.first)
{
CFG_Node *di = n->v;
String8 path = rd_path_from_cfg(di);
if(str8_match(path, new_path, 0))
{
path_found = 1;
found_di = di;
break;
}
}
if(!path_found)
{
CFG_Node *project = cfg_node_child_from_string(cfg_node_root(), str8_lit("project"));
CFG_Node *di = cfg_node_new(rd_state->cfg, project, str8_lit("debug_info"));
CFG_Node *path_root = cfg_node_new(rd_state->cfg, di, str8_lit("path"));
CFG_Node *timestamp_root = cfg_node_new(rd_state->cfg, di, str8_lit("timestamp"));
cfg_node_new(rd_state->cfg, path_root, new_path);
cfg_node_newf(rd_state->cfg, timestamp_root, "%I64u", debug_info_path->timestamp);
}
else
{
CFG_Node *timestamp_root = cfg_node_child_from_string_or_alloc(rd_state->cfg, found_di, str8_lit("timestamp"));
cfg_node_new_replacef(rd_state->cfg, timestamp_root, "%I64u", debug_info_path->timestamp);
}
}
}break;
case D_EventKind_ProcessEnd: case D_EventKind_ProcessEnd:
if(rd_state->quit_after_success) if(rd_state->quit_after_success)
{ {
-3
View File
@@ -1251,9 +1251,6 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
CTRL_Entity *selected_thread_process = ctrl_entity_ancestor_from_kind(selected_thread, CTRL_EntityKind_Process); CTRL_Entity *selected_thread_process = ctrl_entity_ancestor_from_kind(selected_thread, CTRL_EntityKind_Process);
U64 selected_thread_rip_unwind_vaddr = d_query_cached_rip_from_thread_unwind(selected_thread, rd_regs()->unwind_count); U64 selected_thread_rip_unwind_vaddr = d_query_cached_rip_from_thread_unwind(selected_thread, rd_regs()->unwind_count);
CTRL_Entity *selected_thread_module = ctrl_module_from_process_vaddr(selected_thread_process, selected_thread_rip_unwind_vaddr); CTRL_Entity *selected_thread_module = ctrl_module_from_process_vaddr(selected_thread_process, selected_thread_rip_unwind_vaddr);
F32 selected_thread_alive_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "###selected_thread_alive_t_%p", selected_thread), 1.f);
F32 selected_thread_module_alive_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "###selected_thread_module_alive_t_%p", selected_thread_module), 1.f);
F32 selected_thread_arch_alive_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "###selected_thread_arch_alive_t_%i", selected_thread->arch), 1.f);
CTRL_Event stop_event = d_ctrl_last_stop_event(); CTRL_Event stop_event = d_ctrl_last_stop_event();
CTRL_Entity *stopper_thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, stop_event.entity); CTRL_Entity *stopper_thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, stop_event.entity);
B32 is_focused = ui_is_focus_active(); B32 is_focused = ui_is_focus_active();
+16
View File
@@ -4,6 +4,22 @@
#include "lib_rdi/rdi.c" #include "lib_rdi/rdi.c"
#include "lib_rdi/rdi_parse.c" #include "lib_rdi/rdi_parse.c"
////////////////////////////////
//~ rjf: RDI Enum <=> Base Enum
internal Arch
arch_from_rdi_arch(RDI_Arch arch)
{
Arch result = Arch_Null;
switch((RDI_ArchEnum)arch)
{
case RDI_Arch_NULL:{}break;
case RDI_Arch_X86:{result = Arch_x86;}break;
case RDI_Arch_X64:{result = Arch_x64;}break;
}
return result;
}
//////////////////////////////// ////////////////////////////////
//~ rjf: Lookup Helpers //~ rjf: Lookup Helpers
+5
View File
@@ -64,6 +64,11 @@ read_only global String8 rdi_name_title_from_dump_subset_table[] =
#undef X #undef X
}; };
////////////////////////////////
//~ rjf: RDI Enum <=> Base Enum
internal Arch arch_from_rdi_arch(RDI_Arch arch);
//////////////////////////////// ////////////////////////////////
//~ rjf: Lookup Helpers //~ rjf: Lookup Helpers
+1 -1
View File
@@ -306,7 +306,7 @@ static inline int sha512_cpuid(void)
DWORD bitsize = sizeof(bits); DWORD bitsize = sizeof(bits);
RegGetValueA(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", "CP 4030", RRF_RT_QWORD | RRF_ZEROONFAILURE, NULL, &bits, &bitsize); RegGetValueA(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", "CP 4030", RRF_RT_QWORD | RRF_ZEROONFAILURE, NULL, &bits, &bitsize);
// bits from ID_AA64ISAR0_EL1 // bits from ID_AA64ISAR0_EL1
int has_arm64 = ((bits >> 15) & 0xf) == 0x2; int has_arm64 = ((bits >> 12) & 0xf) == 0x2;
#elif defined(__linux__) #elif defined(__linux__)
unsigned long hwcap = getauxval(AT_HWCAP); unsigned long hwcap = getauxval(AT_HWCAP);
int has_arm64 = hwcap & HWCAP_SHA512; int has_arm64 = hwcap & HWCAP_SHA512;