plug in dwarf converter to radbin; hook up to both rdi generation & breakpad generation; radbin exe -> pdb / elf -> dwarf inferences; cleanup / unification passes

This commit is contained in:
Ryan Fleury
2025-06-10 08:53:57 -07:00
parent 638adad93b
commit 49de09883e
29 changed files with 1524 additions and 1019 deletions
+39 -60
View File
@@ -543,7 +543,7 @@ pe_bin_info_from_data(Arena *arena, String8 data)
data_dir_count = ClampTop(reported_data_dir_count, data_dir_max);
// rjf: convert PE directories to ranges
data_dir_franges = push_array(arena, Rng1U64, data_dir_count);
data_dir_franges = push_array(arena, Rng1U64, Max(data_dir_count, PE_DataDirectoryIndex_COUNT));
for(U32 dir_idx = 0; dir_idx < data_dir_count; dir_idx += 1)
{
U64 dir_offset = optional_range.min + reported_data_dir_offset + sizeof(PE_DataDirectory)*dir_idx;
@@ -620,87 +620,66 @@ pe_bin_info_from_data(Arena *arena, String8 data)
}
internal PE_DebugInfoList
pe_parse_debug_directory(Arena *arena, String8 raw_image, String8 raw_debug_dir)
pe_debug_info_list_from_raw_debug_dir(Arena *arena, String8 raw_image, String8 raw_debug_dir)
{
PE_DebugInfoList result = {0};
PE_DebugDirectory *debug_entry = str8_deserial_get_raw_ptr(raw_debug_dir, 0, sizeof(*debug_entry));
PE_DebugDirectory *debug_entry_opl = debug_entry + raw_debug_dir.size/sizeof(*debug_entry_opl);
for (PE_DebugDirectory *entry = debug_entry; entry < debug_entry_opl; ++entry) {
switch (entry->type) {
default: {
PE_DebugInfoNode *n = push_array(arena, PE_DebugInfoNode, 1);
n->v.header = *entry;
n->v.u.raw_data = str8_substr(raw_image, rng_1u64(entry->foff, entry->foff + entry->size));
SLLQueuePush(result.first, result.last, n);
++result.count;
} break;
case PE_DebugDirectoryType_CODEVIEW: {
U32 cv_magic = 0;
str8_deserial_read_struct(raw_image, entry->foff, &cv_magic);
switch (cv_magic) {
case PE_CODEVIEW_PDB20_MAGIC: {
for(PE_DebugDirectory *entry = debug_entry; entry < debug_entry_opl; entry += 1)
{
PE_DebugInfoNode *n = push_array(arena, PE_DebugInfoNode, 1);
SLLQueuePush(result.first, result.last, n);
result.count += 1;
n->v.header = *entry;
switch(entry->type)
{
default:{}break;
case PE_DebugDirectoryType_CODEVIEW:
{
str8_deserial_read_struct(raw_image, entry->foff, &n->v.cv_magic);
switch(n->v.cv_magic)
{
case PE_CODEVIEW_PDB20_MAGIC:
{
PE_CvHeaderPDB20 cv = {0};
U64 cv_read_size = str8_deserial_read_struct(raw_image, entry->foff, &cv);
if (cv_read_size == sizeof(cv)) {
if(cv_read_size == sizeof(cv))
{
String8 path = {0};
str8_deserial_read_cstr(raw_image, entry->foff+sizeof(cv), &path);
PE_DebugInfoNode *n = push_array(arena, PE_DebugInfoNode, 1);
n->v.header = *entry;
n->v.u.codeview.pdb20.header = cv;
n->v.u.codeview.pdb20.path = path;
SLLQueuePush(result.first, result.last, n);
++result.count;
} else {
Assert(!"unable to read PE_CvHeaderPDB20");
n->v.cv_pdb20_header = cv;
n->v.path = path;
}
} break;
case PE_CODEVIEW_PDB70_MAGIC: {
}break;
case PE_CODEVIEW_PDB70_MAGIC:
{
PE_CvHeaderPDB70 cv = {0};
U64 cv_read_size = str8_deserial_read_struct(raw_image, entry->foff, &cv);
if (cv_read_size == sizeof(cv)) {
if(cv_read_size == sizeof(cv))
{
String8 path = {0};
str8_deserial_read_cstr(raw_image, entry->foff+sizeof(cv), &path);
PE_DebugInfoNode *n = push_array(arena, PE_DebugInfoNode, 1);
n->v.header = *entry;
n->v.u.codeview.pdb70.header = cv;
n->v.u.codeview.pdb70.path = path;
SLLQueuePush(result.first, result.last, n);
++result.count;
} else {
Assert(!"unable to read PE_CvHeaderPDB70");
n->v.cv_pdb70_header = cv;
n->v.path = path;
}
} break;
case PE_CODEVIEW_RDI_MAGIC: {
}break;
case PE_CODEVIEW_RDI_MAGIC:
{
PE_CvHeaderRDI cv = {0};
U64 cv_read_size = str8_deserial_read_struct(raw_image, entry->foff, &cv);
if (cv_read_size == sizeof(cv)) {
if(cv_read_size == sizeof(cv))
{
String8 path = {0};
str8_deserial_read_cstr(raw_image, entry->foff+sizeof(cv), &path);
PE_DebugInfoNode *n = push_array(arena, PE_DebugInfoNode, 1);
n->v.header = *entry;
n->v.u.codeview.rdi.header = cv;
n->v.u.codeview.rdi.path = path;
SLLQueuePush(result.first, result.last, n);
++result.count;
} else {
Assert(!"unable to read PE_CvHeaderRDI");
n->v.cv_rdi_header = cv;
n->v.path = path;
}
} break;
default: break;
}break;
default:{}break;
}
} break;
}break;
}
}
return result;
}
+8 -25
View File
@@ -1012,30 +1012,13 @@ struct PE_BinInfo
typedef struct PE_DebugInfo
{
PE_DebugDirectory header;
union
{
union
{
U32 magic;
struct
{
PE_CvHeaderPDB20 header;
String8 path;
} pdb20;
struct
{
PE_CvHeaderPDB70 header;
String8 path;
} pdb70;
struct
{
PE_CvHeaderRDI header;
String8 path;
} rdi;
} codeview;
String8 raw_data;
} u;
} PE_DebugInfo;
U32 cv_magic;
PE_CvHeaderPDB20 cv_pdb20_header;
PE_CvHeaderPDB70 cv_pdb70_header;
PE_CvHeaderRDI cv_rdi_header;
String8 path;
}
PE_DebugInfo;
typedef struct PE_DebugInfoNode
{
@@ -1075,7 +1058,7 @@ internal String8 pe_string_from_dll_characteristics(Arena *arena, PE_DllCharacte
internal B32 pe_check_magic(String8 data);
internal PE_BinInfo pe_bin_info_from_data(Arena *arena, String8 data);
internal PE_DebugInfoList pe_parse_debug_directory(Arena *arena, String8 raw_image, String8 raw_debug_dir);
internal PE_DebugInfoList pe_debug_info_list_from_raw_debug_dir(Arena *arena, String8 raw_image, String8 raw_debug_dir);
internal PE_ParsedStaticImportTable pe_static_imports_from_data(Arena *arena, B32 is_pe32, U64 section_count, COFF_SectionHeader *sections, String8 raw_data, Rng1U64 dir_file_range);
internal PE_ParsedDelayImportTable pe_delay_imports_from_data(Arena *arena, B32 is_pe32, U64 section_count, COFF_SectionHeader *sections, String8 raw_data, Rng1U64 dir_file_range);
internal PE_ParsedExportTable pe_exports_from_data(Arena *arena, U64 section_count, COFF_SectionHeader *sections, String8 raw_data, Rng1U64 dir_file_range, Rng1U64 dir_virt_range);