diff --git a/project.4coder b/project.4coder index 444a7d12..767c54a9 100644 --- a/project.4coder +++ b/project.4coder @@ -48,7 +48,7 @@ commands = //- rjf: fkey command slots (change locally but do not commit) .f1 = { .win = "build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, .f2 = { .win = "build rdi_from_pdb", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, - .f3 = { .win = "pushd build && raddbg.exe --user:local_dev.raddbg_user --project:local_dev.raddbg_project --xuto_step && popd",.linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f3 = { .win = "pushd build && raddbg.exe --user:local_dev.raddbg_user --project:local_dev.raddbg_project --auto_step && popd",.linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: local target builds .build_raddbg = { .win = "build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/base/base_meta.c b/src/base/base_meta.c index c5d6b824..add96a07 100644 --- a/src/base/base_meta.c +++ b/src/base/base_meta.c @@ -25,6 +25,55 @@ member_from_name(Type *type, String8 name) //////////////////////////////// //~ rjf: Type Info * Instance Operations +internal void +typed_data_rebase_ptrs(Type *type, String8 data, void *base_ptr) +{ + Temp scratch = scratch_begin(0, 0); + typedef struct RebaseTypeTask RebaseTypeTask; + struct RebaseTypeTask + { + RebaseTypeTask *next; + Type *type; + U8 *ptr; + }; + RebaseTypeTask start_task = {0, type, data.str}; + RebaseTypeTask *first_task = &start_task; + RebaseTypeTask *last_task = first_task; + for(RebaseTypeTask *t = first_task; t != 0; t = t->next) + { + switch(t->type->kind) + { + default:{}break; + case TypeKind_Ptr: + { + *(U64 *)t->ptr = ((U64)(*(U8 **)t->ptr - (U8 *)base_ptr)); + }break; + case TypeKind_Array: + { + for(U64 idx = 0; idx < t->type->count; idx += 1) + { + RebaseTypeTask *task = push_array(scratch.arena, RebaseTypeTask, 1); + task->type = t->type->direct; + task->ptr = t->ptr + t->type->direct->size * idx; + SLLQueuePush(first_task, last_task, task); + } + }break; + case TypeKind_Struct: + { + for(U64 idx = 0; idx < t->type->count; idx += 1) + { + Member *member = &t->type->members[idx]; + RebaseTypeTask *task = push_array(scratch.arena, RebaseTypeTask, 1); + task->type = member->type; + task->ptr = t->ptr + member->value; + SLLQueuePush(first_task, last_task, task); + } + }break; + } + } + scratch_end(scratch); +} + internal String8 serialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerializeParams *params) { @@ -32,10 +81,10 @@ serialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerialize String8List strings = {0}; str8_serial_begin(scratch.arena, &strings); { - typedef struct Task Task; - struct Task + typedef struct SerializeTypeTask SerializeTypeTask; + struct SerializeTypeTask { - Task *next; + SerializeTypeTask *next; Type *type; U64 count; U8 *src; @@ -43,10 +92,10 @@ serialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerialize U8 *containing_ptr; B32 is_post_header; }; - Task start_task = {0, type, 1, data.str}; - Task *first_task = &start_task; - Task *last_task = first_task; - for(Task *t = first_task; t != 0; t = t->next) + SerializeTypeTask start_task = {0, type, 1, data.str}; + SerializeTypeTask *first_task = &start_task; + SerializeTypeTask *last_task = first_task; + for(SerializeTypeTask *t = first_task; t != 0; t = t->next) { switch(t->type->kind) { @@ -93,7 +142,7 @@ serialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerialize // delimit our size, so push a new post-header task for pointer. else if(t->type->count_delimiter_name.size != 0 && !t->is_post_header) { - Task *task = push_array(scratch.arena, Task, 1); + SerializeTypeTask *task = push_array(scratch.arena, SerializeTypeTask, 1); task->type = t->type; task->count = t->count; task->src = t->src; @@ -116,7 +165,7 @@ serialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerialize } // rjf: push task - Task *task = push_array(scratch.arena, Task, 1); + SerializeTypeTask *task = push_array(scratch.arena, SerializeTypeTask, 1); task->type = t->type->direct; task->count = count; task->src = *(void **)t->src; @@ -129,7 +178,7 @@ serialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerialize //- rjf: arrays -> descend to underlying type, + count case TypeKind_Array: { - Task *task = push_array(scratch.arena, Task, 1); + SerializeTypeTask *task = push_array(scratch.arena, SerializeTypeTask, 1); task->type = t->type->direct; task->count = t->type->count; task->src = t->src; @@ -150,10 +199,10 @@ serialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerialize { continue; } - Task *task = push_array(scratch.arena, Task, 1); + SerializeTypeTask *task = push_array(scratch.arena, SerializeTypeTask, 1); task->type = t->type->members[member_idx].type; task->count = 1; - task->src = t->src + t->type->members[member_idx].value; + task->src = t->src + idx*t->type->size + t->type->members[member_idx].value; task->containing_type = t->type; task->containing_ptr = t->src; SLLQueuePush(first_task, last_task, task); @@ -164,7 +213,7 @@ serialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerialize //- rjf: enum -> descend to basic type interpretation case TypeKind_Enum: { - Task *task = push_array(scratch.arena, Task, 1); + SerializeTypeTask *task = push_array(scratch.arena, SerializeTypeTask, 1); task->type = t->type->direct; task->count = t->count; task->src = t->src; @@ -188,10 +237,10 @@ deserialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSeriali result.str = push_array(arena, U8, result.size); { Temp scratch = scratch_begin(&arena, 1); - typedef struct Task Task; - struct Task + typedef struct DeserializeTypeTask DeserializeTypeTask; + struct DeserializeTypeTask { - Task *next; + DeserializeTypeTask *next; Type *type; U64 count; U8 *dst; @@ -200,10 +249,10 @@ deserialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSeriali B32 is_post_header; }; U64 read_off = 0; - Task start_task = {0, type, 1, result.str}; - Task *first_task = &start_task; - Task *last_task = first_task; - for(Task *t = first_task; t != 0; t = t->next) + DeserializeTypeTask start_task = {0, type, 1, result.str}; + DeserializeTypeTask *first_task = &start_task; + DeserializeTypeTask *last_task = first_task; + for(DeserializeTypeTask *t = first_task; t != 0; t = t->next) { U8 *t_src = data.str + read_off; switch(t->type->kind) @@ -254,7 +303,7 @@ deserialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSeriali // delimit our size, so push a new post-header task for pointer. else if(t->type->count_delimiter_name.size != 0 && !t->is_post_header) { - Task *task = push_array(scratch.arena, Task, 1); + DeserializeTypeTask *task = push_array(scratch.arena, DeserializeTypeTask, 1); task->type = t->type; task->count = t->count; task->dst = t->dst; @@ -282,7 +331,7 @@ deserialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSeriali MemoryCopy(t->dst, &ptr_dest_buffer, sizeof(ptr_dest_buffer)); // rjf: push task - Task *task = push_array(scratch.arena, Task, 1); + DeserializeTypeTask *task = push_array(scratch.arena, DeserializeTypeTask, 1); task->type = t->type->direct; task->count = count; task->dst = ptr_dest_buffer; @@ -295,7 +344,7 @@ deserialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSeriali //- rjf: arrays -> descend to underlying type, + count case TypeKind_Array: { - Task *task = push_array(scratch.arena, Task, 1); + DeserializeTypeTask *task = push_array(scratch.arena, DeserializeTypeTask, 1); task->type = t->type->direct; task->count = t->type->count; task->dst = t->dst; @@ -315,10 +364,10 @@ deserialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSeriali { continue; } - Task *task = push_array(scratch.arena, Task, 1); + DeserializeTypeTask *task = push_array(scratch.arena, DeserializeTypeTask, 1); task->type = t->type->members[member_idx].type; task->count = 1; - task->dst = t->dst + t->type->members[member_idx].value; + task->dst = t->dst + idx*t->type->size + t->type->members[member_idx].value; task->containing_type = t->type; task->containing_ptr = t->dst; SLLQueuePush(first_task, last_task, task); @@ -329,7 +378,7 @@ deserialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSeriali //- rjf: enum -> descend to basic type interpretation case TypeKind_Enum: { - Task *task = push_array(scratch.arena, Task, 1); + DeserializeTypeTask *task = push_array(scratch.arena, DeserializeTypeTask, 1); task->type = t->type->direct; task->count = t->count; task->dst = t->dst; diff --git a/src/base/base_meta.h b/src/base/base_meta.h index ccfcf0b4..908cff65 100644 --- a/src/base/base_meta.h +++ b/src/base/base_meta.h @@ -249,9 +249,11 @@ internal Member *member_from_name(Type *type, String8 name); //////////////////////////////// //~ rjf: Type Info * Instance Operations +internal void typed_data_rebase_ptrs(Type *type, String8 data, void *base_ptr); internal String8 serialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerializeParams *params); internal String8 deserialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerializeParams *params); internal String8 deep_copy_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerializeParams *params); +#define struct_rebase_ptrs(T, ptr, base) typed_data_rebase_ptrs(type(T), str8_struct(ptr), (base)) #define serialized_from_struct(arena, T, ptr, ...) serialized_from_typed_data((arena), type(T), str8_struct(ptr), &(TypeSerializeParams){.ptr_ref_infos = 0, __VA_ARGS__}) #define struct_from_serialized(arena, T, string, ...) (T *)deserialized_from_typed_data((arena), type(T), (string), &(TypeSerializeParams){.ptr_ref_infos = 0, __VA_ARGS__}).str #define deep_copy_from_struct(arena, T, ptr, ...) (T *)deep_copy_from_typed_data((arena), type(T), str8_struct(ptr), &(TypeSerializeParams){.ptr_ref_infos = 0, __VA_ARGS__}).str diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 95b94603..1ccb6a5a 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -15,6 +15,31 @@ typedef U64 CTRL_MachineID; //////////////////////////////// //~ rjf: Meta Evaluation Types +//- rjf: meta evaluation callstack +typedef struct CTRL_MetaEvalFrame CTRL_MetaEvalFrame; +struct CTRL_MetaEvalFrame +{ + U64 vaddr; +}; +struct_members(CTRL_MetaEvalFrame) +{ + member_lit_comp(CTRL_MetaEvalFrame, type(U64), vaddr), +}; +struct_type(CTRL_MetaEvalFrame); +typedef struct CTRL_MetaEvalFrameArray CTRL_MetaEvalFrameArray; +struct CTRL_MetaEvalFrameArray +{ + U64 count; + CTRL_MetaEvalFrame *v; +}; +ptr_type(CTRL_MetaEvalFrameArray__v_ptr_type, type(CTRL_MetaEvalFrame), .count_delimiter_name = str8_lit_comp("count")); +struct_members(CTRL_MetaEvalFrameArray) +{ + member_lit_comp(CTRL_MetaEvalFrameArray, type(U64), count), + {str8_lit_comp("v"), &CTRL_MetaEvalFrameArray__v_ptr_type, OffsetOf(CTRL_MetaEvalFrameArray, v)}, +}; +struct_type(CTRL_MetaEvalFrameArray); + //- rjf: meta evaluation instance typedef struct CTRL_MetaEval CTRL_MetaEval; struct CTRL_MetaEval @@ -27,7 +52,8 @@ X(U64, id)\ X(U32, color)\ X(String8, label)\ X(String8, location)\ -X(String8, condition) +X(String8, condition)\ +X(CTRL_MetaEvalFrameArray, callstack) #define X(T, name) T name; CTRL_MetaEval_MemberXList #undef X diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 5e25921d..b2664fae 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1865,15 +1865,7 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) U64 pos_min = arena_pos(scratch.arena); String8 eval_srlzed = serialized_from_struct(scratch.arena, CTRL_MetaEval, eval); CTRL_MetaEval *eval_read = struct_from_serialized(scratch.arena, CTRL_MetaEval, eval_srlzed); - for EachMember(CTRL_MetaEval, m) - { - if(str8_match(m->type->name, str8_lit("String8"), 0)) - { - U64 ptr_value = *(U64 *)((U8 *)eval_read + m->value); - U64 space_relative_ptr_value = ptr_value - (U64)eval_read; - *(U64 *)((U8 *)eval_read + m->value) = space_relative_ptr_value; - } - } + struct_rebase_ptrs(CTRL_MetaEval, eval_read, eval_read); U64 pos_opl = arena_pos(scratch.arena); Rng1U64 legal_range = r1u64(0, pos_opl-pos_min); if(contains_1u64(legal_range, range.min)) @@ -10228,6 +10220,26 @@ rd_frame(void) meval->color = entity->rgba; meval->label = entity->string; meval->id = entity->id; + if(entity->kind == CTRL_EntityKind_Thread) + { + CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); + CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(entity); + D_Unwind rich_unwind = d_unwind_from_ctrl_unwind(scratch.arena, di_scope, process, &base_unwind); + meval->callstack.count = rich_unwind.frames.total_frame_count; + meval->callstack.v = push_array(scratch.arena, CTRL_MetaEvalFrame, meval->callstack.count); + U64 idx = 0; + for(U64 base_idx = 0; base_idx < rich_unwind.frames.concrete_frame_count; base_idx += 1) + { + U64 inline_idx = 0; + for(D_UnwindInlineFrame *f = rich_unwind.frames.v[base_idx].first_inline_frame; f != 0; f = f->next, inline_idx += 1) + { + meval->callstack.v[idx].vaddr = regs_rip_from_arch_block(entity->arch, rich_unwind.frames.v[base_idx].regs); + idx += 1; + } + meval->callstack.v[idx].vaddr = regs_rip_from_arch_block(entity->arch, rich_unwind.frames.v[base_idx].regs); + idx += 1; + } + } meta_eval_idx += 1; } } @@ -10276,23 +10288,14 @@ rd_frame(void) ctx->macro_map = push_array(scratch.arena, E_String2ExprMap, 1); ctx->macro_map[0] = e_string2expr_map_make(scratch.arena, 512); - //- rjf: add macros for constants + //- rjf: add macros for all evallable frontend entities + { + + } + + //- rjf: add macros for all evallable control entities { - // rjf: pid -> current process' ID - if(process != &ctrl_entity_nil) - { - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafU64, 0); - expr->value.u64 = process->id; - e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("pid"), expr); - } - // rjf: tid -> current thread's ID - if(thread != &ctrl_entity_nil) - { - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafU64, 0); - expr->value.u64 = thread->id; - e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("tid"), expr); - } } //- rjf: add macros for meta evaluations