regression fixes, better integration, and tightening up the new unwinder

This commit is contained in:
Ryan Fleury
2024-05-17 14:15:11 -07:00
parent 578a56d231
commit 301cf6b7ac
7 changed files with 155 additions and 145 deletions
+9 -7
View File
@@ -54,12 +54,14 @@ set clang_out= -o
:: --- Per-Build Settings ----------------------------------------------------- :: --- Per-Build Settings -----------------------------------------------------
set link_dll=-DLL set link_dll=-DLL
if "%msvc%"=="1" set only_compile=/c if "%msvc%"=="1" set only_compile=/c
if "%clang%"=="1" set only_compile=-c if "%clang%"=="1" set only_compile=-c
if "%msvc%"=="1" set EHsc=/EHsc if "%msvc%"=="1" set EHsc=/EHsc
if "%clang%"=="1" set EHsc= if "%clang%"=="1" set EHsc=
if "%msvc%"=="1" set rc=rc.exe if "%msvc%"=="1" set no_aslr=/DYNAMICBASE:NO
if "%clang%"=="1" set rc=llvm-rc.exe if "%clang%"=="1" set no_aslr=/DYNAMICBASE:NO
if "%msvc%"=="1" set rc=rc.exe
if "%clang%"=="1" set rc=llvm-rc.exe
:: --- Choose Compile/Link Lines ---------------------------------------------- :: --- Choose Compile/Link Lines ----------------------------------------------
if "%msvc%"=="1" set compile_debug=%cl_debug% if "%msvc%"=="1" set compile_debug=%cl_debug%
@@ -104,7 +106,7 @@ if "%raddbgi_breakpad_from_pdb%"=="1" %compile% ..\src\raddbgi_brea
if "%ryan_scratch%"=="1" %compile% ..\src\scratch\ryan_scratch.c %compile_link% %out%ryan_scratch.exe || exit /b 1 if "%ryan_scratch%"=="1" %compile% ..\src\scratch\ryan_scratch.c %compile_link% %out%ryan_scratch.exe || exit /b 1
if "%cpp_tests%"=="1" %compile% ..\src\scratch\i_hate_c_plus_plus.cpp %compile_link% %out%cpp_tests.exe || exit /b 1 if "%cpp_tests%"=="1" %compile% ..\src\scratch\i_hate_c_plus_plus.cpp %compile_link% %out%cpp_tests.exe || exit /b 1
if "%look_at_raddbg%"=="1" %compile% ..\src\scratch\look_at_raddbg.c %compile_link% %out%look_at_raddbg.exe || exit /b 1 if "%look_at_raddbg%"=="1" %compile% ..\src\scratch\look_at_raddbg.c %compile_link% %out%look_at_raddbg.exe || exit /b 1
if "%mule_main%"=="1" del vc*.pdb mule*.pdb && %compile_release% %only_compile% ..\src\mule\mule_inline.cpp && %compile_release% %only_compile% ..\src\mule\mule_o2.cpp && %compile_debug% %EHsc% ..\src\mule\mule_main.cpp ..\src\mule\mule_c.c mule_inline.obj mule_o2.obj %compile_link% %out%mule_main.exe || exit /b 1 if "%mule_main%"=="1" del vc*.pdb mule*.pdb && %compile_release% %only_compile% ..\src\mule\mule_inline.cpp && %compile_release% %only_compile% ..\src\mule\mule_o2.cpp && %compile_debug% %EHsc% ..\src\mule\mule_main.cpp ..\src\mule\mule_c.c mule_inline.obj mule_o2.obj %compile_link% %no_aslr% %out%mule_main.exe || exit /b 1
if "%mule_module%"=="1" %compile% ..\src\mule\mule_module.cpp %compile_link% %link_dll% %out%mule_module.dll || exit /b 1 if "%mule_module%"=="1" %compile% ..\src\mule\mule_module.cpp %compile_link% %link_dll% %out%mule_module.dll || exit /b 1
if "%mule_hotload%"=="1" %compile% ..\src\mule\mule_hotload_main.c %compile_link% %out%mule_hotload.exe & %compile% ..\src\mule\mule_hotload_module_main.c %compile_link% %link_dll% %out%mule_hotload_module.dll || exit /b 1 if "%mule_hotload%"=="1" %compile% ..\src\mule\mule_hotload_main.c %compile_link% %out%mule_hotload.exe & %compile% ..\src\mule\mule_hotload_module_main.c %compile_link% %link_dll% %out%mule_hotload_module.dll || exit /b 1
popd popd
+79 -59
View File
@@ -1036,7 +1036,6 @@ ctrl_stored_hash_from_process_vaddr_range(CTRL_MachineID machine_id, DMN_Handle
{ {
U64 range_slot_idx = range_hash%n->range_hash_slots_count; U64 range_slot_idx = range_hash%n->range_hash_slots_count;
CTRL_ProcessMemoryRangeHashSlot *range_slot = &n->range_hash_slots[range_slot_idx]; CTRL_ProcessMemoryRangeHashSlot *range_slot = &n->range_hash_slots[range_slot_idx];
B32 range_node_exists = 0;
for(CTRL_ProcessMemoryRangeHashNode *range_n = range_slot->first; range_n != 0; range_n = range_n->next) for(CTRL_ProcessMemoryRangeHashNode *range_n = range_slot->first; range_n != 0; range_n = range_n->next)
{ {
if(MemoryMatchStruct(&range_n->vaddr_range, &range) && range_n->zero_terminated == zero_terminated) if(MemoryMatchStruct(&range_n->vaddr_range, &range) && range_n->zero_terminated == zero_terminated)
@@ -1508,6 +1507,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
if(is_valid) if(is_valid)
{ {
if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, module->vaddr_range.min, &is_stale, &dos_header, endt_us) || if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, module->vaddr_range.min, &is_stale, &dos_header, endt_us) ||
is_stale ||
dos_header.magic != PE_DOS_MAGIC) dos_header.magic != PE_DOS_MAGIC)
{ {
is_valid = 0; is_valid = 0;
@@ -1520,6 +1520,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
if(is_valid) if(is_valid)
{ {
if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, module->vaddr_range.min + dos_header.coff_file_offset, &is_stale, &pe_magic, endt_us) || if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, module->vaddr_range.min + dos_header.coff_file_offset, &is_stale, &pe_magic, endt_us) ||
is_stale ||
pe_magic != PE_MAGIC) pe_magic != PE_MAGIC)
{ {
is_valid = 0; is_valid = 0;
@@ -1532,7 +1533,8 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
COFF_Header coff_header = {0}; COFF_Header coff_header = {0};
if(is_valid) if(is_valid)
{ {
if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, module->vaddr_range.min + coff_header_off, &is_stale, &coff_header, endt_us)) if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, module->vaddr_range.min + coff_header_off, &is_stale, &coff_header, endt_us) ||
is_stale)
{ {
is_valid = 0; is_valid = 0;
is_good = 0; is_good = 0;
@@ -1680,6 +1682,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
if(read_vaddr + sizeof(inst) <= read_vaddr_opl) if(read_vaddr + sizeof(inst) <= read_vaddr_opl)
{ {
inst_good = ctrl_read_cached_process_memory(machine_id, process->handle, r1u64(read_vaddr, read_vaddr+sizeof(inst)), &is_stale, inst, endt_us); inst_good = ctrl_read_cached_process_memory(machine_id, process->handle, r1u64(read_vaddr, read_vaddr+sizeof(inst)), &is_stale, inst, endt_us);
inst_good = inst_good && !is_stale;
} }
if(!inst_good) if(!inst_good)
{ {
@@ -1761,7 +1764,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
{ {
inst_byte_good = ctrl_read_cached_process_memory_struct(machine_id, process->handle, read_vaddr, &is_stale, &inst_byte, endt_us); inst_byte_good = ctrl_read_cached_process_memory_struct(machine_id, process->handle, read_vaddr, &is_stale, &inst_byte, endt_us);
} }
if(!inst_byte_good) if(!inst_byte_good || is_stale)
{ {
keep_parsing = 0; keep_parsing = 0;
} }
@@ -1777,7 +1780,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
{ {
check_inst_byte_good = ctrl_read_cached_process_memory_struct(machine_id, process->handle, read_vaddr, &is_stale, &check_inst_byte, endt_us); check_inst_byte_good = ctrl_read_cached_process_memory_struct(machine_id, process->handle, read_vaddr, &is_stale, &check_inst_byte, endt_us);
} }
if(!check_inst_byte_good) if(!check_inst_byte_good || is_stale)
{ {
keep_parsing = 0; keep_parsing = 0;
} }
@@ -1813,7 +1816,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
{ {
imm_good = ctrl_read_cached_process_memory_struct(machine_id, process->handle, read_vaddr, &is_stale, &imm, endt_us); imm_good = ctrl_read_cached_process_memory_struct(machine_id, process->handle, read_vaddr, &is_stale, &imm, endt_us);
} }
if(!imm_good) if(!imm_good || is_stale)
{ {
keep_parsing = 0; keep_parsing = 0;
} }
@@ -1870,6 +1873,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
//- rjf: read next instruction byte //- rjf: read next instruction byte
U8 inst_byte = 0; U8 inst_byte = 0;
is_good = is_good && ctrl_read_cached_process_memory_struct(machine_id, process->handle, read_vaddr, &is_stale, &inst_byte, endt_us); is_good = is_good && ctrl_read_cached_process_memory_struct(machine_id, process->handle, read_vaddr, &is_stale, &inst_byte, endt_us);
is_good = is_good && !is_stale;
read_vaddr += 1; read_vaddr += 1;
//- rjf: extract rex from instruction byte //- rjf: extract rex from instruction byte
@@ -1878,6 +1882,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
{ {
rex = inst_byte & 0xF; // rex prefix rex = inst_byte & 0xF; // rex prefix
is_good = is_good && ctrl_read_cached_process_memory_struct(machine_id, process->handle, read_vaddr, &is_stale, &inst_byte, endt_us); is_good = is_good && ctrl_read_cached_process_memory_struct(machine_id, process->handle, read_vaddr, &is_stale, &inst_byte, endt_us);
is_good = is_good && !is_stale;
read_vaddr += 1; read_vaddr += 1;
} }
@@ -1897,7 +1902,8 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
// rjf: read value at rsp // rjf: read value at rsp
U64 sp = regs->rsp.u64; U64 sp = regs->rsp.u64;
U64 value = 0; U64 value = 0;
if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, sp, &is_stale, &sp, endt_us)) if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, sp, &is_stale, &sp, endt_us) ||
is_stale)
{ {
is_good = 0; is_good = 0;
break; break;
@@ -1921,7 +1927,8 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
// rjf: read the 4-byte immediate // rjf: read the 4-byte immediate
S32 imm = 0; S32 imm = 0;
if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, read_vaddr, &is_stale, &imm, endt_us)) if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, read_vaddr, &is_stale, &imm, endt_us) ||
is_stale)
{ {
is_good = 0; is_good = 0;
break; break;
@@ -1943,7 +1950,8 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
// rjf: read the 4-byte immediate // rjf: read the 4-byte immediate
S8 imm = 0; S8 imm = 0;
if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, read_vaddr, &is_stale, &imm, endt_us)) if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, read_vaddr, &is_stale, &imm, endt_us) ||
is_stale)
{ {
is_good = 0; is_good = 0;
break; break;
@@ -1962,7 +1970,8 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
{ {
// rjf: read source register // rjf: read source register
U8 modrm = 0; U8 modrm = 0;
if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, read_vaddr, &is_stale, &modrm, endt_us)) if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, read_vaddr, &is_stale, &modrm, endt_us) ||
is_stale)
{ {
is_good = 0; is_good = 0;
break; break;
@@ -1979,7 +1988,8 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
if((modrm >> 6) == 1) if((modrm >> 6) == 1)
{ {
S8 imm8 = 0; S8 imm8 = 0;
if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, read_vaddr, &is_stale, &imm8, endt_us)) if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, read_vaddr, &is_stale, &imm8, endt_us) ||
is_stale)
{ {
is_good = 0; is_good = 0;
break; break;
@@ -1991,7 +2001,8 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
// rjf: read 4-byte immediate // rjf: read 4-byte immediate
else else
{ {
if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, read_vaddr, &is_stale, &imm, endt_us)) if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, read_vaddr, &is_stale, &imm, endt_us) ||
is_stale)
{ {
is_good = 0; is_good = 0;
break; break;
@@ -2013,7 +2024,8 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
// rjf: read new ip // rjf: read new ip
U64 sp = regs->rsp.u64; U64 sp = regs->rsp.u64;
U64 new_ip = 0; U64 new_ip = 0;
if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, sp, &is_stale, &new_ip, endt_us)) if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, sp, &is_stale, &new_ip, endt_us) ||
is_stale)
{ {
is_good = 0; is_good = 0;
break; break;
@@ -2021,7 +2033,8 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
// rjf: read 2-byte immediate & advance stack pointer // rjf: read 2-byte immediate & advance stack pointer
U16 imm = 0; U16 imm = 0;
if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, read_vaddr, &is_stale, &imm, endt_us)) if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, read_vaddr, &is_stale, &imm, endt_us) ||
is_stale)
{ {
is_good = 0; is_good = 0;
break; break;
@@ -2043,7 +2056,8 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
// rjf: read new ip // rjf: read new ip
U64 sp = regs->rsp.u64; U64 sp = regs->rsp.u64;
U64 new_ip = 0; U64 new_ip = 0;
if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, sp, &is_stale, &new_ip, endt_us)) if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, sp, &is_stale, &new_ip, endt_us) ||
is_stale)
{ {
is_good = 0; is_good = 0;
break; break;
@@ -2089,7 +2103,8 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
{ {
U64 unwind_info_off = first_pdata->voff_unwind_info; U64 unwind_info_off = first_pdata->voff_unwind_info;
PE_UnwindInfo unwind_info = {0}; PE_UnwindInfo unwind_info = {0};
if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, module->vaddr_range.min+unwind_info_off, &is_stale, &unwind_info, endt_us)) if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, module->vaddr_range.min+unwind_info_off, &is_stale, &unwind_info, endt_us) ||
is_stale)
{ {
is_good = 0; is_good = 0;
} }
@@ -2113,6 +2128,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
U64 unwind_info_off = pdata->voff_unwind_info; U64 unwind_info_off = pdata->voff_unwind_info;
PE_UnwindInfo unwind_info = {0}; PE_UnwindInfo unwind_info = {0};
good_unwind_info = good_unwind_info && ctrl_read_cached_process_memory_struct(machine_id, process->handle, module->vaddr_range.min+unwind_info_off, &is_stale, &unwind_info, endt_us); good_unwind_info = good_unwind_info && ctrl_read_cached_process_memory_struct(machine_id, process->handle, module->vaddr_range.min+unwind_info_off, &is_stale, &unwind_info, endt_us);
good_unwind_info = good_unwind_info && !is_stale;
PE_UnwindCode *unwind_codes = push_array(scratch.arena, PE_UnwindCode, unwind_info.codes_num); PE_UnwindCode *unwind_codes = push_array(scratch.arena, PE_UnwindCode, unwind_info.codes_num);
good_unwind_info = good_unwind_info && ctrl_read_cached_process_memory(machine_id, process->handle, r1u64(module->vaddr_range.min+unwind_info_off+sizeof(unwind_info), good_unwind_info = good_unwind_info && ctrl_read_cached_process_memory(machine_id, process->handle, r1u64(module->vaddr_range.min+unwind_info_off+sizeof(unwind_info),
module->vaddr_range.min+unwind_info_off+sizeof(unwind_info)+sizeof(PE_UnwindCode)*unwind_info.codes_num), module->vaddr_range.min+unwind_info_off+sizeof(unwind_info)+sizeof(PE_UnwindCode)*unwind_info.codes_num),
@@ -2173,7 +2189,8 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
// rjf: read value from stack pointer // rjf: read value from stack pointer
U64 rsp = regs->rsp.u64; U64 rsp = regs->rsp.u64;
U64 value = 0; U64 value = 0;
if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, rsp, &is_stale, &rsp, endt_us)) if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, rsp, &is_stale, &value, endt_us) ||
is_stale)
{ {
keep_parsing = 0; keep_parsing = 0;
is_good = 0; is_good = 0;
@@ -2234,7 +2251,8 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
U64 off = code_ptr[1].u16*8; U64 off = code_ptr[1].u16*8;
U64 addr = frame_base + off; U64 addr = frame_base + off;
U64 value = 0; U64 value = 0;
if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, addr, &is_stale, &value, endt_us)) if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, addr, &is_stale, &value, endt_us) ||
is_stale)
{ {
keep_parsing = 0; keep_parsing = 0;
is_good = 0; is_good = 0;
@@ -2252,7 +2270,8 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
U64 off = code_ptr[1].u16 + ((U32)code_ptr[2].u16 << 16); U64 off = code_ptr[1].u16 + ((U32)code_ptr[2].u16 << 16);
U64 addr = frame_base + off; U64 addr = frame_base + off;
U64 value = 0; U64 value = 0;
if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, addr, &is_stale, &value, endt_us)) if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, addr, &is_stale, &value, endt_us) ||
is_stale)
{ {
keep_parsing = 0; keep_parsing = 0;
is_good = 0; is_good = 0;
@@ -2301,7 +2320,8 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
U8 buf[16]; U8 buf[16];
U64 off = code_ptr[1].u16 + ((U32)code_ptr[2].u16 << 16); U64 off = code_ptr[1].u16 + ((U32)code_ptr[2].u16 << 16);
U64 addr = frame_base + off; U64 addr = frame_base + off;
if(!ctrl_read_cached_process_memory(machine_id, process->handle, r1u64(addr, addr+16), &is_stale, buf, endt_us)) if(!ctrl_read_cached_process_memory(machine_id, process->handle, r1u64(addr, addr+16), &is_stale, buf, endt_us) ||
is_stale)
{ {
keep_parsing = 0; keep_parsing = 0;
is_good = 0; is_good = 0;
@@ -2332,7 +2352,8 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
sp_adj += 8; sp_adj += 8;
} }
U64 ip_value = 0; U64 ip_value = 0;
if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, sp_adj, &is_stale, &ip_value, endt_us)) if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, sp_adj, &is_stale, &ip_value, endt_us) ||
is_stale)
{ {
keep_parsing = 0; keep_parsing = 0;
is_good = 0; is_good = 0;
@@ -2340,7 +2361,8 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
} }
U64 sp_after_ip = sp_adj + 8; U64 sp_after_ip = sp_adj + 8;
U16 ss_value = 0; U16 ss_value = 0;
if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, sp_after_ip, &is_stale, &ss_value, endt_us)) if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, sp_after_ip, &is_stale, &ss_value, endt_us) ||
is_stale)
{ {
keep_parsing = 0; keep_parsing = 0;
is_good = 0; is_good = 0;
@@ -2348,7 +2370,8 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
} }
U64 sp_after_ss = sp_after_ip + 8; U64 sp_after_ss = sp_after_ip + 8;
U64 rflags_value = 0; U64 rflags_value = 0;
if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, sp_after_ss, &is_stale, &rflags_value, endt_us)) if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, sp_after_ss, &is_stale, &rflags_value, endt_us) ||
is_stale)
{ {
keep_parsing = 0; keep_parsing = 0;
is_good = 0; is_good = 0;
@@ -2356,7 +2379,8 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
} }
U64 sp_after_rflags = sp_after_ss + 8; U64 sp_after_rflags = sp_after_ss + 8;
U64 sp_value = 0; U64 sp_value = 0;
if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, sp_after_rflags, &is_stale, &sp_value, endt_us)) if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, sp_after_rflags, &is_stale, &sp_value, endt_us) ||
is_stale)
{ {
keep_parsing = 0; keep_parsing = 0;
is_good = 0; is_good = 0;
@@ -2485,6 +2509,9 @@ ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_MachineID ma
} }
//- rjf: loop & unwind //- rjf: loop & unwind
CTRL_UnwindFrameNode *first_frame_node = 0;
CTRL_UnwindFrameNode *last_frame_node = 0;
U64 frame_node_count = 0;
UNW_MemView memview = stack_memview; UNW_MemView memview = stack_memview;
if(regs_block_good && stack_memview_good) if(regs_block_good && stack_memview_good)
{ {
@@ -2510,12 +2537,12 @@ ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_MachineID ma
} }
// rjf: valid step -> push frame // rjf: valid step -> push frame
CTRL_UnwindFrame *frame = push_array(arena, CTRL_UnwindFrame, 1); CTRL_UnwindFrameNode *frame_node = push_array(scratch.arena, CTRL_UnwindFrameNode, 1);
frame->rip = rip; CTRL_UnwindFrame *frame = &frame_node->v;
frame->regs = push_array_no_zero(arena, U8, arch_reg_block_size); frame->regs = push_array_no_zero(arena, U8, arch_reg_block_size);
MemoryCopy(frame->regs, regs_block, arch_reg_block_size); MemoryCopy(frame->regs, regs_block, arch_reg_block_size);
DLLPushBack(unwind.first, unwind.last, frame); DLLPushBack(first_frame_node, last_frame_node, frame_node);
unwind.count += 1; frame_node_count += 1;
// rjf: unwind one step // rjf: unwind one step
CTRL_UnwindStepResult step = ctrl_unwind_step(store, machine_id, module, arch, regs_block, endt_us); CTRL_UnwindStepResult step = ctrl_unwind_step(store, machine_id, module, arch, regs_block, endt_us);
@@ -2524,34 +2551,17 @@ ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_MachineID ma
{ {
break; break;
} }
}
// rjf: unwind one step (OLD) }
#if 0
UNW_Step unwind_step = {0}; //- rjf: bake frames list into result array
switch(arch) {
{ unwind.frames.count = frame_node_count;
default:{unwind_step.dead = 1;}break; unwind.frames.v = push_array(arena, CTRL_UnwindFrame, unwind.frames.count);
case Architecture_x64: U64 idx = 0;
{ for(CTRL_UnwindFrameNode *n = first_frame_node; n != 0; n = n->next, idx += 1)
unwind_step = unw_unwind_pe_x64(binary_data, &dbgi->pe, module_vaddr_range.min, &memview, (REGS_RegBlockX64 *)regs_block); {
}break; unwind.frames.v[idx] = n->v;
}
// rjf: cancel on bad step
if(unwind_step.dead != 0)
{
break;
}
if(unwind_step.missed_read != 0)
{
unwind.error = 1;
break;
}
if(unwind_step.stack_pointer == 0)
{
break;
}
#endif
} }
} }
@@ -4636,8 +4646,9 @@ ctrl_mem_stream_thread__entry_point(void *p)
Arena *range_arena = 0; Arena *range_arena = 0;
void *range_base = 0; void *range_base = 0;
U64 zero_terminated_size = 0; U64 zero_terminated_size = 0;
U64 mem_gen = dmn_mem_gen(); U64 pre_read_mem_gen = dmn_mem_gen();
if(got_task && mem_gen != preexisting_mem_gen) U64 post_read_mem_gen = 0;
if(got_task && pre_read_mem_gen != preexisting_mem_gen)
{ {
range_size = dim_1u64(vaddr_range_clamped); range_size = dim_1u64(vaddr_range_clamped);
U64 arena_size = AlignPow2(range_size + ARENA_HEADER_SIZE, os_page_size()); U64 arena_size = AlignPow2(range_size + ARENA_HEADER_SIZE, os_page_size());
@@ -4656,7 +4667,12 @@ ctrl_mem_stream_thread__entry_point(void *p)
bytes_read = dmn_process_read(process, vaddr_range_clamped_retry, range_base); bytes_read = dmn_process_read(process, vaddr_range_clamped_retry, range_base);
if(bytes_read == 0 && vaddr_range_clamped_retry.max > vaddr_range_clamped_retry.min) if(bytes_read == 0 && vaddr_range_clamped_retry.max > vaddr_range_clamped_retry.min)
{ {
vaddr_range_clamped_retry.max -= (vaddr_range_clamped_retry.max-vaddr_range_clamped_retry.min)/2; U64 diff = (vaddr_range_clamped_retry.max-vaddr_range_clamped_retry.min)/2;
vaddr_range_clamped_retry.max -= diff;
if(diff == 0)
{
break;
}
} }
else else
{ {
@@ -4687,6 +4703,7 @@ ctrl_mem_stream_thread__entry_point(void *p)
} }
} }
} }
post_read_mem_gen = dmn_mem_gen();
} }
//- rjf: read successful -> submit to hash store //- rjf: read successful -> submit to hash store
@@ -4712,7 +4729,10 @@ ctrl_mem_stream_thread__entry_point(void *p)
if(!u128_match(u128_zero(), hash)) if(!u128_match(u128_zero(), hash))
{ {
range_n->hash = hash; range_n->hash = hash;
range_n->mem_gen = mem_gen; }
if(!u128_match(u128_zero(), hash))
{
range_n->mem_gen = post_read_mem_gen;
} }
ins_atomic_u32_eval_assign(&range_n->is_taken, 0); ins_atomic_u32_eval_assign(&range_n->is_taken, 0);
goto commit__break_all; goto commit__break_all;
+16 -6
View File
@@ -123,18 +123,28 @@ struct CTRL_UnwindStepResult
typedef struct CTRL_UnwindFrame CTRL_UnwindFrame; typedef struct CTRL_UnwindFrame CTRL_UnwindFrame;
struct CTRL_UnwindFrame struct CTRL_UnwindFrame
{ {
CTRL_UnwindFrame *next;
CTRL_UnwindFrame *prev;
U64 rip;
void *regs; void *regs;
}; };
typedef struct CTRL_UnwindFrameNode CTRL_UnwindFrameNode;
struct CTRL_UnwindFrameNode
{
CTRL_UnwindFrameNode *next;
CTRL_UnwindFrameNode *prev;
CTRL_UnwindFrame v;
};
typedef struct CTRL_UnwindFrameArray CTRL_UnwindFrameArray;
struct CTRL_UnwindFrameArray
{
CTRL_UnwindFrame *v;
U64 count;
};
typedef struct CTRL_Unwind CTRL_Unwind; typedef struct CTRL_Unwind CTRL_Unwind;
struct CTRL_Unwind struct CTRL_Unwind
{ {
CTRL_UnwindFrame *first; CTRL_UnwindFrameArray frames;
CTRL_UnwindFrame *last;
U64 count;
CTRL_UnwindFlags flags; CTRL_UnwindFlags flags;
}; };
+19 -37
View File
@@ -1535,9 +1535,10 @@ df_search_tags_from_entity(Arena *arena, DF_Entity *entity)
DF_Entity *process = df_entity_ancestor_from_kind(entity, DF_EntityKind_Process); DF_Entity *process = df_entity_ancestor_from_kind(entity, DF_EntityKind_Process);
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(entity); CTRL_Unwind unwind = df_query_cached_unwind_from_thread(entity);
String8List strings = {0}; String8List strings = {0};
for(CTRL_UnwindFrame *f = unwind.last; f != 0; f = f->prev) for(U64 frame_num = unwind.frames.count; frame_num > 0; frame_num -= 1)
{ {
U64 rip_vaddr = f->rip; CTRL_UnwindFrame *f = &unwind.frames.v[frame_num-1];
U64 rip_vaddr = regs_rip_from_arch_block(entity->arch, f->regs);
DF_Entity *module = df_module_from_process_vaddr(process, rip_vaddr); DF_Entity *module = df_module_from_process_vaddr(process, rip_vaddr);
U64 rip_voff = df_voff_from_vaddr(module, rip_vaddr); U64 rip_voff = df_voff_from_vaddr(module, rip_vaddr);
DF_Entity *binary = df_binary_file_from_module(module); DF_Entity *binary = df_binary_file_from_module(module);
@@ -3672,9 +3673,9 @@ df_set_thread_rip(DF_Entity *thread, U64 vaddr)
DF_RunUnwindCacheSlot *slot = &unwind_cache->slots[slot_idx]; DF_RunUnwindCacheSlot *slot = &unwind_cache->slots[slot_idx];
for(DF_RunUnwindCacheNode *n = slot->first; n != 0; n = n->hash_next) for(DF_RunUnwindCacheNode *n = slot->first; n != 0; n = n->hash_next)
{ {
if(df_handle_match(n->thread, thread_handle) && n->unwind.first != 0) if(df_handle_match(n->thread, thread_handle) && n->unwind.frames.count != 0)
{ {
n->unwind.first->rip = vaddr; regs_arch_block_write_rip(thread->arch, n->unwind.frames.v[0].regs, vaddr);
break; break;
} }
} }
@@ -4084,17 +4085,10 @@ df_eval_from_string(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_
U64 reg_size = regs_block_size_from_architecture(arch); U64 reg_size = regs_block_size_from_architecture(arch);
U64 thread_unwind_ip_vaddr = 0; U64 thread_unwind_ip_vaddr = 0;
void *thread_unwind_regs_block = push_array(scratch.arena, U8, reg_size); void *thread_unwind_regs_block = push_array(scratch.arena, U8, reg_size);
if(unwind.frames.count != 0)
{ {
U64 idx = 0; thread_unwind_regs_block = unwind.frames.v[unwind_count%unwind.frames.count].regs;
for(CTRL_UnwindFrame *f = unwind.first; f != 0; f = f->next, idx += 1) thread_unwind_ip_vaddr = regs_rip_from_arch_block(arch, thread_unwind_regs_block);
{
if(idx == unwind_count)
{
thread_unwind_ip_vaddr = f->rip;
thread_unwind_regs_block = f->regs;
break;
}
}
} }
//- rjf: unpack module info & produce eval machine //- rjf: unpack module info & produce eval machine
@@ -4269,17 +4263,10 @@ df_value_mode_eval_from_eval(TG_Graph *graph, RDI_Parsed *rdi, DF_CtrlCtx *ctrl_
U64 type_byte_size = tg_byte_size_from_graph_rdi_key(graph, rdi, type_key); U64 type_byte_size = tg_byte_size_from_graph_rdi_key(graph, rdi, type_key);
U64 reg_off = eval.offset; U64 reg_off = eval.offset;
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread); CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread);
if(unwind.first != 0) if(unwind.frames.count != 0)
{ {
U64 unwind_idx = 0; CTRL_UnwindFrame *frame = &unwind.frames.v[ctrl_ctx->unwind_count%unwind.frames.count];
for(CTRL_UnwindFrame *frame = unwind.first; frame != 0; frame = frame->next, unwind_idx += 1) MemoryCopy(&eval.imm_u128[0], ((U8 *)frame->regs + reg_off), Min(type_byte_size, sizeof(U64)*2));
{
if(unwind_idx == ctrl_ctx->unwind_count && frame->regs != 0)
{
MemoryCopy(&eval.imm_u128[0], ((U8 *)frame->regs + reg_off), Min(type_byte_size, sizeof(U64)*2));
break;
}
}
} }
eval.mode = EVAL_EvalMode_Value; eval.mode = EVAL_EvalMode_Value;
}break; }break;
@@ -4790,11 +4777,11 @@ df_commit_eval_value(TG_Graph *graph, RDI_Parsed *rdi, DF_CtrlCtx *ctrl_ctx, DF_
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread); CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread);
Architecture arch = df_architecture_from_entity(thread); Architecture arch = df_architecture_from_entity(thread);
U64 reg_block_size = regs_block_size_from_architecture(arch); U64 reg_block_size = regs_block_size_from_architecture(arch);
if(unwind.first != 0 && if(unwind.frames.count != 0 &&
(0 <= dst_eval.offset && dst_eval.offset+commit_data.size < reg_block_size)) (0 <= dst_eval.offset && dst_eval.offset+commit_data.size < reg_block_size))
{ {
void *new_regs = push_array(scratch.arena, U8, reg_block_size); void *new_regs = push_array(scratch.arena, U8, reg_block_size);
MemoryCopy(new_regs, unwind.first->regs, reg_block_size); MemoryCopy(new_regs, unwind.frames.v[0].regs, reg_block_size);
MemoryCopy((U8 *)new_regs+dst_eval.offset, commit_data.str, commit_data.size); MemoryCopy((U8 *)new_regs+dst_eval.offset, commit_data.str, commit_data.size);
result = ctrl_thread_write_reg_block(thread->ctrl_machine_id, thread->ctrl_handle, new_regs); result = ctrl_thread_write_reg_block(thread->ctrl_machine_id, thread->ctrl_handle, new_regs);
} }
@@ -6245,7 +6232,7 @@ df_query_cached_unwind_from_thread(DF_Entity *thread)
else else
{ {
result = ctrl_unwind_from_thread(cache->arena, df_state->ctrl_entity_store, thread->ctrl_machine_id, thread->ctrl_handle, 0); result = ctrl_unwind_from_thread(cache->arena, df_state->ctrl_entity_store, thread->ctrl_machine_id, thread->ctrl_handle, 0);
if(!(result.flags & CTRL_UnwindFlag_Error)) if(!(result.flags & (CTRL_UnwindFlag_Error|CTRL_UnwindFlag_Stale)))
{ {
node = push_array(cache->arena, DF_RunUnwindCacheNode, 1); node = push_array(cache->arena, DF_RunUnwindCacheNode, 1);
SLLQueuePush_N(slot->first, slot->last, node, hash_next); SLLQueuePush_N(slot->first, slot->last, node, hash_next);
@@ -6276,14 +6263,9 @@ df_query_cached_rip_from_thread_unwind(DF_Entity *thread, U64 unwind_count)
else else
{ {
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread); CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread);
U64 unwind_idx = 0; if(unwind.frames.count != 0)
for(CTRL_UnwindFrame *frame = unwind.first; frame != 0; frame = frame->next, unwind_idx += 1)
{ {
if(unwind_idx == unwind_count) result = regs_rip_from_arch_block(thread->arch, unwind.frames.v[unwind_count%unwind.frames.count].regs);
{
result = frame->rip;
break;
}
} }
} }
return result; return result;
@@ -7436,9 +7418,9 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread); CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread);
// rjf: use first unwind frame to generate trap // rjf: use first unwind frame to generate trap
if(unwind.first != 0 && unwind.first->next != 0) if(unwind.frames.count > 1)
{ {
U64 vaddr = unwind.first->next->rip; U64 vaddr = regs_rip_from_arch_block(thread->arch, unwind.frames.v[1].regs);
CTRL_Trap trap = {CTRL_TrapFlag_EndStepping|CTRL_TrapFlag_IgnoreStackPointerCheck, vaddr}; CTRL_Trap trap = {CTRL_TrapFlag_EndStepping|CTRL_TrapFlag_IgnoreStackPointerCheck, vaddr};
ctrl_trap_list_push(scratch.arena, &traps, &trap); ctrl_trap_list_push(scratch.arena, &traps, &trap);
} }
@@ -7603,7 +7585,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
{ {
DF_Entity *thread = df_entity_from_handle(df_state->ctrl_ctx.thread); DF_Entity *thread = df_entity_from_handle(df_state->ctrl_ctx.thread);
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread); CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread);
U64 max_unwind = unwind.count ? unwind.count-1 : 0; U64 max_unwind = unwind.frames.count ? unwind.frames.count-1 : 0;
U64 index = Clamp(0, params.index, max_unwind); U64 index = Clamp(0, params.index, max_unwind);
df_state->ctrl_ctx.unwind_count = index; df_state->ctrl_ctx.unwind_count = index;
}break; }break;
+7 -6
View File
@@ -3924,9 +3924,9 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
DF_Entity *process = df_entity_ancestor_from_kind(entity, DF_EntityKind_Process); DF_Entity *process = df_entity_ancestor_from_kind(entity, DF_EntityKind_Process);
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(entity); CTRL_Unwind unwind = df_query_cached_unwind_from_thread(entity);
String8List lines = {0}; String8List lines = {0};
for(CTRL_UnwindFrame *frame = unwind.first; frame != 0; frame = frame->next) for(U64 frame_idx = 0; frame_idx < unwind.frames.count; frame_idx += 1)
{ {
U64 rip_vaddr = frame->rip; U64 rip_vaddr = regs_rip_from_arch_block(entity->arch, unwind.frames.v[frame_idx].regs);
DF_Entity *module = df_module_from_process_vaddr(process, rip_vaddr); DF_Entity *module = df_module_from_process_vaddr(process, rip_vaddr);
DF_Entity *binary = df_binary_file_from_module(module); DF_Entity *binary = df_binary_file_from_module(module);
U64 rip_voff = df_voff_from_vaddr(module, rip_vaddr); U64 rip_voff = df_voff_from_vaddr(module, rip_vaddr);
@@ -9938,9 +9938,9 @@ df_entity_tooltips(DF_Entity *entity)
ui_spacer(ui_em(1.5f, 1.f)); ui_spacer(ui_em(1.5f, 1.f));
DF_Entity *process = df_entity_ancestor_from_kind(entity, DF_EntityKind_Process); DF_Entity *process = df_entity_ancestor_from_kind(entity, DF_EntityKind_Process);
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(entity); CTRL_Unwind unwind = df_query_cached_unwind_from_thread(entity);
for(CTRL_UnwindFrame *frame = unwind.first; frame != 0; frame = frame->next) for(U64 idx = 0; idx < unwind.frames.count; idx += 1)
{ {
U64 rip_vaddr = frame->rip; U64 rip_vaddr = regs_rip_from_arch_block(entity->arch, unwind.frames.v[idx].regs);
DF_Entity *module = df_module_from_process_vaddr(process, rip_vaddr); DF_Entity *module = df_module_from_process_vaddr(process, rip_vaddr);
DF_Entity *binary = df_binary_file_from_module(module); DF_Entity *binary = df_binary_file_from_module(module);
U64 rip_voff = df_voff_from_vaddr(module, rip_vaddr); U64 rip_voff = df_voff_from_vaddr(module, rip_vaddr);
@@ -10133,9 +10133,10 @@ df_entity_desc_button(DF_Window *ws, DF_Entity *entity, FuzzyMatchRangeList *nam
U64 idx = 0; U64 idx = 0;
U64 limit = 3; U64 limit = 3;
ui_spacer(ui_em(1.f, 1.f)); ui_spacer(ui_em(1.f, 1.f));
for(CTRL_UnwindFrame *f = unwind.last; f != 0 && idx < limit; f = f->prev) for(U64 num = unwind.frames.count; num > 0; num -= 1)
{ {
U64 rip_vaddr = f->rip; CTRL_UnwindFrame *f = &unwind.frames.v[num-1];
U64 rip_vaddr = regs_rip_from_arch_block(entity->arch, f->regs);
DF_Entity *module = df_module_from_process_vaddr(process, rip_vaddr); DF_Entity *module = df_module_from_process_vaddr(process, rip_vaddr);
U64 rip_voff = df_voff_from_vaddr(module, rip_vaddr); U64 rip_voff = df_voff_from_vaddr(module, rip_vaddr);
DF_Entity *binary = df_binary_file_from_module(module); DF_Entity *binary = df_binary_file_from_module(module);
+21 -26
View File
@@ -888,19 +888,12 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread); CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread);
Architecture arch = df_architecture_from_entity(thread); Architecture arch = df_architecture_from_entity(thread);
U64 reg_size = regs_block_size_from_architecture(arch); U64 reg_size = regs_block_size_from_architecture(arch);
U64 thread_unwind_ip_vaddr = 0;
void *thread_unwind_regs_block = push_array(scratch.arena, U8, reg_size); void *thread_unwind_regs_block = push_array(scratch.arena, U8, reg_size);
U64 thread_unwind_ip_vaddr = 0;
if(unwind.frames.count != 0)
{ {
U64 idx = 0; thread_unwind_regs_block = unwind.frames.v[unwind_count%unwind.frames.count].regs;
for(CTRL_UnwindFrame *f = unwind.first; f != 0; f = f->next, idx += 1) thread_unwind_ip_vaddr = regs_rip_from_arch_block(arch, thread_unwind_regs_block);
{
if(idx == unwind_count)
{
thread_unwind_ip_vaddr = f->rip;
thread_unwind_regs_block = f->regs;
break;
}
}
} }
//- rjf: lex & parse //- rjf: lex & parse
@@ -4815,8 +4808,8 @@ DF_VIEW_UI_FUNCTION_DEF(CallStack)
scroll_list_params.flags = UI_ScrollListFlag_All; scroll_list_params.flags = UI_ScrollListFlag_All;
scroll_list_params.row_height_px = floor_f32(ui_top_font_size()*2.5f); scroll_list_params.row_height_px = floor_f32(ui_top_font_size()*2.5f);
scroll_list_params.dim_px = dim_2f32(rect); scroll_list_params.dim_px = dim_2f32(rect);
scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(3, unwind.count)); scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(3, unwind.frames.count));
scroll_list_params.item_range = r1s64(0, unwind.count+1); scroll_list_params.item_range = r1s64(0, unwind.frames.count+1);
scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1;
} }
UI_ScrollListSignal scroll_list_sig = {0}; UI_ScrollListSignal scroll_list_sig = {0};
@@ -4849,20 +4842,20 @@ DF_VIEW_UI_FUNCTION_DEF(CallStack)
} }
//- rjf: frame rows //- rjf: frame rows
U64 frame_idx = 0; for(S64 row_num = visible_row_range.min; row_num <= visible_row_range.max && row_num <= unwind.frames.count; row_num += 1)
for(CTRL_UnwindFrame *frame = unwind.first; frame != 0; frame = frame->next, frame_idx += 1)
{ {
// rjf: out of range -> skip (TODO(rjf): this should be an array...) if(row_num == 0)
if(frame_idx+1 < visible_row_range.min || visible_row_range.max < frame_idx+1)
{ {
continue; continue;
} }
U64 frame_idx = row_num-1;
CTRL_UnwindFrame *frame = &unwind.frames.v[frame_idx];
// rjf: determine selection // rjf: determine selection
B32 row_selected = cs->cursor.y == ((S64)frame_idx+1); B32 row_selected = (cs->cursor.y == row_num);
// rjf: regs => rip // rjf: regs => rip
U64 rip_vaddr = frame->rip; U64 rip_vaddr = regs_rip_from_arch_block(thread->arch, frame->regs);
// rjf: rip_vaddr => module // rjf: rip_vaddr => module
DF_Entity *module = df_module_from_process_vaddr(process, rip_vaddr); DF_Entity *module = df_module_from_process_vaddr(process, rip_vaddr);
@@ -8485,20 +8478,22 @@ DF_VIEW_UI_FUNCTION_DEF(Memory)
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread); CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread);
//- rjf: fill unwind frame annotations //- rjf: fill unwind frame annotations
if(unwind.first != 0) if(unwind.frames.count != 0)
{ {
U64 last_stack_top = regs_rsp_from_arch_block(thread->arch, unwind.first->regs); U64 last_stack_top = regs_rsp_from_arch_block(thread->arch, unwind.frames.v[0].regs);
for(CTRL_UnwindFrame *f = unwind.first->next; f != 0; f = f->next) for(U64 idx = 1; idx < unwind.frames.count; idx += 1)
{ {
CTRL_UnwindFrame *f = &unwind.frames.v[idx];
U64 f_stack_top = regs_rsp_from_arch_block(thread->arch, f->regs); U64 f_stack_top = regs_rsp_from_arch_block(thread->arch, f->regs);
Rng1U64 frame_vaddr_range = r1u64(last_stack_top, f_stack_top); 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); Rng1U64 frame_vaddr_range_in_viz = intersect_1u64(frame_vaddr_range, viz_range_bytes);
last_stack_top = f_stack_top; last_stack_top = f_stack_top;
if(dim_1u64(frame_vaddr_range_in_viz) != 0) if(dim_1u64(frame_vaddr_range_in_viz) != 0)
{ {
DF_Entity *module = df_module_from_process_vaddr(process, f->rip); U64 f_rip = regs_rip_from_arch_block(thread->arch, f->regs);
DF_Entity *module = df_module_from_process_vaddr(process, f_rip);
DF_Entity *binary = df_binary_file_from_module(module); DF_Entity *binary = df_binary_file_from_module(module);
U64 rip_voff = df_voff_from_vaddr(module, f->rip); U64 rip_voff = df_voff_from_vaddr(module, f_rip);
String8 symbol_name = df_symbol_name_from_binary_voff(scratch.arena, binary, rip_voff); String8 symbol_name = df_symbol_name_from_binary_voff(scratch.arena, binary, rip_voff);
Annotation *annotation = push_array(scratch.arena, Annotation, 1); Annotation *annotation = push_array(scratch.arena, Annotation, 1);
annotation->name_string = symbol_name.size != 0 ? symbol_name : str8_lit("[external code]"); annotation->name_string = symbol_name.size != 0 ? symbol_name : str8_lit("[external code]");
@@ -8515,10 +8510,10 @@ DF_VIEW_UI_FUNCTION_DEF(Memory)
} }
//- rjf: fill selected thread stack range annotation //- rjf: fill selected thread stack range annotation
if(unwind.first != 0) if(unwind.frames.count > 0)
{ {
U64 stack_base_vaddr = thread->stack_base; U64 stack_base_vaddr = thread->stack_base;
U64 stack_top_vaddr = regs_rsp_from_arch_block(thread->arch, unwind.first->regs); U64 stack_top_vaddr = regs_rsp_from_arch_block(thread->arch, unwind.frames.v[0].regs);
Rng1U64 stack_vaddr_range = r1u64(stack_base_vaddr, stack_top_vaddr); 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); Rng1U64 stack_vaddr_range_in_viz = intersect_1u64(stack_vaddr_range, viz_range_bytes);
if(dim_1u64(stack_vaddr_range_in_viz) != 0) if(dim_1u64(stack_vaddr_range_in_viz) != 0)
+4 -4
View File
@@ -13,7 +13,7 @@ internal U64
regs_rip_from_arch_block(Architecture arch, void *block) regs_rip_from_arch_block(Architecture arch, void *block)
{ {
U64 result = 0; U64 result = 0;
switch(arch) if(block != 0) switch(arch)
{ {
default:{}break; default:{}break;
case Architecture_x64:{result = ((REGS_RegBlockX64 *)block)->rip.u64;}break; case Architecture_x64:{result = ((REGS_RegBlockX64 *)block)->rip.u64;}break;
@@ -26,7 +26,7 @@ internal U64
regs_rsp_from_arch_block(Architecture arch, void *block) regs_rsp_from_arch_block(Architecture arch, void *block)
{ {
U64 result = 0; U64 result = 0;
switch(arch) if(block != 0) switch(arch)
{ {
default:{}break; default:{}break;
case Architecture_x64:{result = ((REGS_RegBlockX64 *)block)->rsp.u64;}break; case Architecture_x64:{result = ((REGS_RegBlockX64 *)block)->rsp.u64;}break;
@@ -38,7 +38,7 @@ regs_rsp_from_arch_block(Architecture arch, void *block)
internal void internal void
regs_arch_block_write_rip(Architecture arch, void *block, U64 rip) regs_arch_block_write_rip(Architecture arch, void *block, U64 rip)
{ {
switch(arch) if(block != 0) switch(arch)
{ {
default:{}break; default:{}break;
case Architecture_x64:{((REGS_RegBlockX64 *)block)->rip.u64 = rip;}break; case Architecture_x64:{((REGS_RegBlockX64 *)block)->rip.u64 = rip;}break;
@@ -49,7 +49,7 @@ regs_arch_block_write_rip(Architecture arch, void *block, U64 rip)
internal void internal void
regs_arch_block_write_rsp(Architecture arch, void *block, U64 rsp) regs_arch_block_write_rsp(Architecture arch, void *block, U64 rsp)
{ {
switch(arch) if(block != 0) switch(arch)
{ {
default:{}break; default:{}break;
case Architecture_x64:{((REGS_RegBlockX64 *)block)->rsp.u64 = rsp;}break; case Architecture_x64:{((REGS_RegBlockX64 *)block)->rsp.u64 = rsp;}break;