get debugger onto new location info & symbol format

This commit is contained in:
Ryan Fleury
2026-04-20 09:57:33 -07:00
parent 6764e1281e
commit 881e19c842
29 changed files with 352 additions and 1653 deletions
+94 -3
View File
@@ -590,7 +590,7 @@ e_push_locals_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff)
U32 local_opl_idx = scope->local_first + scope->local_count;
for(U32 local_idx = scope->local_first; local_idx < local_opl_idx; local_idx += 1)
{
RDI_Local *local_var = rdi_element_from_name_idx(rdi, Locals, local_idx);
RDI_Symbol *local_var = rdi_element_from_name_idx(rdi, LocalVariableSymbols, local_idx);
U64 local_name_size = 0;
U8 *local_name_str = rdi_string_from_idx(rdi, local_var->name_string_idx, &local_name_size);
String8 name = push_str8_copy(arena, str8(local_name_str, local_name_size));
@@ -612,10 +612,10 @@ e_push_member_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff)
//- rjf: tightest scope -> procedure
U32 proc_idx = tightest_scope->proc_idx;
RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx);
RDI_Symbol *procedure = rdi_element_from_name_idx(rdi, ProcedureSymbols, proc_idx);
//- rjf: procedure -> udt
U32 udt_idx = procedure->container_idx;
U32 udt_idx = procedure->container_flags & RDI_ContainerFlag_KindMask == RDI_ContainerKind_Type ? procedure->container_idx : 0;
RDI_UDT *udt = rdi_element_from_name_idx(rdi, UDTs, udt_idx);
//- rjf: build blank map
@@ -644,6 +644,97 @@ e_push_member_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff)
return map;
}
////////////////////////////////
//~ rjf: RDI Location Info -> Eval Op List
internal E_OpList
e_oplist_from_location(Arena *arena, RDI_Parsed *rdi, RDI_Location loc)
{
E_OpList result = {0};
B32 need_extra_memread = 0;
switch((RDI_LocationKindEnum)rdi_kind_from_location(loc))
{
case RDI_LocationKind_NULL:
case RDI_LocationKind_Set:{}break;
//- rjf: bytecode
case RDI_LocationKind_AddrBytecodeStream:
case RDI_LocationKind_ValBytecodeStream:
{
U64 all_bytecode_size = 0;
U8 *all_bytecode = rdi_table_from_name(rdi, LocationsBytecodeData, &all_bytecode_size);
U64 bytecode_first_idx = rdi_bytecode_data_off_from_location(loc);
bytecode_first_idx = Min(bytecode_first_idx, all_bytecode_size);
U64 bytecode_opl_idx = bytecode_first_idx;
for(U64 off = bytecode_first_idx, next_off = all_bytecode_size; off < all_bytecode_size; off = next_off)
{
next_off = all_bytecode_size;
U8 opcode = all_bytecode[off];
if(opcode == 0)
{
break;
}
U16 ctrlbits = rdi_eval_op_ctrlbits_table[opcode];
U32 p_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits);
bytecode_opl_idx += (1 + p_size);
next_off = (off + 1 + p_size);
}
String8 bytecode = str8(all_bytecode + bytecode_first_idx, (bytecode_opl_idx - bytecode_first_idx));
e_oplist_push_bytecode(arena, &result, bytecode);
}break;
//- rjf: reg + off
case RDI_LocationKind_AddrRegPlusU16: goto reg_plus_off;
case RDI_LocationKind_AddrAddrRegPlusU16: need_extra_memread = 1; goto reg_plus_off;
reg_plus_off:;
{
RDI_TopLevelInfo *tli = rdi_element_from_name_idx(rdi, TopLevelInfo, 0);
Arch arch = arch_from_rdi_arch(tli->arch);
U64 arch_addr_bytesize = byte_size_from_arch(arch);
RDI_RegCode regcode = rdi_regcode_from_location(loc);
U64 reg_off = rdi_regoff_from_location(loc);
e_oplist_push_op(arena, &result, RDI_EvalOp_RegRead, e_value_u64(RDI_EncodeRegReadParam(regcode, arch_addr_bytesize, 0)));
e_oplist_push_uconst(arena, &result, reg_off);
e_oplist_push_op(arena, &result, RDI_EvalOp_Add, e_value_u64(0));
if(need_extra_memread)
{
e_oplist_push_op(arena, &result, RDI_EvalOp_MemRead, e_value_u64(arch_addr_bytesize));
}
}break;
//- rjf: reg
case RDI_LocationKind_ValReg:
{
RDI_TopLevelInfo *tli = rdi_element_from_name_idx(rdi, TopLevelInfo, 0);
Arch arch = arch_from_rdi_arch(tli->arch);
RDI_RegCode rdi_regcode = rdi_regcode_from_location(loc);
REGS_RegCode regs_reg_code = regs_reg_code_from_arch_rdi_code(arch, rdi_regcode);
REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(arch)[regs_reg_code];
U64 byte_size = (U64)reg_rng.byte_size;
U64 byte_pos = 0;
e_oplist_push_op(arena, &result, RDI_EvalOp_RegRead, e_value_u64(RDI_EncodeRegReadParam(rdi_regcode, byte_size, byte_pos)));
}break;
//- rjf: space offsets
case RDI_LocationKind_ModuleOff:
{
U64 voff = rdi_voff_from_location(loc);
e_oplist_push_op(arena, &result, RDI_EvalOp_ModuleOff, e_value_u64(voff));
}break;
case RDI_LocationKind_TLSOff:
{
U64 toff = rdi_toff_from_location(loc);
e_oplist_push_op(arena, &result, RDI_EvalOp_TLSOff, e_value_u64(toff));
}break;
case RDI_LocationKind_ConstantDataOff:
{
U64 constant_data_off = rdi_constant_data_off_from_location(loc);
e_oplist_push_uconst(arena, &result, constant_data_off);
}break;
}
return result;
}
////////////////////////////////
//~ rjf: Cache Creation & Selection
+6 -1
View File
@@ -1075,7 +1075,7 @@ struct E_Cache
E_CacheParentNode *free_parent_node;
//- rjf: unpacked context
RDI_Procedure *thread_ip_procedure;
RDI_Symbol *thread_ip_procedure;
//- rjf: [types] JIT-constructed types tables
U64 cons_id_gen;
@@ -1208,6 +1208,11 @@ internal void e_auto_hook_map_insert_new_(Arena *arena, E_AutoHookMap *map, E_Au
internal E_String2NumMap *e_push_locals_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff);
internal E_String2NumMap *e_push_member_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff);
////////////////////////////////
//~ rjf: RDI Location Info -> Eval Op List
internal E_OpList e_oplist_from_location(Arena *arena, RDI_Parsed *rdi, RDI_Location loc);
////////////////////////////////
//~ rjf: Cache Creation & Selection
+11 -32
View File
@@ -12,43 +12,22 @@ e_select_interpret_ctx(E_InterpretCtx *ctx, RDI_Parsed *primary_rdi, U64 ip_voff
// compute and apply frame base
if(primary_rdi != 0)
{
E_Interpretation frame_base = { .code = ~0 };
RDI_Procedure *proc = rdi_procedure_from_voff(primary_rdi, ip_voff);
for(U64 loc_block_idx = proc->frame_base_location_first; loc_block_idx < proc->frame_base_location_opl; loc_block_idx += 1)
Temp scratch = scratch_begin(0, 0);
RDI_Symbol *proc = rdi_procedure_from_voff(primary_rdi, ip_voff);
RDI_Location location = rdi_location_from_location_voff(primary_rdi, proc->location, ip_voff);
E_OpList oplist = e_oplist_from_location(scratch.arena, primary_rdi, location);
String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist);
E_Interpretation frame_base_interpretation = e_interpret(bytecode);
U64 frame_base = frame_base_interpretation.value.u64;
if(frame_base_interpretation.code == E_InterpretationCode_Good)
{
RDI_LocationBlock *block = rdi_element_from_name_idx(primary_rdi, LocationBlocks, loc_block_idx);
if (block->scope_off_first <= ip_voff && ip_voff < block->scope_off_opl) {
U64 all_location_data_size = 0;
U8 *all_location_data = rdi_table_from_name(primary_rdi, LocationData, &all_location_data_size);
if(block->location_data_off + sizeof(RDI_LocationKind) <= all_location_data_size)
{
RDI_LocationKind loc_kind = *(RDI_LocationKind *)(all_location_data + block->location_data_off);
if(loc_kind == RDI_LocationKind_ValBytecodeStream || loc_kind == RDI_LocationKind_AddrBytecodeStream)
{
U8 *bytecode_ptr = all_location_data + block->location_data_off;
U8 *bytecode_opl = all_location_data + all_location_data_size;
U64 bytecode_size = rdi_size_from_bytecode_stream(bytecode_ptr, bytecode_opl);
String8 bytecode = str8(bytecode_ptr + sizeof(RDI_LocationKind), bytecode_size);
frame_base = e_interpret(bytecode);
}
else if(loc_kind != RDI_LocationKind_NULL)
{
NotImplemented;
}
}
break;
}
}
if(frame_base.code == E_InterpretationCode_Good)
{
*ctx->frame_base = frame_base.value.u64;
*ctx->frame_base = frame_base;
}
else
{
ctx->frame_base = 0;
}
scratch_end(scratch);
}
}
@@ -960,7 +939,7 @@ e_interpret(String8 bytecode)
// TODO: add support for pushing multiple values onto the stack
NotImplemented;
}break;
case RDI_EvalOp_PushCfa:
{
nval.u64 = e_interpret_ctx->cfa;
+59 -79
View File
@@ -971,18 +971,18 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
E_DbgInfo *dbg_info = e_dbg_info_from_module(module);
U64 voff = interpretation.value.u64 - module->vaddr_range.min;
U64 new_vaddr = 0;
RDI_Procedure *p = rdi_procedure_from_voff(dbg_info->rdi, voff);
RDI_GlobalVariable *g = rdi_global_variable_from_voff(dbg_info->rdi, voff);
RDI_Symbol *p = rdi_procedure_from_voff(dbg_info->rdi, voff);
RDI_Symbol *g = rdi_global_variable_from_voff(dbg_info->rdi, voff);
U32 type_idx = 0;
if(p->name_string_idx != 0)
{
type_idx = p->type_idx;
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 && rdi_kind_from_location(g->location) == RDI_LocationKind_ModuleOff)
{
type_idx = g->type_idx;
new_vaddr = module->vaddr_range.min + g->voff;
new_vaddr = module->vaddr_range.min + rdi_voff_from_location(g->location);
}
if(type_idx != 0)
{
@@ -1692,8 +1692,8 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
B32 string_mapped = 0;
B32 string_is_implicit_member_name = 0;
E_TypeKey mapped_type_key = zero_struct;
E_Module *mapped_location_block_module = &e_module_nil;
RDI_LocationBlock *mapped_location_block = 0;
E_Module *mapped_location_module = &e_module_nil;
RDI_Location mapped_location = 0;
E_Mode mapped_bytecode_mode = E_Mode_Offset;
E_Space mapped_bytecode_space = zero_struct;
String8 mapped_bytecode = {0};
@@ -1788,7 +1788,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
E_Module *module = e_base_ctx->primary_module;
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_Symbol *procedure = e_cache->thread_ip_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);
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);
@@ -1810,7 +1810,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
U64 local_num = e_num_from_string(e_ir_ctx->locals_map, string__redirected);
if(local_num != 0)
{
RDI_Local *local = rdi_element_from_name_idx(rdi, Locals, local_num-1);
RDI_Symbol *local = rdi_element_from_name_idx(rdi, LocalVariableSymbols, local_num-1);
// rjf: extract local's type key
RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, local->type_idx);
@@ -1819,16 +1819,12 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
// rjf: extract local's location block
B32 got_location_block = 0;
U64 ip_voff = e_base_ctx->thread_ip_voff;
for(U32 loc_block_idx = local->location_first;
loc_block_idx < local->location_opl;
loc_block_idx += 1)
{
RDI_LocationBlock *block = rdi_element_from_name_idx(rdi, LocationBlocks, loc_block_idx);
if(block->scope_off_first <= ip_voff && ip_voff < block->scope_off_opl)
mapped_location = rdi_location_from_location_voff(rdi, local->location, ip_voff);
if(mapped_location != 0)
{
mapped_location_block_module = module;
mapped_location_block = block;
got_location_block = 1;
mapped_location_module = module;
}
}
@@ -1896,7 +1892,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
E_Module *module = e_base_ctx->primary_module;
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_Symbol *procedure = e_cache->thread_ip_procedure;
U64 name_size = 0;
U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size);
String8 containing_procedure_name = str8(name_ptr, name_size);
@@ -1962,72 +1958,30 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
switch(match.section_kind)
{
default:{}break;
case RDI_SectionKind_GlobalVariables:
case RDI_SectionKind_GlobalVariableSymbols:
case RDI_SectionKind_ThreadVariableSymbols:
case RDI_SectionKind_ConstantSymbols:
{
RDI_GlobalVariable *global_var = rdi_element_from_name_idx(rdi, GlobalVariables, match.idx);
U32 type_idx = global_var->type_idx;
RDI_Symbol *symbol = (RDI_Symbol *)rdi_section_raw_element_from_kind_idx(rdi, match.section_kind, match.idx);
U64 ip_voff = e_base_ctx->thread_ip_voff;
RDI_Location location = rdi_location_from_location_voff(rdi, symbol->location, ip_voff);
U32 type_idx = symbol->type_idx;
RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx);
E_OpList oplist = {0};
e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + global_var->voff));
string_mapped = 1;
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_location = location;
mapped_location_module = module;
mapped_bytecode_mode = E_Mode_Offset;
mapped_bytecode_space = module->space;
}break;
case RDI_SectionKind_ThreadVariables:
case RDI_SectionKind_ProcedureSymbols:
{
RDI_ThreadVariable *thread_var = rdi_element_from_name_idx(rdi, ThreadVariables, match.idx);
U32 type_idx = thread_var->type_idx;
RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx);
E_OpList oplist = {0};
e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(thread_var->tls_off));
string_mapped = 1;
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_mode = E_Mode_Offset;
mapped_bytecode_space = module->space;
}break;
case RDI_SectionKind_Constants:
{
RDI_Constant *constant = rdi_element_from_name_idx(rdi, Constants, match.idx);
U32 type_idx = constant->type_idx;
RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx);
RDI_U32 constant_value_off = *rdi_element_from_name_idx(rdi, ConstantValueTable, constant->constant_value_idx);
RDI_U32 constant_value_size = *rdi_element_from_name_idx(rdi, ConstantValueTable, constant->constant_value_idx+1) - constant_value_off;
if(constant_value_size <= 8)
{
RDI_U64 constant_value_data_size = 0;
RDI_U8 *constant_value_data = rdi_table_from_name(rdi, ConstantValueData, &constant_value_data_size);
if(0 <= constant_value_off && constant_value_off + constant_value_size <= constant_value_data_size)
{
RDI_U64 value = 0;
MemoryCopy(&value, constant_value_data+constant_value_off, constant_value_size);
E_OpList oplist = {0};
e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(value));
string_mapped = 1;
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_mode = E_Mode_Value;
mapped_bytecode_space = module->space;
break;
}
}
}break;
case RDI_SectionKind_Procedures:
{
RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, match.idx);
RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, procedure->root_scope_idx);
U64 voff = *rdi_element_from_name_idx(rdi, ScopeVOffData, scope->voff_range_first);
U32 type_idx = procedure->type_idx;
RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx);
E_OpList oplist = {0};
e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff));
string_mapped = 1;
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);
RDI_Symbol *procedure = (RDI_Symbol *)rdi_section_raw_element_from_kind_idx(rdi, match.section_kind, match.idx);
RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, procedure->type_idx);
U64 procedure_base_voff = rdi_first_voff_from_procedure(rdi, procedure);
mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), procedure->type_idx, dbg_info_num);
mapped_location = rdi_location_voff(procedure_base_voff);
mapped_location_module = module;
mapped_bytecode_mode = E_Mode_Value;
mapped_bytecode_space = module->space;
}break;
case RDI_SectionKind_TypeNodes:
{
@@ -2114,14 +2068,39 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
}break;
}
//- rjf: mapped to location block -> extract or produce bytecode for this mapping
if(!generated && mapped_location_block != 0)
//- rjf: mapped to location -> extract or produce bytecode for this mapping
if(!generated && mapped_location != 0 && mapped_bytecode.size == 0)
{
E_Module *module = mapped_location_block_module;
E_Module *module = mapped_location_module;
E_DbgInfo *dbg_info = e_dbg_info_from_module(module);
E_Space space = module->space;
Arch arch = module->arch;
RDI_Parsed *rdi = dbg_info->rdi;
RDI_Location location = mapped_location;
E_OpList oplist = e_oplist_from_location(scratch.arena, rdi, location);
// TODO(rjf): @locpass `space` needs to be set to the constant data space if needed
mapped_bytecode = e_bytecode_from_oplist(arena, &oplist);
mapped_bytecode_space = space;
if(mapped_bytecode_mode == E_Mode_Null)
{
switch(rdi_kind_from_location(mapped_location))
{
default:{}break;
case RDI_LocationKind_ValBytecodeStream:
case RDI_LocationKind_ValReg:
{
mapped_bytecode_mode = E_Mode_Value;
}break;
case RDI_LocationKind_AddrBytecodeStream:
case RDI_LocationKind_AddrRegPlusU16:
case RDI_LocationKind_AddrAddrRegPlusU16:
{
mapped_bytecode_mode = E_Mode_Offset;
}break;
}
}
#if 0 //~TODO(rjf): OLD vvvvvvvvvvvv
RDI_LocationBlock *block = mapped_location_block;
U64 all_location_data_size = 0;
U8 *all_location_data = rdi_table_from_name(rdi, LocationData, &all_location_data_size);
@@ -2204,6 +2183,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
}break;
}
}
#endif
}
//- rjf: generate IR trees for bytecode
@@ -2499,8 +2479,8 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
{
U64 vtable_voff = vtable_vaddr - module_base;
U64 global_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_GlobalVMap, vtable_voff);
RDI_GlobalVariable *global_var = rdi_element_from_name_idx(rdi, GlobalVariables, global_idx);
if(global_var->link_flags & RDI_LinkFlag_TypeScoped)
RDI_Symbol *global_var = rdi_element_from_name_idx(rdi, GlobalVariableSymbols, global_idx);
if(global_var->container_flags & RDI_ContainerFlag_KindMask == RDI_ContainerKind_Type)
{
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);
+1 -1
View File
@@ -59,7 +59,7 @@ struct E_IRState
E_IRCtx *ctx;
// rjf: unpacked ctx
RDI_Procedure *thread_ip_procedure;
RDI_Symbol *thread_ip_procedure;
// rjf: overridden irtree
E_IRTreeAndType *overridden_irtree;