mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-07-14 05:21:25 -07:00
generate markers from RDI
This commit is contained in:
+108
-9
@@ -255,13 +255,107 @@ rd_marker_is_before(void *a, void *b)
|
||||
return u64_is_before(&((RD_Marker*)a)->off, &((RD_Marker*)b)->off);
|
||||
}
|
||||
|
||||
internal int
|
||||
rd_range_min_is_before(void *raw_a, void *raw_b)
|
||||
{
|
||||
Rng1U64 *a = raw_a;
|
||||
Rng1U64 *b = raw_b;
|
||||
return a->min < b->min;
|
||||
}
|
||||
|
||||
internal U64
|
||||
rd_range_bsearch(Rng1U64 *ranges, U64 count, U64 x)
|
||||
{
|
||||
if (count > 0 && ranges[0].min <= x && x < ranges[count - 1].min) {
|
||||
U64 first = 0;
|
||||
U64 opl = count;
|
||||
for (;;) {
|
||||
U64 mid = (first + opl)/2;
|
||||
if (ranges[mid].min < x) {
|
||||
first = mid;
|
||||
} else if (ranges[mid].min > x) {
|
||||
opl = mid;
|
||||
} else {
|
||||
first = mid;
|
||||
break;
|
||||
}
|
||||
if (opl - first <= 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return first;
|
||||
}
|
||||
return max_U64;
|
||||
}
|
||||
|
||||
internal RD_MarkerArray *
|
||||
rd_section_markers_from_rdi(Arena *arena, RDI_Parsed *rdi)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
|
||||
U64 sect_count = 0;
|
||||
RDI_BinarySection *sect_lo = rdi_table_from_name(rdi, BinarySections, §_count);
|
||||
|
||||
Rng1U64 *sect_vranges = push_array(scratch.arena, Rng1U64, sect_count);
|
||||
for (U64 i = 0; i < sect_count; ++i) {
|
||||
sect_vranges[i].min = sect_lo[i].voff_first;
|
||||
sect_vranges[i].max = i;
|
||||
}
|
||||
radsort(sect_vranges, sect_count, rd_range_min_is_before);
|
||||
|
||||
U64 proc_count = 0;
|
||||
RDI_Procedure *proc_lo = rdi_table_from_name(rdi, Procedures, &proc_count);
|
||||
|
||||
RD_MarkerList *markers = push_array(scratch.arena, RD_MarkerList, sect_count);
|
||||
for (U64 i = 0; i < proc_count; ++i) {
|
||||
RDI_Procedure *proc = proc_lo + i;
|
||||
U64 proc_voff_lo = rdi_first_voff_from_procedure(rdi, proc);
|
||||
U64 proc_voff_hi = rdi_opl_voff_from_procedure(rdi, proc);
|
||||
|
||||
U64 sect_range_idx = rd_range_bsearch(sect_vranges, sect_count, proc_voff_lo);
|
||||
if (sect_range_idx < sect_count) {
|
||||
Rng1U64 sect_range = sect_vranges[sect_range_idx];
|
||||
U64 sect_idx = sect_range.max;
|
||||
|
||||
String8 name = str8_zero();
|
||||
name.str = rdi_name_from_procedure(rdi, proc, &name.size);
|
||||
|
||||
RD_MarkerNode *n = push_array(scratch.arena, RD_MarkerNode, 1);
|
||||
n->v.off = proc_voff_lo - sect_range.min;
|
||||
n->v.string = name;
|
||||
|
||||
RD_MarkerList *list = &markers[sect_idx];
|
||||
SLLQueuePush(list->first, list->last, n);
|
||||
++list->count;
|
||||
}
|
||||
}
|
||||
|
||||
// lists -> arrays
|
||||
RD_MarkerArray *result = push_array(arena, RD_MarkerArray, sect_count);
|
||||
for (U64 i = 0; i < sect_count; ++i) {
|
||||
result[i].count = 0;
|
||||
result[i].v = push_array(arena, RD_Marker, markers[i].count);
|
||||
for (RD_MarkerNode *n = markers[i].first; n != 0; n = n->next) {
|
||||
result[i].v[result[i].count++] = n->v;
|
||||
}
|
||||
}
|
||||
|
||||
// sort arrays
|
||||
for (U64 i = 0; i < sect_count; ++i) {
|
||||
radsort(result[i].v, result[i].count, rd_marker_is_before);
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal RD_MarkerArray *
|
||||
rd_section_markers_from_coff_symbol_table(Arena *arena, String8 raw_data, U64 string_table_off, U64 section_count, COFF_Symbol32Array symbols)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
|
||||
// extract markers from symbol table
|
||||
RD_MarkerList *markers = push_array(scratch.arena, RD_MarkerList, section_count);
|
||||
RD_MarkerList *markers = push_array(scratch.arena, RD_MarkerList, section_count+1);
|
||||
for (U64 symbol_idx = 0; symbol_idx < symbols.count; ++symbol_idx) {
|
||||
COFF_Symbol32 *symbol = &symbols.v[symbol_idx];
|
||||
|
||||
@@ -277,7 +371,7 @@ rd_section_markers_from_coff_symbol_table(Arena *arena, String8 raw_data, U64 st
|
||||
n->v.off = symbol->value;
|
||||
n->v.string = name;
|
||||
|
||||
RD_MarkerList *list = &markers[symbol->section_number-1];
|
||||
RD_MarkerList *list = &markers[symbol->section_number];
|
||||
SLLQueuePush(list->first, list->last, n);
|
||||
++list->count;
|
||||
}
|
||||
@@ -4709,14 +4803,15 @@ coff_disasm_sections(Arena *arena,
|
||||
for (U64 sect_idx = 0; sect_idx < section_count; ++sect_idx) {
|
||||
COFF_SectionHeader *sect = sections+sect_idx;
|
||||
if (sect->flags & COFF_SectionFlag_CNT_CODE) {
|
||||
U64 sect_off = is_obj ? sect->foff : sect->voff;
|
||||
U64 sect_size = is_obj ? sect->fsize : sect->vsize;
|
||||
String8 raw_code = str8_substr(raw_data, rng_1u64(sect->foff, sect->foff+sect_size));
|
||||
RD_MarkerArray markers = section_markers[sect_idx];
|
||||
U64 sect_off = is_obj ? sect->foff : sect->voff;
|
||||
U64 sect_size = is_obj ? sect->fsize : sect->vsize;
|
||||
String8 raw_code = str8_substr(raw_data, rng_1u64(sect->foff, sect->foff+sect_size));
|
||||
U64 sect_number = sect_idx+1;
|
||||
RD_MarkerArray markers = section_markers[sect_number];
|
||||
|
||||
rd_printf("# Disassembly [Section No. %#llx]", (sect_idx+1));
|
||||
rd_printf("# Disassembly [Section No. %#llx]", sect_number);
|
||||
rd_indent();
|
||||
rd_print_disasm(arena, out, indent, machine, image_base, sect_off, markers.count, markers.v, raw_code);
|
||||
rd_print_disasm(arena, out, indent, arch_from_coff_machine(machine), image_base, sect_off, markers.count, markers.v, raw_code);
|
||||
rd_unindent();
|
||||
}
|
||||
}
|
||||
@@ -6796,7 +6891,11 @@ pe_print(Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Op
|
||||
|
||||
RD_MarkerArray *section_markers = 0;
|
||||
if (opts & (RD_Option_Disasm|RD_Option_Rawdata)) {
|
||||
section_markers = rd_section_markers_from_coff_symbol_table(scratch.arena, raw_data, string_table_off, coff_header->section_count, symbols);
|
||||
if (rdi) {
|
||||
section_markers = rd_section_markers_from_rdi(scratch.arena, rdi);
|
||||
} else {
|
||||
section_markers = rd_section_markers_from_coff_symbol_table(scratch.arena, raw_data, string_table_off, coff_header->section_count, symbols);
|
||||
}
|
||||
}
|
||||
|
||||
if (opts & RD_Option_Rawdata) {
|
||||
|
||||
Reference in New Issue
Block a user