mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 17:28:07 +00:00
parse CIE and FDE out of runtime ELF
This commit is contained in:
committed by
Ryan Fleury
parent
4e2c983b0f
commit
7f705923e6
+206
-76
@@ -1901,11 +1901,13 @@ DW_REG_WRITE(ctrl_unwind_reg_write_dwarf_x64)
|
||||
internal CTRL_UnwindStepResult
|
||||
ctrl_unwind_step__dwarf(CTRL_Handle process_handle, CTRL_Handle module_handle, Arch arch, void *regs, U64 endt_us)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
|
||||
CTRL_UnwindStepResult result = { .flags = CTRL_UnwindFlag_Error };
|
||||
|
||||
// gather context for virtual stack unwinder
|
||||
U64 rebase = 0;
|
||||
B32 is_unwind_data_eh = 0;
|
||||
B32 is_unwind_eh = 0;
|
||||
String8 unwind_data = {0};
|
||||
EH_FrameHdr eh_frame_hdr = {0};
|
||||
EH_PtrCtx eh_ptr_ctx = {0};
|
||||
@@ -1920,7 +1922,7 @@ ctrl_unwind_step__dwarf(CTRL_Handle process_handle, CTRL_Handle module_handle, A
|
||||
if(ctrl_handle_match(n->module, module_handle))
|
||||
{
|
||||
rebase = n->rebase;
|
||||
is_unwind_data_eh = n->is_dwarf_unwind_data_eh;
|
||||
is_unwind_eh = n->is_unwind_eh;
|
||||
unwind_data = n->dwarf_unwind_data;
|
||||
eh_frame_hdr = n->eh_frame_hdr;
|
||||
eh_ptr_ctx = n->eh_ptr_ctx;
|
||||
@@ -1934,25 +1936,103 @@ ctrl_unwind_step__dwarf(CTRL_Handle process_handle, CTRL_Handle module_handle, A
|
||||
U64 cfi_ip = ip + rebase;
|
||||
|
||||
// use .eh_frame_hdr to quickly locate nearest FDE offset
|
||||
U64 fde_offset = eh_find_nearest_fde(eh_frame_hdr, &eh_ptr_ctx, cfi_ip);
|
||||
U64 fde_addr = eh_find_nearest_fde(eh_frame_hdr, &eh_ptr_ctx, cfi_ip);
|
||||
|
||||
if(fde_offset < unwind_data.size)
|
||||
if(fde_addr != max_U64)
|
||||
{
|
||||
// parse call frame info
|
||||
DW_CIE cie = {0};
|
||||
DW_FDE fde = {0};
|
||||
B32 is_cfi_parsed = is_unwind_data_eh ?
|
||||
eh_parse_cfi(unwind_data, fde_offset, arch, &eh_ptr_ctx, &cie, &fde) :
|
||||
dw_parse_cfi(unwind_data, fde_offset, arch, &cie, &fde);
|
||||
B32 is_cfi_parsed = 0;
|
||||
if(is_unwind_eh)
|
||||
{
|
||||
B32 is_stale = 0;
|
||||
|
||||
// extract FDE info
|
||||
Rng1U64 fde_vrange = {0};
|
||||
DW_Format fde_format = DW_Format_Null;
|
||||
String8 fde_data = {0};
|
||||
U64 cie_addr = 0;
|
||||
{
|
||||
// parse FDE length
|
||||
U32 first_four_bytes = 0;
|
||||
if(!ctrl_process_memory_read_struct(process_handle, fde_addr, &is_stale, &first_four_bytes, endt_us)) { goto eh_parse_exit; }
|
||||
if(first_four_bytes == max_U32)
|
||||
{
|
||||
U64 length = 0;
|
||||
if(!ctrl_process_memory_read_struct(process_handle, fde_addr + sizeof(first_four_bytes), &is_stale, &length, endt_us)) { goto eh_parse_exit; }
|
||||
fde_vrange = r1u64(fde_addr, fde_addr + sizeof(first_four_bytes) + length);
|
||||
fde_format = DW_Format_64Bit;
|
||||
}
|
||||
else
|
||||
{
|
||||
fde_vrange = r1u64(fde_addr, fde_addr + sizeof(first_four_bytes) + first_four_bytes);
|
||||
fde_format = DW_Format_32Bit;
|
||||
}
|
||||
|
||||
// read out whole FDE
|
||||
void *fde_raw = push_array(scratch.arena, U8, dim_1u64(fde_vrange));
|
||||
if(!ctrl_process_memory_read(process_handle, fde_vrange, &is_stale, fde_raw, endt_us)) { goto eh_parse_exit; }
|
||||
fde_data = str8(fde_raw, dim_1u64(fde_vrange));
|
||||
|
||||
// compute CIE address
|
||||
U64 cie_delta_off = fde_format == DW_Format_32Bit ? 4 : 12;
|
||||
U64 cie_delta = 0;
|
||||
U64 cie_delta_size = str8_deserial_read_dwarf_uint(fde_data, cie_delta_off, fde_format, &cie_delta);
|
||||
if (cie_delta_size == 0) { goto eh_parse_exit; }
|
||||
cie_addr = (fde_addr + cie_delta_off) - cie_delta;
|
||||
}
|
||||
|
||||
// extract CIE info
|
||||
Rng1U64 cie_vrange = {0};
|
||||
DW_Format cie_format = DW_Format_Null;
|
||||
String8 cie_data = {0};
|
||||
{
|
||||
// parse CIE length
|
||||
U32 first_four_bytes = 0;
|
||||
if(!ctrl_process_memory_read_struct(process_handle, cie_addr, &is_stale, &first_four_bytes, endt_us)) { goto eh_parse_exit; }
|
||||
if(first_four_bytes == max_U32)
|
||||
{
|
||||
U64 length = 0;
|
||||
if(!ctrl_process_memory_read_struct(process_handle, cie_addr + sizeof(first_four_bytes), &is_stale, &length, endt_us)) { goto eh_parse_exit; }
|
||||
cie_vrange = r1u64(cie_addr, cie_addr + sizeof(first_four_bytes) + length);
|
||||
cie_format = DW_Format_64Bit;
|
||||
}
|
||||
else
|
||||
{
|
||||
cie_vrange = r1u64(cie_addr, cie_addr + sizeof(first_four_bytes) + first_four_bytes);
|
||||
cie_format = DW_Format_32Bit;
|
||||
}
|
||||
|
||||
// read out whole CIE
|
||||
void *cie_raw = push_array(scratch.arena, U8, dim_1u64(cie_vrange));
|
||||
if(!ctrl_process_memory_read(process_handle, cie_vrange, &is_stale, cie_raw, endt_us)) { goto eh_parse_exit; }
|
||||
cie_data = str8(cie_raw, dim_1u64(cie_vrange));
|
||||
}
|
||||
|
||||
// parse CIE and FDE
|
||||
if(eh_parse_cie(cie_data, cie_format, arch, cie_vrange.min, &eh_ptr_ctx, &cie))
|
||||
{
|
||||
is_cfi_parsed = eh_parse_fde(fde_data, fde_format, fde_vrange.min, &cie, &eh_ptr_ctx, &fde);
|
||||
}
|
||||
|
||||
eh_parse_exit:;
|
||||
if(is_stale)
|
||||
{
|
||||
result.flags = CTRL_UnwindFlag_Stale;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
is_cfi_parsed = dw_parse_cfi(unwind_data, fde_addr, arch, &cie, &fde);
|
||||
}
|
||||
|
||||
if(is_cfi_parsed)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
|
||||
// setup pointer decoder ops
|
||||
DW_DecodePtr *decode_ptr_func = 0;
|
||||
void *decode_ptr_ctx = 0;
|
||||
if(is_unwind_data_eh)
|
||||
if(is_unwind_eh)
|
||||
{
|
||||
EH_DecodePtrCtx *decode_ptr_ctx_eh = push_array(scratch.arena, EH_DecodePtrCtx, 1);
|
||||
decode_ptr_ctx_eh->ptr_ctx = &eh_ptr_ctx;
|
||||
@@ -2034,12 +2114,6 @@ ctrl_unwind_step__dwarf(CTRL_Handle process_handle, CTRL_Handle module_handle, A
|
||||
default: { InvalidPath; } break;
|
||||
}
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert(0 && "failed to parse CFI");
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -2047,6 +2121,7 @@ ctrl_unwind_step__dwarf(CTRL_Handle process_handle, CTRL_Handle module_handle, A
|
||||
// TODO: if IP does not have FDE, does this mean function is a leaf?
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -3639,28 +3714,21 @@ ctrl_thread__append_program_defined_bp_traps(Arena *arena, CTRL_Entity *bp, DMN_
|
||||
|
||||
//- rjf: module lifetime open/close work
|
||||
|
||||
internal void
|
||||
ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_range, String8 path)
|
||||
internal
|
||||
DW_MEM_READ(ctrl_dmn_mem_read)
|
||||
{
|
||||
//////////////////////////////
|
||||
//- rjf: parse module image info
|
||||
//
|
||||
U64 read = dmn_process_read(((CTRL_Handle *)ud)->dmn_handle, r1u64(addr, addr + size), buffer);
|
||||
return read == size ? DW_UnwindStatus_Ok : DW_UnwindStatus_Fail;
|
||||
}
|
||||
|
||||
internal void
|
||||
ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_range, String8 path, Rng1U64 elf_phdr_vrange, U64 elf_phdr_entsize)
|
||||
{
|
||||
Temp scratch = scratch_begin(0,0);
|
||||
|
||||
Arena *arena = arena_alloc();
|
||||
COFF_MachineType machine = COFF_MachineType_Unknown;
|
||||
PE_ImageFileCharacteristics file_characteristics = 0;
|
||||
PE_IntelPdata *pdatas = 0;
|
||||
U64 pdatas_count = 0;
|
||||
U64 rebase = 0;
|
||||
B32 is_dwarf_unwind_data_eh = 0;
|
||||
String8 dwarf_unwind_data = {0};
|
||||
EH_FrameHdr eh_frame_hdr = {0};
|
||||
EH_PtrCtx eh_ptr_ctx = {0};
|
||||
U64 entry_point_voff = 0;
|
||||
Rng1U64 tls_vaddr_range = {0};
|
||||
U32 pdb_dbg_time = 0;
|
||||
U32 pdb_dbg_age = 0;
|
||||
Guid pdb_dbg_guid = {0};
|
||||
String8 pdb_dbg_path = {0};
|
||||
U32 rdi_dbg_time = 0;
|
||||
Guid rdi_dbg_guid = {0};
|
||||
String8 exe_dbg_path = {0};
|
||||
@@ -3668,6 +3736,30 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_
|
||||
String8 raddbg_data = {0};
|
||||
Rng1U64 raddbg_section_voff_range = r1u64(0, 0);
|
||||
Rng1U64 raddbg_is_attached_section_voff_range = r1u64(0, 0);
|
||||
|
||||
PE_IntelPdata *pdatas = 0;
|
||||
U64 pdatas_count = 0;
|
||||
U32 pdb_dbg_time = 0;
|
||||
U32 pdb_dbg_age = 0;
|
||||
Guid pdb_dbg_guid = {0};
|
||||
String8 pdb_dbg_path = {0};
|
||||
|
||||
U64 rebase = 0;
|
||||
B32 is_unwind_eh = 0;
|
||||
EH_FrameHdr eh_frame_hdr = {0};
|
||||
EH_PtrCtx eh_ptr_ctx = { .raw_base_vaddr = max_U64, .text_vaddr = max_U64, .data_vaddr = max_U64, .func_vaddr = max_U64, .ptr_align = 0 };
|
||||
|
||||
// read module's signature bytes
|
||||
U64 module_sig_size = Max(elf_magic_string.size, sizeof(PE_DosMagic));
|
||||
U8 *module_sig_bytes = push_array(scratch.arena, U8, module_sig_size);
|
||||
dmn_process_read(process.dmn_handle, rng_1u64(vaddr_range.min, vaddr_range.min + module_sig_size), module_sig_bytes);
|
||||
|
||||
//////////////////////////////
|
||||
//- parse PE module
|
||||
//
|
||||
PE_DosMagic dos_magic = *(PE_DosMagic *)module_sig_bytes;
|
||||
if(dos_magic == PE_DOS_MAGIC)
|
||||
{
|
||||
ProfScope("unpack relevant PE info")
|
||||
{
|
||||
B32 is_valid = 1;
|
||||
@@ -3699,12 +3791,7 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_
|
||||
COFF_FileHeader file_header = {0};
|
||||
if(is_valid)
|
||||
{
|
||||
if(dmn_process_read_struct(process.dmn_handle, vaddr_range.min + file_header_off, &file_header))
|
||||
{
|
||||
machine = file_header.machine;
|
||||
file_characteristics = file_header.flags;
|
||||
}
|
||||
else
|
||||
if(!dmn_process_read_struct(process.dmn_handle, vaddr_range.min + file_header_off, &file_header))
|
||||
{
|
||||
is_valid = 0;
|
||||
}
|
||||
@@ -3720,8 +3807,6 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_
|
||||
U32 data_dir_count = 0;
|
||||
if(opt_ext_size > 0)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
|
||||
// rjf: read magic number
|
||||
U16 opt_ext_magic = 0;
|
||||
dmn_process_read_struct(process.dmn_handle, vaddr_range.min + opt_ext_off_range.min, &opt_ext_magic);
|
||||
@@ -3902,44 +3987,90 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_
|
||||
U8 new_value = 1;
|
||||
dmn_process_write_struct(process.dmn_handle, vaddr_range.min + raddbg_is_attached_section_voff_range.min, &new_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//////////////////////////////
|
||||
//- parse ELF module
|
||||
//
|
||||
else if(str8_match(str8(module_sig_bytes, elf_magic_string.size), elf_magic_string, 0))
|
||||
{
|
||||
U64 e_entry = 0;
|
||||
ELF_Type e_type = ELF_Type_None;
|
||||
{
|
||||
U8 *elf_sig = dmn_process_read_raw(scratch.arena, process.dmn_handle, rng_1u64(vaddr_range.min, vaddr_range.min + sizeof(elf_sig[0]) * ELF_Identifier_Max));
|
||||
if(elf_sig == 0) { goto elf_exit; }
|
||||
switch(elf_sig[ELF_Identifier_Class])
|
||||
{
|
||||
default:
|
||||
case ELF_Class_None:{}break;
|
||||
case ELF_Class_32:
|
||||
{
|
||||
NotImplemented;
|
||||
}break;
|
||||
case ELF_Class_64:
|
||||
{
|
||||
ELF_Hdr64 *ehdr = dmn_process_read_raw(scratch.arena, process.dmn_handle, rng_1u64(vaddr_range.min, vaddr_range.min + sizeof(*ehdr)));
|
||||
if(ehdr == 0) { goto elf_exit; }
|
||||
e_entry = ehdr->e_entry;
|
||||
e_type = ehdr->e_type;
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// TODO(ns): temporary hack to test DWARF unwinder on windows -- remove when done
|
||||
// find and parse .eh_frame_hdr
|
||||
Rng1U64 eh_frame_hdr_vrange = {0};
|
||||
String8 eh_frame_hdr_data = {0};
|
||||
{
|
||||
for EachIndex(idx, sec_count)
|
||||
void *phdrs_raw = dmn_process_read_raw(scratch.arena, process.dmn_handle, elf_phdr_vrange);
|
||||
if(phdrs_raw == 0) { goto elf_exit; }
|
||||
|
||||
if(elf_phdr_entsize == sizeof(ELF_Phdr32))
|
||||
{
|
||||
String8 section_name = str8_cstring((char *)sec[idx].name);
|
||||
if(str8_match(section_name, str8_lit("/130"), 0))
|
||||
{
|
||||
U64 restore_pos = arena_pos(arena);
|
||||
Rng1U64 debug_frame_voff_range = rng_1u64(sec[idx].voff, sec[idx].voff + sec[idx].vsize);
|
||||
Rng1U64 debug_frame_vaddr_range = shift_1u64(debug_frame_voff_range, vaddr_range.min);
|
||||
void *debug_frame_buffer = push_array(arena, U8, sec[idx].vsize);
|
||||
U64 debug_frame_read_size = dmn_process_read(process.dmn_handle, debug_frame_vaddr_range, debug_frame_buffer);
|
||||
if(debug_frame_read_size == sec[idx].vsize)
|
||||
{
|
||||
U64 default_base = pe_get_default_base_addr(file_characteristics, machine);
|
||||
Arch arch = ctrl_arch_from_process_handle(process);
|
||||
String8 debug_frame = str8(debug_frame_buffer, debug_frame_read_size);
|
||||
DW_CallFrameInfo dwarf_cfi = dw_call_frame_info_from_data(scratch.arena, arch, debug_frame);
|
||||
String8 eh_frame_hdr_data = eh_frame_hdr_from_call_frame_info(arena, dwarf_cfi.fde_count, dwarf_cfi.fde_offsets, dwarf_cfi.fde);
|
||||
rebase = default_base - vaddr_range.min; // DL overwrites image base in the optional header, if image is linked with a custom base this breaks
|
||||
dwarf_unwind_data = debug_frame;
|
||||
is_dwarf_unwind_data_eh = 0;
|
||||
eh_frame_hdr = eh_parse_frame_hdr(eh_frame_hdr_data, byte_size_from_arch(arch), 0);
|
||||
NotImplemented;
|
||||
}
|
||||
else
|
||||
else if(elf_phdr_entsize == sizeof(ELF_Phdr64))
|
||||
{
|
||||
arena_pop_to(arena, restore_pos);
|
||||
}
|
||||
U64 elf_phcount = dim_1u64(elf_phdr_vrange) / elf_phdr_entsize;
|
||||
ELF_Phdr64 *phdrs64 = phdrs_raw;
|
||||
for EachIndex(phdr_idx, elf_phcount)
|
||||
{
|
||||
ELF_Phdr64 *phdr = phdrs64 + phdr_idx;
|
||||
if(phdr->p_type == ELF_PType_GnuEHFrame)
|
||||
{
|
||||
eh_frame_hdr_vrange = r1u64(phdr->p_vaddr, phdr->p_vaddr + phdr->p_memsz);
|
||||
eh_frame_hdr_data = dmn_process_read_block(arena, process.dmn_handle, eh_frame_hdr_vrange);
|
||||
is_unwind_eh = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
// parse .eh_frame_hdr
|
||||
Arch arch = ctrl_arch_from_process_handle(process);
|
||||
eh_ptr_ctx.raw_base_vaddr = eh_frame_hdr_vrange.min;
|
||||
eh_ptr_ctx.data_vaddr = eh_frame_hdr_vrange.min;
|
||||
eh_frame_hdr = eh_parse_frame_hdr(eh_frame_hdr_data, byte_size_from_arch(arch), &eh_ptr_ctx);
|
||||
|
||||
// set entry point
|
||||
if (e_entry != 0)
|
||||
{
|
||||
entry_point_voff = e_entry - vaddr_range.min;
|
||||
}
|
||||
|
||||
// TODO: is there a way to detect DWARF in runtime ELF?
|
||||
if(1)
|
||||
{
|
||||
exe_dbg_path = path;
|
||||
}
|
||||
|
||||
if(e_type == ELF_Type_Dyn)
|
||||
{
|
||||
rebase = -vaddr_range.min;
|
||||
}
|
||||
|
||||
elf_exit:;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
@@ -3947,7 +4078,6 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_
|
||||
//
|
||||
String8 initial_debug_info_path = str8_zero();
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
String8 exe_folder = str8_chop_last_slash(path);
|
||||
String8List dbg_path_candidates = {0};
|
||||
//
|
||||
@@ -3988,7 +4118,6 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_
|
||||
break;
|
||||
}
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
@@ -4003,7 +4132,7 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_
|
||||
MutexScopeW(stripe->rw_mutex)
|
||||
{
|
||||
CTRL_ModuleImageInfoCacheNode *node = 0;
|
||||
for(CTRL_ModuleImageInfoCacheNode *n = slot->first; n != 0; n = n->next)
|
||||
for EachNode(n, CTRL_ModuleImageInfoCacheNode, slot->first)
|
||||
{
|
||||
if(ctrl_handle_match(n->module, module))
|
||||
{
|
||||
@@ -4020,8 +4149,7 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_
|
||||
node->pdatas = pdatas;
|
||||
node->pdatas_count = pdatas_count;
|
||||
node->rebase = rebase;
|
||||
node->is_dwarf_unwind_data_eh = is_dwarf_unwind_data_eh;
|
||||
node->dwarf_unwind_data = dwarf_unwind_data;
|
||||
node->is_unwind_eh = is_unwind_eh;
|
||||
node->eh_frame_hdr = eh_frame_hdr;
|
||||
node->eh_ptr_ctx = eh_ptr_ctx;
|
||||
node->entry_point_voff = entry_point_voff;
|
||||
@@ -4029,6 +4157,8 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
internal void
|
||||
@@ -4362,7 +4492,7 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg,
|
||||
CTRL_Event *out_evt1 = ctrl_event_list_push(scratch.arena, &evts);
|
||||
String8 module_path = path_normalized_from_string(scratch.arena, event->string);
|
||||
U64 exe_timestamp = os_properties_from_file_path(module_path).modified;
|
||||
ctrl_thread__module_open(process_handle, module_handle, r1u64(event->address, event->address+event->size), module_path);
|
||||
ctrl_thread__module_open(process_handle, module_handle, r1u64(event->address, event->address+event->size), module_path, event->elf_phdr_vrange, event->elf_phdr_entsize);
|
||||
out_evt1->kind = CTRL_EventKind_NewModule;
|
||||
out_evt1->msg_id = msg->msg_id;
|
||||
out_evt1->entity = module_handle;
|
||||
|
||||
@@ -598,7 +598,7 @@ struct CTRL_ModuleImageInfoCacheNode
|
||||
PE_IntelPdata *pdatas;
|
||||
U64 pdatas_count;
|
||||
U64 rebase;
|
||||
B32 is_dwarf_unwind_data_eh;
|
||||
B32 is_unwind_eh;
|
||||
String8 dwarf_unwind_data;
|
||||
EH_FrameHdr eh_frame_hdr;
|
||||
EH_PtrCtx eh_ptr_ctx;
|
||||
@@ -987,7 +987,7 @@ internal void ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, C
|
||||
internal void ctrl_thread__append_program_defined_bp_traps(Arena *arena, CTRL_Entity *bp, DMN_TrapChunkList *traps_out);
|
||||
|
||||
//- rjf: module lifetime open/close work
|
||||
internal void ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_range, String8 path);
|
||||
internal void ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_range, String8 path, Rng1U64 elf_phdr_vrange, U64 elf_phdr_entsize);
|
||||
internal void ctrl_thread__module_close(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_range);
|
||||
|
||||
//- rjf: attached process running/event gathering
|
||||
|
||||
@@ -486,6 +486,7 @@ struct PE_LoadConfig64
|
||||
#define PE_MAGIC 0x00004550u
|
||||
#define PE_PE32_MAGIC 0x010bu
|
||||
#define PE_PE32PLUS_MAGIC 0x020bu
|
||||
typedef U16 PE_DosMagic;
|
||||
|
||||
typedef struct PE_MipsPdata PE_MipsPdata;
|
||||
struct PE_MipsPdata
|
||||
|
||||
Reference in New Issue
Block a user