diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index a2a231bf..5ae8b19f 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -131,6 +131,16 @@ ctrl_dmn_trap_flags_from_user_breakpoint_flags(CTRL_UserBreakpointFlags flags) return result; } +internal CTRL_UserBreakpointFlags +ctrl_user_breakpoint_flags_from_dmn_trap_flags(DMN_TrapFlags flags) +{ + CTRL_UserBreakpointFlags result = 0; + if(flags & DMN_TrapFlag_BreakOnWrite) { result |= CTRL_UserBreakpointFlag_BreakOnWrite; } + if(flags & DMN_TrapFlag_BreakOnRead) { result |= CTRL_UserBreakpointFlag_BreakOnRead; } + if(flags & DMN_TrapFlag_BreakOnExecute) { result |= CTRL_UserBreakpointFlag_BreakOnExecute; } + return result; +} + //////////////////////////////// //~ rjf: Machine/Handle Pair Type Functions @@ -588,8 +598,9 @@ ctrl_serialized_string_from_event(Arena *arena, CTRL_Event *event, U64 max) str8_serial_push_struct(scratch.arena, &srl, &event->stack_base); str8_serial_push_struct(scratch.arena, &srl, &event->tls_root); str8_serial_push_struct(scratch.arena, &srl, &event->timestamp); - str8_serial_push_struct(scratch.arena, &srl, &event->rgba); str8_serial_push_struct(scratch.arena, &srl, &event->exception_code); + str8_serial_push_struct(scratch.arena, &srl, &event->rgba); + str8_serial_push_struct(scratch.arena, &srl, &event->bp_flags); String8 string = event->string; string.size = Min(string.size, max-srl.total_size); str8_serial_push_struct(scratch.arena, &srl, &string.size); @@ -620,8 +631,9 @@ ctrl_event_from_serialized_string(Arena *arena, String8 string) read_off += str8_deserial_read_struct(string, read_off, &event.stack_base); read_off += str8_deserial_read_struct(string, read_off, &event.tls_root); read_off += str8_deserial_read_struct(string, read_off, &event.timestamp); - read_off += str8_deserial_read_struct(string, read_off, &event.rgba); read_off += str8_deserial_read_struct(string, read_off, &event.exception_code); + read_off += str8_deserial_read_struct(string, read_off, &event.rgba); + read_off += str8_deserial_read_struct(string, read_off, &event.bp_flags); read_off += str8_deserial_read_struct(string, read_off, &event.string.size); event.string.str = push_array_no_zero(arena, U8, event.string.size); read_off += str8_deserial_read(string, read_off, event.string.str, event.string.size, 1); @@ -4353,6 +4365,20 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, out_evt->parent = ctrl_handle_make(CTRL_MachineID_Local, event->process); out_evt->rgba = event->code; }break; + case DMN_EventKind_SetBreakpoint: + { + CTRL_Event *out_evt = ctrl_event_list_push(scratch.arena, &evts); + out_evt->kind = CTRL_EventKind_SetBreakpoint; + out_evt->vaddr_rng = r1u64(event->address, event->address+event->size); + out_evt->bp_flags = ctrl_user_breakpoint_flags_from_dmn_trap_flags(event->flags); + }break; + case DMN_EventKind_UnsetBreakpoint: + { + CTRL_Event *out_evt = ctrl_event_list_push(scratch.arena, &evts); + out_evt->kind = CTRL_EventKind_UnsetBreakpoint; + out_evt->vaddr_rng = r1u64(event->address, event->address+event->size); + out_evt->bp_flags = ctrl_user_breakpoint_flags_from_dmn_trap_flags(event->flags); + }break; } ctrl_c2u_push_events(&evts); diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index e8481f95..3ded38c1 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -406,10 +406,12 @@ typedef enum CTRL_EventKind //- rjf: debug info changes CTRL_EventKind_ModuleDebugInfoPathChange, - //- rjf: debug strings / decorations + //- rjf: debug strings / decorations / markup CTRL_EventKind_DebugString, CTRL_EventKind_ThreadName, CTRL_EventKind_ThreadColor, + CTRL_EventKind_SetBreakpoint, + CTRL_EventKind_UnsetBreakpoint, //- rjf: memory CTRL_EventKind_MemReserve, @@ -465,6 +467,7 @@ struct CTRL_Event U64 timestamp; U32 exception_code; U32 rgba; + CTRL_UserBreakpointFlags bp_flags; String8 string; }; @@ -755,6 +758,7 @@ internal String8 ctrl_string_from_event_kind(CTRL_EventKind kind); internal String8 ctrl_string_from_msg_kind(CTRL_MsgKind kind); internal CTRL_EntityKind ctrl_entity_kind_from_string(String8 string); internal DMN_TrapFlags ctrl_dmn_trap_flags_from_user_breakpoint_flags(CTRL_UserBreakpointFlags flags); +internal CTRL_UserBreakpointFlags ctrl_user_breakpoint_flags_from_dmn_trap_flags(DMN_TrapFlags flags); //////////////////////////////// //~ rjf: Handle Type Functions diff --git a/src/demon/demon_core.h b/src/demon/demon_core.h index 522988a1..94f8d8c3 100644 --- a/src/demon/demon_core.h +++ b/src/demon/demon_core.h @@ -73,7 +73,7 @@ struct DMN_Event U64 size; String8 string; U32 code; // code gives pid & tid on CreateProcess and CreateThread (respectfully) - U32 flags; + U32 flags; // DMN_TrapFlags, if `DMN_EventKind_SetBreakpoint` S32 signo; S32 sigcode; U64 instruction_pointer; diff --git a/src/demon/demon_core.mdesk b/src/demon/demon_core.mdesk index ea3139f6..3c9a367e 100644 --- a/src/demon/demon_core.mdesk +++ b/src/demon/demon_core.mdesk @@ -22,6 +22,8 @@ DMN_EventKindTable: {DebugString} {SetThreadName} {SetThreadColor} + {SetBreakpoint} + {UnsetBreakpoint} } @table(name) diff --git a/src/demon/generated/demon.meta.c b/src/demon/generated/demon.meta.c index 3aa15e72..47406944 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[18] = +String8 dmn_event_kind_string_table[20] = { str8_lit_comp("Null"), str8_lit_comp("Error"), @@ -24,6 +24,8 @@ str8_lit_comp("Memory"), str8_lit_comp("DebugString"), str8_lit_comp("SetThreadName"), str8_lit_comp("SetThreadColor"), +str8_lit_comp("SetBreakpoint"), +str8_lit_comp("UnsetBreakpoint"), }; String8 dmn_exception_kind_string_table[5] = diff --git a/src/demon/generated/demon.meta.h b/src/demon/generated/demon.meta.h index f5fdae4c..4a8b5b80 100644 --- a/src/demon/generated/demon.meta.h +++ b/src/demon/generated/demon.meta.h @@ -26,6 +26,8 @@ DMN_EventKind_Memory, DMN_EventKind_DebugString, DMN_EventKind_SetThreadName, DMN_EventKind_SetThreadColor, +DMN_EventKind_SetBreakpoint, +DMN_EventKind_UnsetBreakpoint, DMN_EventKind_COUNT, } DMN_EventKind; @@ -59,7 +61,7 @@ DMN_ExceptionKind_COUNT, } DMN_ExceptionKind; C_LINKAGE_BEGIN -extern String8 dmn_event_kind_string_table[18]; +extern String8 dmn_event_kind_string_table[20]; 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 bca362dd..6480d200 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -2527,6 +2527,23 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) e->code = exception->ExceptionInformation[1]; }break; + //- rjf: fill set-data-breakpoint info + case DMN_W32_EXCEPTION_RADDBG_SET_BREAKPOINT: + { + U64 vaddr = exception->ExceptionInformation[0]; + U64 size = exception->ExceptionInformation[1]; + U64 read = exception->ExceptionInformation[2]; + U64 write = exception->ExceptionInformation[3]; + U64 exec = exception->ExceptionInformation[4]; + U64 set = exception->ExceptionInformation[5]; + e->kind = set ? DMN_EventKind_SetBreakpoint : DMN_EventKind_UnsetBreakpoint; + e->address = vaddr; + e->size = size; + if(read) { e->flags |= DMN_TrapFlag_BreakOnRead; } + if(write) { e->flags |= DMN_TrapFlag_BreakOnWrite; } + if(exec) { e->flags |= DMN_TrapFlag_BreakOnExecute; } + }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 24f527f2..05483e26 100644 --- a/src/demon/win32/demon_core_win32.h +++ b/src/demon/win32/demon_core_win32.h @@ -15,48 +15,49 @@ //////////////////////////////// //~ rjf: Win32 Exception Codes -#define DMN_W32_EXCEPTION_BREAKPOINT 0x80000003u -#define DMN_W32_EXCEPTION_SINGLE_STEP 0x80000004u -#define DMN_W32_EXCEPTION_LONG_JUMP 0x80000026u -#define DMN_W32_EXCEPTION_ACCESS_VIOLATION 0xC0000005u -#define DMN_W32_EXCEPTION_ARRAY_BOUNDS_EXCEEDED 0xC000008Cu -#define DMN_W32_EXCEPTION_DATA_TYPE_MISALIGNMENT 0x80000002u -#define DMN_W32_EXCEPTION_GUARD_PAGE_VIOLATION 0x80000001u -#define DMN_W32_EXCEPTION_FLT_DENORMAL_OPERAND 0xC000008Du -#define DMN_W32_EXCEPTION_FLT_DEVIDE_BY_ZERO 0xC000008Eu -#define DMN_W32_EXCEPTION_FLT_INEXACT_RESULT 0xC000008Fu -#define DMN_W32_EXCEPTION_FLT_INVALID_OPERATION 0xC0000090u -#define DMN_W32_EXCEPTION_FLT_OVERFLOW 0xC0000091u -#define DMN_W32_EXCEPTION_FLT_STACK_CHECK 0xC0000092u -#define DMN_W32_EXCEPTION_FLT_UNDERFLOW 0xC0000093u -#define DMN_W32_EXCEPTION_INT_DIVIDE_BY_ZERO 0xC0000094u -#define DMN_W32_EXCEPTION_INT_OVERFLOW 0xC0000095u -#define DMN_W32_EXCEPTION_PRIVILEGED_INSTRUCTION 0xC0000096u -#define DMN_W32_EXCEPTION_ILLEGAL_INSTRUCTION 0xC000001Du -#define DMN_W32_EXCEPTION_IN_PAGE_ERROR 0xC0000006u -#define DMN_W32_EXCEPTION_INVALID_DISPOSITION 0xC0000026u -#define DMN_W32_EXCEPTION_NONCONTINUABLE 0xC0000025u -#define DMN_W32_EXCEPTION_STACK_OVERFLOW 0xC00000FDu -#define DMN_W32_EXCEPTION_INVALID_HANDLE 0xC0000008u -#define DMN_W32_EXCEPTION_UNWIND_CONSOLIDATE 0x80000029u -#define DMN_W32_EXCEPTION_DLL_NOT_FOUND 0xC0000135u -#define DMN_W32_EXCEPTION_ORDINAL_NOT_FOUND 0xC0000138u -#define DMN_W32_EXCEPTION_ENTRY_POINT_NOT_FOUND 0xC0000139u -#define DMN_W32_EXCEPTION_DLL_INIT_FAILED 0xC0000142u -#define DMN_W32_EXCEPTION_CONTROL_C_EXIT 0xC000013Au -#define DMN_W32_EXCEPTION_FLT_MULTIPLE_FAULTS 0xC00002B4u -#define DMN_W32_EXCEPTION_FLT_MULTIPLE_TRAPS 0xC00002B5u -#define DMN_W32_EXCEPTION_NAT_CONSUMPTION 0xC00002C9u -#define DMN_W32_EXCEPTION_HEAP_CORRUPTION 0xC0000374u -#define DMN_W32_EXCEPTION_STACK_BUFFER_OVERRUN 0xC0000409u -#define DMN_W32_EXCEPTION_INVALID_CRUNTIME_PARAM 0xC0000417u -#define DMN_W32_EXCEPTION_ASSERT_FAILURE 0xC0000420u -#define DMN_W32_EXCEPTION_NO_MEMORY 0xC0000017u -#define DMN_W32_EXCEPTION_THROW 0xE06D7363u -#define DMN_W32_EXCEPTION_SET_THREAD_NAME 0x406d1388u -#define DMN_w32_EXCEPTION_CLRDBG_NOTIFICATION 0x04242420u -#define DMN_w32_EXCEPTION_CLR 0xE0434352u -#define DMN_W32_EXCEPTION_RADDBG_SET_THREAD_COLOR 0x00524144u +#define DMN_W32_EXCEPTION_BREAKPOINT 0x80000003u +#define DMN_W32_EXCEPTION_SINGLE_STEP 0x80000004u +#define DMN_W32_EXCEPTION_LONG_JUMP 0x80000026u +#define DMN_W32_EXCEPTION_ACCESS_VIOLATION 0xC0000005u +#define DMN_W32_EXCEPTION_ARRAY_BOUNDS_EXCEEDED 0xC000008Cu +#define DMN_W32_EXCEPTION_DATA_TYPE_MISALIGNMENT 0x80000002u +#define DMN_W32_EXCEPTION_GUARD_PAGE_VIOLATION 0x80000001u +#define DMN_W32_EXCEPTION_FLT_DENORMAL_OPERAND 0xC000008Du +#define DMN_W32_EXCEPTION_FLT_DEVIDE_BY_ZERO 0xC000008Eu +#define DMN_W32_EXCEPTION_FLT_INEXACT_RESULT 0xC000008Fu +#define DMN_W32_EXCEPTION_FLT_INVALID_OPERATION 0xC0000090u +#define DMN_W32_EXCEPTION_FLT_OVERFLOW 0xC0000091u +#define DMN_W32_EXCEPTION_FLT_STACK_CHECK 0xC0000092u +#define DMN_W32_EXCEPTION_FLT_UNDERFLOW 0xC0000093u +#define DMN_W32_EXCEPTION_INT_DIVIDE_BY_ZERO 0xC0000094u +#define DMN_W32_EXCEPTION_INT_OVERFLOW 0xC0000095u +#define DMN_W32_EXCEPTION_PRIVILEGED_INSTRUCTION 0xC0000096u +#define DMN_W32_EXCEPTION_ILLEGAL_INSTRUCTION 0xC000001Du +#define DMN_W32_EXCEPTION_IN_PAGE_ERROR 0xC0000006u +#define DMN_W32_EXCEPTION_INVALID_DISPOSITION 0xC0000026u +#define DMN_W32_EXCEPTION_NONCONTINUABLE 0xC0000025u +#define DMN_W32_EXCEPTION_STACK_OVERFLOW 0xC00000FDu +#define DMN_W32_EXCEPTION_INVALID_HANDLE 0xC0000008u +#define DMN_W32_EXCEPTION_UNWIND_CONSOLIDATE 0x80000029u +#define DMN_W32_EXCEPTION_DLL_NOT_FOUND 0xC0000135u +#define DMN_W32_EXCEPTION_ORDINAL_NOT_FOUND 0xC0000138u +#define DMN_W32_EXCEPTION_ENTRY_POINT_NOT_FOUND 0xC0000139u +#define DMN_W32_EXCEPTION_DLL_INIT_FAILED 0xC0000142u +#define DMN_W32_EXCEPTION_CONTROL_C_EXIT 0xC000013Au +#define DMN_W32_EXCEPTION_FLT_MULTIPLE_FAULTS 0xC00002B4u +#define DMN_W32_EXCEPTION_FLT_MULTIPLE_TRAPS 0xC00002B5u +#define DMN_W32_EXCEPTION_NAT_CONSUMPTION 0xC00002C9u +#define DMN_W32_EXCEPTION_HEAP_CORRUPTION 0xC0000374u +#define DMN_W32_EXCEPTION_STACK_BUFFER_OVERRUN 0xC0000409u +#define DMN_W32_EXCEPTION_INVALID_CRUNTIME_PARAM 0xC0000417u +#define DMN_W32_EXCEPTION_ASSERT_FAILURE 0xC0000420u +#define DMN_W32_EXCEPTION_NO_MEMORY 0xC0000017u +#define DMN_W32_EXCEPTION_THROW 0xE06D7363u +#define DMN_W32_EXCEPTION_SET_THREAD_NAME 0x406d1388u +#define DMN_w32_EXCEPTION_CLRDBG_NOTIFICATION 0x04242420u +#define DMN_w32_EXCEPTION_CLR 0xE0434352u +#define DMN_W32_EXCEPTION_RADDBG_SET_THREAD_COLOR 0x00524144u +#define DMN_W32_EXCEPTION_RADDBG_SET_BREAKPOINT 0x00524145u //////////////////////////////// //~ rjf: Win32 Register Codes diff --git a/src/lib_raddbg_markup/raddbg_markup.h b/src/lib_raddbg_markup/raddbg_markup.h index e153ab4d..09de9b30 100644 --- a/src/lib_raddbg_markup/raddbg_markup.h +++ b/src/lib_raddbg_markup/raddbg_markup.h @@ -16,29 +16,33 @@ //~ Usage Macros #if defined(RADDBG_MARKUP_STUBS) -# define raddbg_is_attached(...) (0) -# define raddbg_thread_name(fmt, ...) ((void)0) -# define raddbg_thread_color_hex(hexcode) ((void)0) -# define raddbg_thread_color_rgba(r, g, b, a) ((void)0) -# define raddbg_break(...) ((void)0) -# define raddbg_break_if(expr, ...) ((void)expr) -# define raddbg_watch(fmt, ...) ((void)0) +# define raddbg_is_attached(...) (0) +# define raddbg_thread_name(fmt, ...) ((void)0) +# define raddbg_thread_color_hex(hexcode) ((void)0) +# define raddbg_thread_color_rgba(r, g, b, a) ((void)0) +# define raddbg_break(...) ((void)0) +# define raddbg_break_if(expr, ...) ((void)expr) +# define raddbg_watch(fmt, ...) ((void)0) # define raddbg_pin(expr, ...) -# define raddbg_log(fmt, ...) ((void)0) -# define raddbg_entry_point(...) struct raddbg_gen_data_id(){int __unused__} -# define raddbg_auto_view_rule(type, ...) struct raddbg_gen_data_id(){int __unused__} +# define raddbg_log(fmt, ...) ((void)0) +# define raddbg_entry_point(...) struct raddbg_gen_data_id(){int __unused__} +# define raddbg_auto_view_rule(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) #else -# define raddbg_is_attached(...) raddbg_is_attached__impl() -# define raddbg_thread_name(fmt, ...) raddbg_thread_name__impl((fmt), __VA_ARGS__) -# define raddbg_thread_color_hex(hexcode) raddbg_thread_color__impl((hexcode)) -# define raddbg_thread_color_rgba(r, g, b, a) raddbg_thread_color__impl(((unsigned int)((r)*255) << 24) | ((unsigned int)((g)*255) << 16) | ((unsigned int)((b)*255) << 8) | ((unsigned int)(a)*255)) -# define raddbg_break(...) raddbg_break__impl() -# define raddbg_break_if(expr, ...) ((expr) ? raddbg_break__impl() : (void)0) -# define raddbg_watch(fmt, ...) raddbg_watch__impl((fmt), __VA_ARGS__) -# define raddbg_pin(expr, ...) /* NOTE(rjf): inspected by debugger ui - does not change program execution */ -# define raddbg_log(fmt, ...) raddbg_log__impl((fmt), __VA_ARGS__) -# define raddbg_entry_point(...) raddbg_exe_data static char raddbg_gen_data_id()[] = ("entry_point: \"" #__VA_ARGS__ "\"") -# define raddbg_auto_view_rule(type, ...) raddbg_exe_data static char raddbg_gen_data_id()[] = ("auto_view_rule: {type: \"" #type "\", view_rule: \"" #__VA_ARGS__ "\"}") +# define raddbg_is_attached(...) raddbg_is_attached__impl() +# define raddbg_thread_name(fmt, ...) raddbg_thread_name__impl((fmt), __VA_ARGS__) +# define raddbg_thread_color_hex(hexcode) raddbg_thread_color__impl((hexcode)) +# define raddbg_thread_color_rgba(r, g, b, a) raddbg_thread_color__impl(((unsigned int)((r)*255) << 24) | ((unsigned int)((g)*255) << 16) | ((unsigned int)((b)*255) << 8) | ((unsigned int)(a)*255)) +# define raddbg_break(...) raddbg_break__impl() +# define raddbg_break_if(expr, ...) ((expr) ? raddbg_break__impl() : (void)0) +# define raddbg_watch(fmt, ...) raddbg_watch__impl((fmt), __VA_ARGS__) +# define raddbg_pin(expr, ...) /* NOTE(rjf): inspected by debugger ui - does not change program execution */ +# define raddbg_log(fmt, ...) raddbg_log__impl((fmt), __VA_ARGS__) +# define raddbg_entry_point(...) raddbg_exe_data static char raddbg_gen_data_id()[] = ("entry_point: \"" #__VA_ARGS__ "\"") +# define raddbg_auto_view_rule(type, ...) raddbg_exe_data static char raddbg_gen_data_id()[] = ("auto_view_rule: {type: \"" #type "\", view_rule: \"" #__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)) #endif //////////////////////////////// @@ -339,6 +343,43 @@ raddbg_log__impl(char *fmt, ...) OutputDebugStringA(buffer); } +static inline void +raddbg_add_or_remove_breakpoint__impl(void *ptr, int set, int size, int r, int w, int x) +{ + if(raddbg_is_attached()) + { +#pragma pack(push, 8) + typedef struct RADDBG_AddBreakpointInfo RADDBG_AddBreakpointInfo; + struct RADDBG_AddBreakpointInfo + { + unsigned __int64 vaddr; + unsigned __int64 size; + unsigned __int64 r; + unsigned __int64 w; + unsigned __int64 x; + unsigned __int64 add; + }; +#pragma pack(pop) + RADDBG_AddBreakpointInfo info; + info.vaddr = (unsigned __int64)ptr; + info.size = size; + info.r = r; + info.w = w; + info.x = x; + info.add = set; +#pragma warning(push) +#pragma warning(disable: 6320 6322) + __try + { + RaiseException(0x00524145u, 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 430d352d..21a07187 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -1941,7 +1941,24 @@ fancy_viz_eval_tests(void) } //////////////////////////////// -// NOTE(allen): Function Overload Resolution +//~ rjf: Markup Tests + +static void +markup_tests(void) +{ + int x = 0; + raddbg_add_breakpoint(&x, sizeof(x), 0, 1, 0); + for(int i = 0; i < 10000; i += 1) + { + if(i == 5000) + { + x += 1; + } + } +} + +//////////////////////////////// +//~ NOTE(allen): Function Overload Resolution static int overloaded_function(float y){ @@ -2747,6 +2764,8 @@ mule_main(int argc, char** argv) fancy_viz_eval_tests(); + markup_tests(); + // NOTE(allen): Stepping Tests control_flow_stepping_tests();