Skip to content

Commit c8a5fc4

Browse files
Changed debug directory parser to handle multiple entries. Added
parser for RDI debug info entry. Changed debug info lookup order so debugger tries to load path specified in exe first and if debug info is missing then debugger will do heuristic searches.
1 parent 652dcaf commit c8a5fc4

File tree

1 file changed

+63
-54
lines changed

1 file changed

+63
-54
lines changed

src/ctrl/ctrl_core.c

Lines changed: 63 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3472,7 +3472,13 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_
34723472
U64 pdatas_count = 0;
34733473
U64 entry_point_voff = 0;
34743474
Rng1U64 tls_vaddr_range = {0};
3475-
String8 builtin_debug_info_path = {0};
3475+
U32 pdb_dbg_time = 0;
3476+
U32 pdb_dbg_age = 0;
3477+
OS_Guid pdb_dbg_guid = {0};
3478+
String8 pdb_dbg_path = str8_zero();
3479+
U32 rdi_dbg_time = 0;
3480+
OS_Guid rdi_dbg_guid = {0};
3481+
String8 rdi_dbg_path = str8_zero();
34763482
ProfScope("unpack relevant PE info")
34773483
{
34783484
B32 is_valid = 1;
@@ -3608,65 +3614,62 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_
36083614
tls_vaddr_range = r1u64(tls_header.index_address, tls_header.index_address+sizeof(U32));
36093615

36103616
// rjf: grab data about debug info
3611-
U32 dbg_time = 0;
3612-
U32 dbg_age = 0;
3613-
OS_Guid dbg_guid = {0};
3617+
36143618
if(data_dir_count > PE_DataDirectoryIndex_DEBUG)
36153619
{
36163620
// rjf: read data dir
36173621
PE_DataDirectory dir = {0};
36183622
dmn_process_read_struct(process.dmn_handle, vaddr_range.min + opt_ext_off_range.min + reported_data_dir_offset + sizeof(PE_DataDirectory)*PE_DataDirectoryIndex_DEBUG, &dir);
36193623

3620-
// rjf: read debug directory
3621-
PE_DebugDirectory dbg_data = {0};
3622-
dmn_process_read_struct(process.dmn_handle, vaddr_range.min+(U64)dir.virt_off, &dbg_data);
3623-
3624-
// rjf: extract external file info from codeview header
3625-
if(dbg_data.type == PE_DebugDirectoryType_CODEVIEW)
3624+
U64 dbg_dir_count = dir.virt_size / sizeof(PE_DebugDirectory);
3625+
for(U64 dbg_dir_idx = 0; dbg_dir_idx < dbg_dir_count; dbg_dir_idx += 1)
36263626
{
3627-
U64 dbg_path_off = 0;
3628-
U64 dbg_path_size = 0;
3629-
U64 cv_offset = dbg_data.voff;
3630-
U32 cv_magic = 0;
3631-
dmn_process_read_struct(process.dmn_handle, vaddr_range.min+cv_offset, &cv_magic);
3632-
switch(cv_magic)
3633-
{
3634-
default:break;
3635-
case PE_CODEVIEW_PDB20_MAGIC:
3636-
{
3637-
PE_CvHeaderPDB20 cv = {0};
3638-
dmn_process_read_struct(process.dmn_handle, vaddr_range.min+cv_offset, &cv);
3639-
dbg_time = cv.time;
3640-
dbg_age = cv.age;
3641-
dbg_path_off = cv_offset + sizeof(cv);
3642-
}break;
3643-
case PE_CODEVIEW_PDB70_MAGIC:
3644-
{
3645-
PE_CvHeaderPDB70 cv = {0};
3646-
dmn_process_read_struct(process.dmn_handle, vaddr_range.min+cv_offset, &cv);
3647-
dbg_guid = cv.guid;
3648-
dbg_age = cv.age;
3649-
dbg_path_off = cv_offset + sizeof(cv);
3650-
}break;
3651-
}
3652-
if(dbg_path_off > 0)
3627+
// rjf: read debug directory
3628+
U64 dir_addr = vaddr_range.min + dir.virt_off + dbg_dir_idx * sizeof(PE_DebugDirectory);
3629+
PE_DebugDirectory dbg_data = {0};
3630+
dmn_process_read_struct(process.dmn_handle, dir_addr, &dbg_data);
3631+
3632+
// rjf: extract external file info from codeview header
3633+
if(dbg_data.type == PE_DebugDirectoryType_CODEVIEW)
36533634
{
3654-
Temp scratch = scratch_begin(0, 0);
3655-
String8List parts = {0};
3656-
for(U64 off = dbg_path_off;; off += 256)
3635+
U32 cv_magic = 0;
3636+
dmn_process_read_struct(process.dmn_handle, vaddr_range.min + dbg_data.voff, &cv_magic);
3637+
switch(cv_magic)
36573638
{
3658-
U8 bytes[256] = {0};
3659-
dmn_process_read(process.dmn_handle, r1u64(vaddr_range.min+off, vaddr_range.min+off+sizeof(bytes)), bytes);
3660-
U64 size = cstring8_length(&bytes[0]);
3661-
String8 part = str8(bytes, size);
3662-
str8_list_push(scratch.arena, &parts, part);
3663-
if(size < sizeof(bytes))
3639+
default:break;
3640+
case PE_CODEVIEW_PDB20_MAGIC:
36643641
{
3665-
break;
3666-
}
3642+
PE_CvHeaderPDB20 cv;
3643+
U64 read_size = dmn_process_read_struct(process.dmn_handle, vaddr_range.min+dbg_data.voff, &cv);
3644+
if(read_size == sizeof(cv))
3645+
{
3646+
pdb_dbg_time = cv.time;
3647+
pdb_dbg_age = cv.age;
3648+
pdb_dbg_path = dmn_process_read_cstring(arena, process.dmn_handle, vaddr_range.min + dbg_data.voff + sizeof(cv));
3649+
}
3650+
}break;
3651+
case PE_CODEVIEW_PDB70_MAGIC:
3652+
{
3653+
PE_CvHeaderPDB70 cv;
3654+
U64 read_size = dmn_process_read_struct(process.dmn_handle, vaddr_range.min + dbg_data.voff, &cv);
3655+
if(read_size == sizeof(cv))
3656+
{
3657+
pdb_dbg_guid = cv.guid;
3658+
pdb_dbg_age = cv.age;
3659+
pdb_dbg_path = dmn_process_read_cstring(arena, process.dmn_handle, vaddr_range.min + dbg_data.voff + sizeof(cv));
3660+
}
3661+
}break;
3662+
case PE_CODEVIEW_RDI_MAGIC:
3663+
{
3664+
PE_CvHeaderRDI cv;
3665+
U64 read_size = dmn_process_read_struct(process.dmn_handle, vaddr_range.min + dbg_data.voff, &cv);
3666+
if(read_size == sizeof(cv))
3667+
{
3668+
rdi_dbg_guid = cv.guid;
3669+
rdi_dbg_path = dmn_process_read_cstring(arena, process.dmn_handle, vaddr_range.min + dbg_data.voff + sizeof(cv));
3670+
}
3671+
}break;
36673672
}
3668-
builtin_debug_info_path = str8_list_join(arena, &parts, 0);
3669-
scratch_end(scratch);
36703673
}
36713674
}
36723675
}
@@ -3676,16 +3679,22 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_
36763679
//////////////////////////////
36773680
//- rjf: pick default initial debug info path
36783681
//
3679-
String8 initial_debug_info_path = builtin_debug_info_path;
3682+
String8 initial_debug_info_path = str8_zero();
36803683
{
36813684
Temp scratch = scratch_begin(0, 0);
36823685
String8 exe_folder = str8_chop_last_slash(path);
3683-
String8 builtin_debug_info_path__absolute = builtin_debug_info_path;
3684-
String8 builtin_debug_info_path__relative = push_str8f(scratch.arena, "%S/%S", exe_folder, builtin_debug_info_path);
3686+
String8 rdi_path__absolute = rdi_dbg_path;
3687+
String8 rdi_path__relative = push_str8f(scratch.arena, "%S/%S", exe_folder, rdi_dbg_path);
3688+
String8 pdb_path__absolute = pdb_dbg_path;
3689+
String8 pdb_path__relative = push_str8f(scratch.arena, "%S/%S", exe_folder, pdb_dbg_path);
36853690
String8 dbg_path_candidates[] =
36863691
{
3687-
/* inferred (treated as relative): */ builtin_debug_info_path__relative,
3688-
/* inferred (treated as absolute): */ builtin_debug_info_path__absolute,
3692+
/* inferred (treated as absolute): */ rdi_path__absolute,
3693+
/* inferred (treated as relative): */ rdi_path__relative,
3694+
/* inferred (treated as absolute): */ pdb_path__absolute,
3695+
/* inferred (treated as relative): */ pdb_path__relative,
3696+
/* "foo.exe" -> "foo.rdi" */ push_str8f(scratch.arena, "%S.rdi", str8_chop_last_dot(path)),
3697+
/* "foo.exe" -> "foo.exe.rdi" */ push_str8f(scratch.arena, "%S.rdi", path),
36893698
/* "foo.exe" -> "foo.pdb" */ push_str8f(scratch.arena, "%S.pdb", str8_chop_last_dot(path)),
36903699
/* "foo.exe" -> "foo.exe.pdb" */ push_str8f(scratch.arena, "%S.pdb", path),
36913700
};

0 commit comments

Comments
 (0)