diff --git a/src/base/base_arena.c b/src/base/base_arena.c index 626808dc..314fcd9e 100644 --- a/src/base/base_arena.c +++ b/src/base/base_arena.c @@ -37,6 +37,7 @@ arena_alloc_(ArenaParams *params) base = os_reserve(reserve_size); os_commit(base, commit_size); } + raddbg_annotate_vaddr_range(base, reserve_size, "arena %s:%i", params->allocation_site_file, params->allocation_site_line); } // rjf: panic on arena creation failure @@ -58,6 +59,8 @@ arena_alloc_(ArenaParams *params) arena->pos = ARENA_HEADER_SIZE; arena->cmt = commit_size; arena->res = reserve_size; + arena->allocation_site_file = params->allocation_site_file; + arena->allocation_site_line = params->allocation_site_line; #if ARENA_FREE_LIST arena->free_size = 0; arena->free_last = 0; @@ -123,7 +126,9 @@ arena_push(Arena *arena, U64 size, U64 align) } new_block = arena_alloc(.reserve_size = res_size, .commit_size = cmt_size, - .flags = current->flags); + .flags = current->flags, + .allocation_site_file = current->allocation_site_file, + .allocation_site_line = current->allocation_site_line); } new_block->base_pos = current->base_pos + current->res; diff --git a/src/base/base_arena.h b/src/base/base_arena.h index 25aafe7f..47c5238d 100644 --- a/src/base/base_arena.h +++ b/src/base/base_arena.h @@ -26,6 +26,8 @@ struct ArenaParams U64 reserve_size; U64 commit_size; void *optional_backing_buffer; + char *allocation_site_file; + int allocation_site_line; }; typedef struct Arena Arena; @@ -40,6 +42,8 @@ struct Arena U64 pos; U64 cmt; U64 res; + char *allocation_site_file; + int allocation_site_line; #if ARENA_FREE_LIST U64 free_size; Arena *free_last; @@ -66,7 +70,7 @@ global ArenaFlags arena_default_flags = 0; //- rjf: arena creation/destruction internal Arena *arena_alloc_(ArenaParams *params); -#define arena_alloc(...) arena_alloc_(&(ArenaParams){.reserve_size = arena_default_reserve_size, .commit_size = arena_default_commit_size, .flags = arena_default_flags, __VA_ARGS__}) +#define arena_alloc(...) arena_alloc_(&(ArenaParams){.reserve_size = arena_default_reserve_size, .commit_size = arena_default_commit_size, .flags = arena_default_flags, .allocation_site_file = __FILE__, .allocation_site_line = __LINE__, __VA_ARGS__}) internal void arena_release(Arena *arena); //- rjf: arena push/pop/pos core functions diff --git a/src/ctrl/ctrl.mdesk b/src/ctrl/ctrl.mdesk index d3f74faf..9684baeb 100644 --- a/src/ctrl/ctrl.mdesk +++ b/src/ctrl/ctrl.mdesk @@ -7,16 +7,17 @@ @table(name code_name display_string) CTRL_EntityKindTable: { - {Root root "Root" } - {Machine machine "Machine" } - {Process process "Process" } - {Thread thread "Thread" } - {Module module "Module" } - {EntryPoint entry_point "Entry Point" } - {DebugInfoPath debug_info_path "Debug Info Path" } - {PendingThreadName pending_thread_name "Pending Thread Name" } - {PendingThreadColor pending_thread_color "Pending Thread Color" } - {Breakpoint breakpoint "Breakpoint" } + {Root root "Root" } + {Machine machine "Machine" } + {Process process "Process" } + {Thread thread "Thread" } + {Module module "Module" } + {EntryPoint entry_point "Entry Point" } + {DebugInfoPath debug_info_path "Debug Info Path" } + {PendingThreadName pending_thread_name "Pending Thread Name" } + {PendingThreadColor pending_thread_color "Pending Thread Color" } + {Breakpoint breakpoint "Breakpoint" } + {AddressRangeAnnotation address_range_annotation "Address Range Annotation" } } @enum CTRL_EntityKind: diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index de86dd84..c88ad7c0 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -1399,6 +1399,15 @@ ctrl_entity_store_apply_events(CTRL_EntityCtxRWStore *store, CTRL_EventList *lis } } }break; + + //- rjf: address range annotations + case CTRL_EventKind_SetVAddrRangeNote: + { + CTRL_Entity *process = ctrl_entity_from_handle(&store->ctx, event->parent); + CTRL_Entity *annotation = ctrl_entity_alloc(store, process, CTRL_EntityKind_AddressRangeAnnotation, Arch_Null, ctrl_handle_zero(), 0); + annotation->vaddr_range = event->vaddr_rng; + ctrl_entity_equip_string(store, annotation, event->string); + }break; } } } @@ -4666,6 +4675,15 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, out_evt->entity_id = event->code; out_evt->rgba = event->user_data; }break; + case DMN_EventKind_SetVAddrRangeNote: + { + CTRL_Event *out_evt = ctrl_event_list_push(scratch.arena, &evts); + out_evt->kind = CTRL_EventKind_SetVAddrRangeNote; + out_evt->parent = ctrl_handle_make(CTRL_MachineID_Local, event->process); + out_evt->msg_id = msg->msg_id; + out_evt->vaddr_rng = r1u64(event->address, event->address + event->size); + out_evt->string = event->string; + } case DMN_EventKind_SetBreakpoint: { CTRL_Event *out_evt = ctrl_event_list_push(scratch.arena, &evts); diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index d29a5f41..8bac1f4c 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -424,6 +424,7 @@ typedef enum CTRL_EventKind CTRL_EventKind_ThreadColor, CTRL_EventKind_SetBreakpoint, CTRL_EventKind_UnsetBreakpoint, + CTRL_EventKind_SetVAddrRangeNote, //- rjf: memory CTRL_EventKind_MemReserve, diff --git a/src/ctrl/generated/ctrl.meta.c b/src/ctrl/generated/ctrl.meta.c index 7f498081..09d20976 100644 --- a/src/ctrl/generated/ctrl.meta.c +++ b/src/ctrl/generated/ctrl.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -String8 ctrl_entity_kind_code_name_table[11] = +String8 ctrl_entity_kind_code_name_table[12] = { {0}, str8_lit_comp("root"), @@ -17,9 +17,10 @@ str8_lit_comp("debug_info_path"), str8_lit_comp("pending_thread_name"), str8_lit_comp("pending_thread_color"), str8_lit_comp("breakpoint"), +str8_lit_comp("address_range_annotation"), }; -String8 ctrl_entity_kind_display_string_table[11] = +String8 ctrl_entity_kind_display_string_table[12] = { {0}, str8_lit_comp("Root"), @@ -32,6 +33,7 @@ str8_lit_comp("DebugInfoPath"), str8_lit_comp("PendingThreadName"), str8_lit_comp("PendingThreadColor"), str8_lit_comp("Breakpoint"), +str8_lit_comp("AddressRangeAnnotation"), }; U32 ctrl_exception_code_kind_code_table[38] = diff --git a/src/ctrl/generated/ctrl.meta.h b/src/ctrl/generated/ctrl.meta.h index 732dbfc2..5495f320 100644 --- a/src/ctrl/generated/ctrl.meta.h +++ b/src/ctrl/generated/ctrl.meta.h @@ -19,6 +19,7 @@ CTRL_EntityKind_DebugInfoPath, CTRL_EntityKind_PendingThreadName, CTRL_EntityKind_PendingThreadColor, CTRL_EntityKind_Breakpoint, +CTRL_EntityKind_AddressRangeAnnotation, CTRL_EntityKind_COUNT, } CTRL_EntityKind; @@ -66,8 +67,8 @@ CTRL_ExceptionCodeKind_COUNT, } CTRL_ExceptionCodeKind; C_LINKAGE_BEGIN -extern String8 ctrl_entity_kind_code_name_table[11]; -extern String8 ctrl_entity_kind_display_string_table[11]; +extern String8 ctrl_entity_kind_code_name_table[12]; +extern String8 ctrl_entity_kind_display_string_table[12]; extern U32 ctrl_exception_code_kind_code_table[38]; extern String8 ctrl_exception_code_kind_display_string_table[38]; extern String8 ctrl_exception_code_kind_lowercase_code_string_table[38]; diff --git a/src/demon/demon_core.mdesk b/src/demon/demon_core.mdesk index 3c9a367e..78e49001 100644 --- a/src/demon/demon_core.mdesk +++ b/src/demon/demon_core.mdesk @@ -24,6 +24,7 @@ DMN_EventKindTable: {SetThreadColor} {SetBreakpoint} {UnsetBreakpoint} + {SetVAddrRangeNote} } @table(name) diff --git a/src/demon/generated/demon.meta.c b/src/demon/generated/demon.meta.c index 70a2272d..cf282f4a 100644 --- a/src/demon/generated/demon.meta.c +++ b/src/demon/generated/demon.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -String8 dmn_event_kind_string_table[20] = +String8 dmn_event_kind_string_table[21] = { str8_lit_comp("Null"), str8_lit_comp("Error"), @@ -26,6 +26,7 @@ str8_lit_comp("SetThreadName"), str8_lit_comp("SetThreadColor"), str8_lit_comp("SetBreakpoint"), str8_lit_comp("UnsetBreakpoint"), +str8_lit_comp("SetVAddrRangeNote"), }; String8 dmn_exception_kind_string_table[5] = diff --git a/src/demon/generated/demon.meta.h b/src/demon/generated/demon.meta.h index 94140c1f..7e1513e0 100644 --- a/src/demon/generated/demon.meta.h +++ b/src/demon/generated/demon.meta.h @@ -28,6 +28,7 @@ DMN_EventKind_SetThreadName, DMN_EventKind_SetThreadColor, DMN_EventKind_SetBreakpoint, DMN_EventKind_UnsetBreakpoint, +DMN_EventKind_SetVAddrRangeNote, DMN_EventKind_COUNT, } DMN_EventKind; @@ -61,7 +62,7 @@ DMN_ExceptionKind_COUNT, } DMN_ExceptionKind; C_LINKAGE_BEGIN -extern String8 dmn_event_kind_string_table[20]; +extern String8 dmn_event_kind_string_table[21]; extern String8 dmn_exception_kind_string_table[5]; C_LINKAGE_END diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index 76399ae1..1ded7853 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -2560,6 +2560,21 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) if(exec) { e->flags |= DMN_TrapFlag_BreakOnExecute; } }break; + //- rjf: fill set-vaddr-range-note info + case DMN_W32_EXCEPTION_RADDBG_SET_VADDR_RANGE_NOTE: + { + U64 vaddr = exception->ExceptionInformation[0]; + U64 size = exception->ExceptionInformation[1]; + U64 name_vaddr = exception->ExceptionInformation[2]; + U64 name_size = exception->ExceptionInformation[3]; + U8 *name_buffer = push_array(arena, U8, name_size); + dmn_w32_process_read(process->handle, r1u64(name_vaddr, name_vaddr+name_size), name_buffer), + e->kind = DMN_EventKind_SetVAddrRangeNote; + e->address = vaddr; + e->size = size; + e->string = str8(name_buffer, name_size); + }break; + //- rjf: unhandled exception case default: { diff --git a/src/demon/win32/demon_core_win32.h b/src/demon/win32/demon_core_win32.h index bc6a2e0a..bb3fbfbe 100644 --- a/src/demon/win32/demon_core_win32.h +++ b/src/demon/win32/demon_core_win32.h @@ -58,6 +58,7 @@ #define DMN_w32_EXCEPTION_CLR 0xE0434352u #define DMN_W32_EXCEPTION_RADDBG_SET_THREAD_COLOR 0x00524144u #define DMN_W32_EXCEPTION_RADDBG_SET_BREAKPOINT 0x00524145u +#define DMN_W32_EXCEPTION_RADDBG_SET_VADDR_RANGE_NOTE 0x00524156u //////////////////////////////// //~ rjf: Win32 Register Codes diff --git a/src/lib_raddbg_markup/raddbg_markup.h b/src/lib_raddbg_markup/raddbg_markup.h index dcff48de..ba405bac 100644 --- a/src/lib_raddbg_markup/raddbg_markup.h +++ b/src/lib_raddbg_markup/raddbg_markup.h @@ -37,6 +37,7 @@ # define raddbg_type_view(type, ...) raddbg_exe_data char raddbg_gen_data_id()[] = ("type_view: {type: ```" #type "```, expr: ```" #__VA_ARGS__ "```}") # define raddbg_add_breakpoint(ptr, size, r, w, x) raddbg_add_or_remove_breakpoint__impl((ptr), (1), (size), (r), (w), (x)) # define raddbg_remove_breakpoint(ptr, size, r, w, x) raddbg_add_or_remove_breakpoint__impl((ptr), (0), (size), (r), (w), (x)) +# define raddbg_annotate_vaddr_range(ptr, size, ...) raddbg_annotate_vaddr_range__impl((ptr), (size), __VA_ARGS__) #else # define raddbg_is_attached(...) (0) # define raddbg_thread_id(...) ((void)0) @@ -55,6 +56,7 @@ # define raddbg_type_view(type, ...) struct raddbg_gen_data_id(){int __unused__;} # define raddbg_add_breakpoint(ptr, size, r, w, x) ((void)0) # define raddbg_remove_breakpoint(ptr, size, r, w, x) ((void)0) +# define raddbg_annotate_vaddr_range(ptr, size, ...) ((void)0) #endif //////////////////////////////// @@ -399,6 +401,50 @@ raddbg_add_or_remove_breakpoint__impl(void *ptr, int set, int size, int r, int w } } +static inline void +raddbg_annotate_vaddr_range__impl(void *ptr, unsigned __int64 size, char *fmt, ...) +{ + if(raddbg_is_attached()) + { + // rjf: resolve variadic arguments + char buffer[4096]; + int buffer_size = 0; + { + va_list args; + va_start(args, fmt); + buffer_size = RADDBG_MARKUP_VSNPRINTF(buffer, sizeof(buffer), fmt, args); + va_end(args); + } + + // rjf: send annotation info via exception +#pragma pack(push, 8) + typedef struct RADDBG_VaddrRangeAnnotationInfo RADDBG_VaddrRangeAnnotationInfo; + struct RADDBG_VaddrRangeAnnotationInfo + { + unsigned __int64 vaddr; + unsigned __int64 size; + void *name; + unsigned __int64 name_size; + }; +#pragma pack(pop) + RADDBG_VaddrRangeAnnotationInfo info; + info.vaddr = (unsigned __int64)ptr; + info.size = size; + info.name = buffer; + info.name_size = buffer_size; +#pragma warning(push) +#pragma warning(disable: 6320 6322) + __try + { + RaiseException(0x00524156u, 0, sizeof(info) / sizeof(void *), (const ULONG_PTR *)&info); + } + __except(1) + { + } +#pragma warning(pop) + } +} + #endif // defined(_WIN32) #endif // defined(RADDBG_MARKUP_IMPLEMENTATION) diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index da13244c..24b82025 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -1880,6 +1880,11 @@ fancy_viz_eval_tests(void) raddbg_pin(text(code_string, lang=c)); raddbg_pin(disasm(fancy_viz_eval_tests)); + //- rjf: programmatic memory annotations + void *some_block_of_memory = malloc(256); + memset(some_block_of_memory, 0x27, 256); + raddbg_annotate_vaddr_range(some_block_of_memory, 256, "test memory annotation"); + //- rjf: half-floats PackedF16 f16s[] = { diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 444558ab..b3468ba9 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -2517,6 +2517,10 @@ RD_VIEW_UI_FUNCTION_DEF(memory) ////////////////////////////// //- rjf: unpack parameterization info // + Vec4F32 main_bg_color_rgba = ui_color_from_name(str8_lit("background")); + Vec4F32 main_bg_color_hsva = hsva_from_rgba(main_bg_color_rgba); + Vec4F32 main_tx_color_rgba = ui_color_from_name(str8_lit("text")); + Vec4F32 main_tx_color_hsva = hsva_from_rgba(main_tx_color_rgba); F32 main_font_size = ui_bottom_font_size(); U64 base_offset = e_base_offset_from_eval(eval); U64 size = rd_view_setting_value_from_name(str8_lit("size")).u64; @@ -2904,42 +2908,52 @@ RD_VIEW_UI_FUNCTION_DEF(memory) typedef struct Annotation Annotation; struct Annotation { - Annotation *next; String8 name_string; String8 kind_string; String8 type_string; Vec4F32 color; Rng1U64 vaddr_range; }; + typedef struct AnnotationNode AnnotationNode; + struct AnnotationNode + { + AnnotationNode *next; + Annotation *v; + }; typedef struct AnnotationList AnnotationList; struct AnnotationList { - Annotation *first; - Annotation *last; + AnnotationNode *first; + AnnotationNode *last; }; AnnotationList *visible_memory_annotations = push_array(scratch.arena, AnnotationList, visible_memory_size); { CTRL_Scope *ctrl_scope = ctrl_scope_open(); - CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->thread); - CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); - CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, &d_state->ctrl_entity_store->ctx, thread, 1, 0); + CTRL_Entity *selected_thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->thread); + CTRL_Entity *selected_process = ctrl_entity_ancestor_from_kind(selected_thread, CTRL_EntityKind_Process); + CTRL_CallStack selected_call_stack = ctrl_call_stack_from_thread(ctrl_scope, &d_state->ctrl_entity_store->ctx, selected_thread, 1, 0); + CTRL_Entity *eval_process = &ctrl_entity_nil; + if(eval.space.kind == RD_EvalSpaceKind_CtrlEntity) + { + eval_process = rd_ctrl_entity_from_eval_space(eval.space); + } //- rjf: fill unwind frame annotations - if(call_stack.concrete_frames_count != 0) UI_Tag(str8_lit("weak")) + if(selected_call_stack.concrete_frames_count != 0) UI_Tag(str8_lit("weak")) { - U64 last_stack_top = regs_rsp_from_arch_block(thread->arch, call_stack.concrete_frames[0]->regs); - for(U64 idx = 1; idx < call_stack.concrete_frames_count; idx += 1) + U64 last_stack_top = regs_rsp_from_arch_block(selected_thread->arch, selected_call_stack.concrete_frames[0]->regs); + for(U64 idx = 1; idx < selected_call_stack.concrete_frames_count; idx += 1) { - CTRL_CallStackFrame *f = call_stack.concrete_frames[idx]; - U64 f_stack_top = regs_rsp_from_arch_block(thread->arch, f->regs); + CTRL_CallStackFrame *f = selected_call_stack.concrete_frames[idx]; + U64 f_stack_top = regs_rsp_from_arch_block(selected_thread->arch, f->regs); Rng1U64 frame_vaddr_range = r1u64(last_stack_top, f_stack_top); Rng1U64 frame_vaddr_range_in_viz = intersect_1u64(frame_vaddr_range, viz_range_bytes); last_stack_top = f_stack_top; if(dim_1u64(frame_vaddr_range_in_viz) != 0) { DI_Scope *scope = di_scope_open(); - U64 f_rip_vaddr = regs_rip_from_arch_block(thread->arch, f->regs); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, f_rip_vaddr); + U64 f_rip_vaddr = regs_rip_from_arch_block(selected_thread->arch, f->regs); + CTRL_Entity *module = ctrl_module_from_process_vaddr(selected_process, f_rip_vaddr); U64 f_rip_voff = ctrl_voff_from_vaddr(module, f_rip_vaddr); DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); RDI_Parsed *rdi = di_rdi_from_key(scope, &dbgi_key, 0); @@ -2957,7 +2971,9 @@ RD_VIEW_UI_FUNCTION_DEF(memory) for(U64 vaddr = frame_vaddr_range_in_viz.min; vaddr < frame_vaddr_range_in_viz.max; vaddr += 1) { U64 visible_byte_idx = vaddr - viz_range_bytes.min; - SLLQueuePush(visible_memory_annotations[visible_byte_idx].first, visible_memory_annotations[visible_byte_idx].last, annotation); + AnnotationNode *n = push_array(scratch.arena, AnnotationNode, 1); + n->v = annotation; + SLLQueuePush(visible_memory_annotations[visible_byte_idx].first, visible_memory_annotations[visible_byte_idx].last, n); } } } @@ -2965,29 +2981,31 @@ RD_VIEW_UI_FUNCTION_DEF(memory) } //- rjf: fill selected thread stack range annotation - if(call_stack.concrete_frames_count > 0) + if(selected_call_stack.concrete_frames_count > 0) { - U64 stack_base_vaddr = thread->stack_base; - U64 stack_top_vaddr = regs_rsp_from_arch_block(thread->arch, call_stack.concrete_frames[0]->regs); + U64 stack_base_vaddr = selected_thread->stack_base; + U64 stack_top_vaddr = regs_rsp_from_arch_block(selected_thread->arch, selected_call_stack.concrete_frames[0]->regs); Rng1U64 stack_vaddr_range = r1u64(stack_base_vaddr, stack_top_vaddr); Rng1U64 stack_vaddr_range_in_viz = intersect_1u64(stack_vaddr_range, viz_range_bytes); if(dim_1u64(stack_vaddr_range_in_viz) != 0) { Annotation *annotation = push_array(scratch.arena, Annotation, 1); - annotation->name_string = thread->string.size ? thread->string : push_str8f(scratch.arena, "TID: %I64u", thread->id); + annotation->name_string = selected_thread->string.size ? selected_thread->string : push_str8f(scratch.arena, "TID: %I64u", selected_thread->id); annotation->kind_string = str8_lit("Stack"); - annotation->color = rd_color_from_ctrl_entity(thread); + annotation->color = rd_color_from_ctrl_entity(selected_thread); annotation->vaddr_range = stack_vaddr_range; for(U64 vaddr = stack_vaddr_range_in_viz.min; vaddr < stack_vaddr_range_in_viz.max; vaddr += 1) { U64 visible_byte_idx = vaddr - viz_range_bytes.min; - SLLQueuePush(visible_memory_annotations[visible_byte_idx].first, visible_memory_annotations[visible_byte_idx].last, annotation); + AnnotationNode *n = push_array(scratch.arena, AnnotationNode, 1); + n->v = annotation; + SLLQueuePush(visible_memory_annotations[visible_byte_idx].first, visible_memory_annotations[visible_byte_idx].last, n); } } } //- rjf: fill local variable annotations - if(e_space_match(rd_eval_space_from_ctrl_entity(process, RD_EvalSpaceKind_CtrlEntity), eval.space)) + if(e_space_match(rd_eval_space_from_ctrl_entity(selected_process, RD_EvalSpaceKind_CtrlEntity), eval.space)) { DI_Scope *scope = di_scope_open(); Vec4F32 local_color = ui_color_from_name(str8_lit("code_local")); @@ -2998,7 +3016,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) mix_4f32(local_color, v4f32(0, 0, 0, 1), 0.6f), mix_4f32(local_color, v4f32(0, 0, 0, 1), 0.8f), }; - U64 thread_rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, rd_regs()->unwind_count); + U64 thread_rip_vaddr = d_query_cached_rip_from_thread_unwind(selected_thread, rd_regs()->unwind_count); for(E_String2NumMapNode *n = e_ir_ctx->locals_map->first; n != 0; n = n->order_next) { String8 local_name = n->string; @@ -3021,7 +3039,9 @@ RD_VIEW_UI_FUNCTION_DEF(memory) } for(U64 vaddr = vaddr_rng_in_visible.min; vaddr < vaddr_rng_in_visible.max; vaddr += 1) { - SLLQueuePushFront(visible_memory_annotations[vaddr-viz_range_bytes.min].first, visible_memory_annotations[vaddr-viz_range_bytes.min].last, annotation); + AnnotationNode *n = push_array(scratch.arena, AnnotationNode, 1); + n->v = annotation; + SLLQueuePushFront(visible_memory_annotations[vaddr-viz_range_bytes.min].first, visible_memory_annotations[vaddr-viz_range_bytes.min].last, n); } } } @@ -3030,7 +3050,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) } //- rjf: fill procedures annotations - if(e_space_match(rd_eval_space_from_ctrl_entity(process, RD_EvalSpaceKind_CtrlEntity), eval.space)) + if(eval_process != &ctrl_entity_nil) { Vec4F32 symbol_color = ui_color_from_name(str8_lit("code_symbol")); Vec4F32 color_gen_table[] = @@ -3046,7 +3066,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) { next_vaddr = vaddr+1; DI_Scope *scope = di_scope_open(); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); + CTRL_Entity *module = ctrl_module_from_process_vaddr(eval_process, vaddr); if(module != &ctrl_entity_nil) { U64 voff = ctrl_voff_from_vaddr(module, vaddr); @@ -3075,7 +3095,9 @@ RD_VIEW_UI_FUNCTION_DEF(memory) } for(U64 vaddr = vaddr_range_in_visible.min; vaddr < vaddr_range_in_visible.max; vaddr += 1) { - SLLQueuePushFront(visible_memory_annotations[vaddr-viz_range_bytes.min].first, visible_memory_annotations[vaddr-viz_range_bytes.min].last, annotation); + AnnotationNode *n = push_array(scratch.arena, AnnotationNode, 1); + n->v = annotation; + SLLQueuePushFront(visible_memory_annotations[vaddr-viz_range_bytes.min].first, visible_memory_annotations[vaddr-viz_range_bytes.min].last, n); } } } @@ -3085,7 +3107,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) } //- rjf: fill globals annotations - if(e_space_match(rd_eval_space_from_ctrl_entity(process, RD_EvalSpaceKind_CtrlEntity), eval.space)) + if(eval_process != &ctrl_entity_nil) { Vec4F32 symbol_color = ui_color_from_name(str8_lit("code_symbol")); Vec4F32 color_gen_table[] = @@ -3101,7 +3123,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) { next_vaddr = vaddr+1; DI_Scope *scope = di_scope_open(); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); + CTRL_Entity *module = ctrl_module_from_process_vaddr(eval_process, vaddr); if(module != &ctrl_entity_nil) { U64 voff = ctrl_voff_from_vaddr(module, vaddr); @@ -3129,7 +3151,9 @@ RD_VIEW_UI_FUNCTION_DEF(memory) } for(U64 vaddr = vaddr_range_in_visible.min; vaddr < vaddr_range_in_visible.max; vaddr += 1) { - SLLQueuePushFront(visible_memory_annotations[vaddr-viz_range_bytes.min].first, visible_memory_annotations[vaddr-viz_range_bytes.min].last, annotation); + AnnotationNode *n = push_array(scratch.arena, AnnotationNode, 1); + n->v = annotation; + SLLQueuePushFront(visible_memory_annotations[vaddr-viz_range_bytes.min].first, visible_memory_annotations[vaddr-viz_range_bytes.min].last, n); } } } @@ -3138,6 +3162,45 @@ RD_VIEW_UI_FUNCTION_DEF(memory) } } + //- rjf: fill debuggee-specified annotations + if(eval_process != &ctrl_entity_nil) UI_TagF(".") UI_TagF("pop") + { + Vec4F32 symbol_color = ui_color_from_name(str8_lit("background")); + Vec4F32 color_gen_table[] = + { + mix_4f32(symbol_color, v4f32(0, 0, 0, 1), 0.00f), + mix_4f32(symbol_color, v4f32(0, 0, 0, 1), 0.05f), + mix_4f32(symbol_color, v4f32(0, 0, 0, 1), 0.10f), + mix_4f32(symbol_color, v4f32(0, 0, 0, 1), 0.15f), + }; + for(CTRL_Entity *child = eval_process->first; child != &ctrl_entity_nil; child = child->next) + { + if(child->kind != CTRL_EntityKind_AddressRangeAnnotation) + { + continue; + } + String8 name = child->string; + Rng1U64 vaddr_range = child->vaddr_range; + Rng1U64 vaddr_range_in_visible = intersect_1u64(vaddr_range, viz_range_bytes); + if(vaddr_range_in_visible.max > vaddr_range_in_visible.min) + { + Annotation *annotation = push_array(scratch.arena, Annotation, 1); + { + annotation->name_string = push_str8_copy(scratch.arena, name); + annotation->kind_string = str8_lit("Annotation"); + annotation->color = color_gen_table[(vaddr_range.min/7)%ArrayCount(color_gen_table)]; + annotation->vaddr_range = vaddr_range; + } + for(U64 vaddr = vaddr_range_in_visible.min; vaddr < vaddr_range_in_visible.max; vaddr += 1) + { + AnnotationNode *n = push_array(scratch.arena, AnnotationNode, 1); + n->v = annotation; + SLLQueuePushFront(visible_memory_annotations[vaddr-viz_range_bytes.min].first, visible_memory_annotations[vaddr-viz_range_bytes.min].last, n); + } + } + } + } + ctrl_scope_close(ctrl_scope); } @@ -3418,7 +3481,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) U8 byte_value = visible_memory[visible_byte_idx]; B32 byte_is_bad = !!(visible_memory_bad_flags[visible_byte_idx/64] & (1ull<<(visible_byte_idx%64))); B32 byte_is_changed = !!(visible_memory_change_flags[visible_byte_idx/64] & (1ull<<(visible_byte_idx%64))); - Annotation *annotation = visible_memory_annotations[visible_byte_idx].first; + AnnotationNode *annotation_node = visible_memory_annotations[visible_byte_idx].first; // rjf: unpack visual cell info UI_BoxFlags cell_flags = 0; @@ -3428,11 +3491,12 @@ RD_VIEW_UI_FUNCTION_DEF(memory) { cell_flags |= UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawDropShadow; } - if(annotation != 0) + if(annotation_node != 0) { cell_flags |= UI_BoxFlag_DrawBackground; - cell_bg_rgba = annotation->color; - cell_bg_rgba.w *= 0.08f; + Vec4F32 cell_bg_color_rgba = annotation_node->v->color; + Vec4F32 cell_bg_color_hsva = hsva_from_rgba(cell_bg_color_rgba); + cell_bg_rgba = mix_4f32(cell_bg_color_rgba, main_bg_color_rgba, clamp_1f32(r1f32(0, 1), 1.f - abs_f32(cell_bg_color_hsva.z - main_tx_color_hsva.z)*0.5f)); } if(selection.min == global_byte_idx) { @@ -3479,13 +3543,14 @@ RD_VIEW_UI_FUNCTION_DEF(memory) ui_box_equip_display_fstrs(cell_box, &byte_fstrs[byte_value]); } { - for(Annotation *a = annotation; a != 0; a = a->next) + for(AnnotationNode *a_n = annotation_node; a_n != 0; a_n = a_n->next) { + Annotation *a = a_n->v; if(global_byte_idx == a->vaddr_range.min) UI_Parent(row_overlay_box) { F32 size = cell_width_px/4.f + cell_width_px/8.f*ui_anim(ui_key_from_stringf(ui_active_seed_key(), "###annotation_hovered_%I64x_%I64x", a->vaddr_range.min, a->vaddr_range.max), (F32)!!(a->vaddr_range.min+1 <= mouse_hover_byte_num && mouse_hover_byte_num <= a->vaddr_range.max)); - ui_set_next_border_color(annotation->color); + ui_set_next_border_color(a->color); ui_set_next_fixed_x(big_glyph_advance*20.f + col_idx*cell_width_px + -size*0.5f); ui_set_next_fixed_y((row_idx-viz_range_rows.min)*row_height_px + -size*0.5f); ui_set_next_fixed_width(size); @@ -3500,7 +3565,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) { F32 size = cell_width_px/4.f + cell_width_px/8.f*ui_anim(ui_key_from_stringf(ui_active_seed_key(), "###annotation_hovered_%I64x_%I64x", a->vaddr_range.min, a->vaddr_range.max), (F32)!!(a->vaddr_range.min+1 <= mouse_hover_byte_num && mouse_hover_byte_num <= a->vaddr_range.max)); - ui_set_next_border_color(annotation->color); + ui_set_next_border_color(a->color); ui_set_next_fixed_x(big_glyph_advance*20.f + (col_idx+1)*cell_width_px + -size*0.5f); ui_set_next_fixed_y((row_idx-viz_range_rows.min)*row_height_px + row_height_px + -size*0.5f); ui_set_next_fixed_width(size); @@ -3513,12 +3578,13 @@ RD_VIEW_UI_FUNCTION_DEF(memory) } } } - if(annotation != 0 && mouse_hover_byte_num == global_byte_num) + if(annotation_node != 0 && mouse_hover_byte_num == global_byte_num) { UI_Tooltip UI_FontSize(ui_top_font_size()) UI_PrefHeight(ui_px(ui_top_font_size()*1.75f, 1.f)) { - for(Annotation *a = annotation; a != 0; a = a->next) + for(AnnotationNode *a_n = annotation_node; a_n != 0; a_n = a_n->next) { + Annotation *a = a_n->v; UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(10, 1)) { RD_Font(RD_FontSlot_Code) rd_code_label(1.f, 0, ui_color_from_name(str8_lit("code_default")), a->name_string); @@ -3529,7 +3595,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) rd_code_label(1.f, 1, ui_color_from_name(str8_lit("code_type")), a->type_string); } UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label(str8_from_memory_size(scratch.arena, dim_1u64(a->vaddr_range))); - if(a->next != 0) + if(a_n->next != 0) { ui_spacer(ui_em(1.5f, 1.f)); }