mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 17:28:07 +00:00
test DWARF32 and DWARF64 unit encodings
This commit is contained in:
@@ -300,6 +300,12 @@ memory_write32(void *ptr, U32 v)
|
||||
MemoryCopy(ptr, &v, sizeof(v));
|
||||
}
|
||||
|
||||
internal void UBSAN_NO_ALIGN
|
||||
memory_write64(void *ptr, U64 v)
|
||||
{
|
||||
MemoryCopy(ptr, &v, sizeof(v));
|
||||
}
|
||||
|
||||
internal U8 UBSAN_NO_ALIGN
|
||||
memory_read8(void *ptr)
|
||||
{
|
||||
|
||||
@@ -1011,6 +1011,7 @@ internal B32 memory_is_zero(void *ptr, U64 size);
|
||||
|
||||
internal void memory_write16(void *ptr, U16 v);
|
||||
internal void memory_write32(void *ptr, U32 v);
|
||||
internal void memory_write64(void *ptr, U64 v);
|
||||
|
||||
internal U8 memory_read8(void *ptr);
|
||||
internal U16 memory_read16(void *ptr);
|
||||
|
||||
@@ -29,7 +29,6 @@ typedef enum DW_ExtEnum
|
||||
DW_Ext_All = DW_Ext_GNU|DW_Ext_LLVM|DW_Ext_APPLE|DW_Ext_MIPS,
|
||||
} DW_ExtEnum;
|
||||
|
||||
#define DW_FormatFromSize(size) ((size) >= max_U32 ? DW_Format_64Bit : DW_Format_32Bit)
|
||||
typedef enum DW_Format
|
||||
{
|
||||
DW_Format_Null,
|
||||
|
||||
@@ -35,7 +35,7 @@ dw_input_from_coff_section_table(Arena *arena,
|
||||
|
||||
for (U64 i = 0; i < section_count; ++i) {
|
||||
COFF_SectionHeader *header = §ion_table[i];
|
||||
Rng1U64 raw_data_range = rng_1u64(header->foff, header->foff + header->fsize);
|
||||
Rng1U64 raw_data_range = rng_1u64(header->foff, header->vsize ? header->foff + header->vsize : header->foff + header->fsize);
|
||||
String8 name = coff_name_from_section_header(string_table, header);
|
||||
|
||||
DW_SectionKind s = dw_section_kind_from_string(name);
|
||||
|
||||
+29
-11
@@ -12,13 +12,14 @@ internal U64
|
||||
str8_deserial_read_dwarf_packed_size(String8 string, U64 off, U64 *size_out)
|
||||
{
|
||||
U64 bytes_read = 0;
|
||||
if (str8_deserial_read(string, off, size_out, sizeof(U32), sizeof(U32))) {
|
||||
if (*size_out == max_U32) {
|
||||
if (str8_deserial_read_struct(string, off+sizeof(U32), size_out)) {
|
||||
U32 first_four_bytes;
|
||||
if (str8_deserial_read_struct(string, off, &first_four_bytes) == sizeof(first_four_bytes)) {
|
||||
if (first_four_bytes == max_U32) {
|
||||
if (str8_deserial_read_struct(string, off+sizeof(U32), size_out) == sizeof(U64)) {
|
||||
bytes_read = sizeof(U32) + sizeof(U64);
|
||||
}
|
||||
} else {
|
||||
*size_out &= (U64)max_U32;
|
||||
*size_out = first_four_bytes;
|
||||
bytes_read = sizeof(U32);
|
||||
}
|
||||
}
|
||||
@@ -273,6 +274,10 @@ internal U64
|
||||
dw_read_list_unit_header_str_offsets(String8 unit_data, DW_ListUnit *lu_out)
|
||||
{
|
||||
U64 header_size = 0;
|
||||
|
||||
U32 first_four_bytes = 0;
|
||||
if (str8_deserial_read_struct(unit_data, 0, &first_four_bytes) != sizeof(first_four_bytes)) { goto exit; }
|
||||
DW_Format format = first_four_bytes == max_U32 ? DW_Format_64Bit : DW_Format_32Bit;
|
||||
|
||||
U64 unit_length = 0;
|
||||
U64 unit_length_size = str8_deserial_read_dwarf_packed_size(unit_data, 0, &unit_length);
|
||||
@@ -291,12 +296,13 @@ dw_read_list_unit_header_str_offsets(String8 unit_data, DW_ListUnit *lu_out)
|
||||
lu_out->version = version;
|
||||
lu_out->address_size = 0;
|
||||
lu_out->segment_selector_size = 0;
|
||||
lu_out->entry_size = dw_size_from_format(DW_FormatFromSize(unit_length));
|
||||
lu_out->entry_size = dw_size_from_format(format);
|
||||
lu_out->entries = str8_skip(unit_data, header_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit:;
|
||||
return header_size;
|
||||
}
|
||||
|
||||
@@ -304,6 +310,10 @@ internal U64
|
||||
dw_read_list_unit_header_list(String8 unit_data, DW_ListUnit *lu_out)
|
||||
{
|
||||
U64 header_size = 0;
|
||||
|
||||
U32 first_four_bytes = 0;
|
||||
if (str8_deserial_read_struct(unit_data, 0, &first_four_bytes) != sizeof(first_four_bytes)) { goto exit; }
|
||||
DW_Format format = first_four_bytes == max_U32 ? DW_Format_64Bit : DW_Format_32Bit;
|
||||
|
||||
U64 unit_length = 0;
|
||||
U64 unit_length_size = str8_deserial_read_dwarf_packed_size(unit_data, 0, &unit_length);
|
||||
@@ -330,7 +340,7 @@ dw_read_list_unit_header_list(String8 unit_data, DW_ListUnit *lu_out)
|
||||
lu_out->version = version;
|
||||
lu_out->address_size = address_size;
|
||||
lu_out->segment_selector_size = segment_selector_size;
|
||||
lu_out->entry_size = dw_size_from_format(DW_FormatFromSize(unit_length));
|
||||
lu_out->entry_size = dw_size_from_format(format);
|
||||
lu_out->entries = str8_skip(unit_data, header_size);
|
||||
}
|
||||
}
|
||||
@@ -338,6 +348,7 @@ dw_read_list_unit_header_list(String8 unit_data, DW_ListUnit *lu_out)
|
||||
}
|
||||
}
|
||||
|
||||
exit:;
|
||||
return header_size;
|
||||
}
|
||||
|
||||
@@ -1972,6 +1983,10 @@ internal DW_CompUnit
|
||||
dw_cu_from_info_off(Arena *arena, DW_Input *input, DW_ListUnitInput lu_input, U64 cu_header_offset, B32 relaxed)
|
||||
{
|
||||
DW_CompUnit cu = {0};
|
||||
|
||||
U32 first_four_bytes = 0;
|
||||
if (str8_deserial_read_struct(input->sec[DW_Section_Info].data, 0, &first_four_bytes) != sizeof(first_four_bytes)) { goto exit; }
|
||||
DW_Format format = first_four_bytes == max_U32 ? DW_Format_64Bit : DW_Format_32Bit;
|
||||
|
||||
// read unit size in bytes
|
||||
U64 length = 0;
|
||||
@@ -1987,7 +2002,6 @@ dw_cu_from_info_off(Arena *arena, DW_Input *input, DW_ListUnitInput lu_input, U6
|
||||
DW_Version version;
|
||||
TryRead(str8_deserial_read_struct(info, info_cursor, &version), info_cursor, exit);
|
||||
|
||||
DW_Format format = DW_FormatFromSize(length);
|
||||
U64 abbrev_base = max_U64;
|
||||
U8 address_size = 0;
|
||||
DW_CompUnitKind unit_kind = DW_CompUnitKind_Reserved;
|
||||
@@ -2202,11 +2216,14 @@ dw_read_line_vm_header(Arena *arena,
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
|
||||
U32 first_four_bytes = 0;
|
||||
if (str8_deserial_read_struct(cu_stmt_list, 0, &first_four_bytes) != sizeof(U32)) { goto exit; }
|
||||
|
||||
// read unit length
|
||||
U64 length = 0;
|
||||
U64 length_size = str8_deserial_read_dwarf_packed_size(cu_stmt_list, 0, &length);
|
||||
|
||||
DW_Format format = DW_FormatFromSize(length);
|
||||
DW_Format format = first_four_bytes == max_U32 ? DW_Format_64Bit : DW_Format_32Bit;
|
||||
U64 cursor = length_size;
|
||||
String8 data = str8_substr(cu_stmt_list, r1u64(0, length + length_size));
|
||||
|
||||
@@ -2723,7 +2740,10 @@ dw_v4_pub_strings_table_from_section_kind(Arena *arena, DW_Input *input, DW_Sect
|
||||
|
||||
String8 section_data = input->sec[section_kind].data;
|
||||
for(U64 cursor = 0; cursor < section_data.size; ) {
|
||||
|
||||
U32 first_four_bytes = 0;
|
||||
if (str8_deserial_read_struct(input->sec[DW_Section_Info].data, 0, &first_four_bytes) != sizeof(first_four_bytes)) { break; }
|
||||
DW_Format format = first_four_bytes == max_U32 ? DW_Format_64Bit : DW_Format_32Bit;
|
||||
|
||||
U64 unit_length = 0;
|
||||
U64 unit_length_size = str8_deserial_read_dwarf_packed_size(section_data, cursor, &unit_length);
|
||||
if (unit_length_size == 0) {
|
||||
@@ -2742,8 +2762,6 @@ dw_v4_pub_strings_table_from_section_kind(Arena *arena, DW_Input *input, DW_Sect
|
||||
break;
|
||||
}
|
||||
|
||||
DW_Format format = DW_FormatFromSize(unit_length);
|
||||
|
||||
U64 debug_info_off = 0;
|
||||
cursor += str8_deserial_read_dwarf_uint(section_data, cursor, format, &debug_info_off);
|
||||
if (cursor >= cursor_opl) {
|
||||
|
||||
@@ -1212,15 +1212,15 @@ dw_writer_emit(DW_Writer *writer)
|
||||
for EachElement(i, writer->sections) {
|
||||
if (writer->sections[i].length) {
|
||||
if (writer->format == DW_Format_64Bit) {
|
||||
U64 *length = writer->sections[i].length;
|
||||
U64 *length = (U64 *)((U8 *)writer->sections[i].length + sizeof(U32));
|
||||
U64 length_size = sizeof(U64) + sizeof(U32);
|
||||
Assert(writer->sections[i].srl.total_size >= length_size);
|
||||
*length = writer->sections[i].srl.total_size - length_size;
|
||||
memory_write64(length, writer->sections[i].srl.total_size - length_size);
|
||||
} else {
|
||||
U32 *length = writer->sections[i].length;
|
||||
U32 length_size = sizeof(U32);
|
||||
Assert(writer->sections[i].srl.total_size >= length_size);
|
||||
*length = safe_cast_u32(writer->sections[i].srl.total_size - length_size);
|
||||
memory_write32(length, safe_cast_u32(writer->sections[i].srl.total_size - length_size));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,6 +135,64 @@ dw_input_from_writer(Arena *arena, DW_Writer *writer)
|
||||
return input;
|
||||
}
|
||||
|
||||
T_BeginTest(dwarf_32bit)
|
||||
{
|
||||
DW_Writer *writer = dw_writer_begin(DW_Format_32Bit, DW_Version_5, DW_CompUnitKind_Compile, Arch_x64);
|
||||
dw_writer_tag_begin(writer, DW_TagKind_CompileUnit);
|
||||
dw_writer_push_attrib_string(writer, DW_AttribKind_Producer, str8_lit("RAD DWARF WRITER"));
|
||||
dw_writer_tag_end(writer);
|
||||
|
||||
DW_Input input = dw_input_from_writer(scratch.arena, writer);
|
||||
|
||||
for EachElement(sec_idx, input.sec) {
|
||||
if (sec_idx == DW_Section_Abbrev) continue;
|
||||
Rng1U64Array unit_ranges = dw_unit_ranges_from_data_arr(scratch.arena, input.sec[sec_idx].data);
|
||||
for EachIndex(range_idx, unit_ranges.count) {
|
||||
Rng1U64 range = unit_ranges.v[range_idx];
|
||||
|
||||
U32 first_four_bytes = 0;
|
||||
T_Ok(str8_deserial_read_struct(input.sec[sec_idx].data, range.min, &first_four_bytes) == sizeof(first_four_bytes));
|
||||
T_Ok(first_four_bytes + 4 == dim_1u64(range));
|
||||
|
||||
U32 unit_length = 0;
|
||||
T_Ok(str8_deserial_read_struct(input.sec[sec_idx].data, range.min, &unit_length) == sizeof(U32));
|
||||
T_Ok(unit_length + 4 == dim_1u64(range));
|
||||
}
|
||||
}
|
||||
|
||||
dw_writer_end(&writer);
|
||||
}
|
||||
T_EndTest;
|
||||
|
||||
T_BeginTest(dwarf_64bit)
|
||||
{
|
||||
DW_Writer *writer = dw_writer_begin(DW_Format_64Bit, DW_Version_5, DW_CompUnitKind_Compile, Arch_x64);
|
||||
dw_writer_tag_begin(writer, DW_TagKind_CompileUnit);
|
||||
dw_writer_push_attrib_string(writer, DW_AttribKind_Producer, str8_lit("RAD DWARF WRITER"));
|
||||
dw_writer_tag_end(writer);
|
||||
|
||||
DW_Input input = dw_input_from_writer(scratch.arena, writer);
|
||||
|
||||
for EachElement(sec_idx, input.sec) {
|
||||
if (sec_idx == DW_Section_Abbrev) continue;
|
||||
Rng1U64Array unit_ranges = dw_unit_ranges_from_data_arr(scratch.arena, input.sec[sec_idx].data);
|
||||
for EachIndex(range_idx, unit_ranges.count) {
|
||||
Rng1U64 range = unit_ranges.v[range_idx];
|
||||
|
||||
U32 first_four_bytes = 0;
|
||||
T_Ok(str8_deserial_read_struct(input.sec[sec_idx].data, range.min, &first_four_bytes) == sizeof(first_four_bytes));
|
||||
T_Ok(first_four_bytes == max_U32);
|
||||
|
||||
U64 unit_length = 0;
|
||||
T_Ok(str8_deserial_read_struct(input.sec[sec_idx].data, range.min + sizeof(U32), &unit_length) == sizeof(U64));
|
||||
T_Ok(unit_length + 12 == dim_1u64(range));
|
||||
}
|
||||
}
|
||||
|
||||
dw_writer_end(&writer);
|
||||
}
|
||||
T_EndTest;
|
||||
|
||||
T_BeginTest(dwarf_line_opcodes)
|
||||
{
|
||||
DW_Writer *writer = dw_writer_begin(DW_Format_32Bit, DW_Version_5, DW_CompUnitKind_Compile, Arch_x64);
|
||||
@@ -574,7 +632,6 @@ T_BeginTest(dwarf_writer)
|
||||
DW_TagTree tag_tree = dw_tag_tree_from_cu(scratch.arena, &input, &cu);
|
||||
AssertAlways(dwt_tags_must_match(writer->root, tag_tree.root));
|
||||
|
||||
|
||||
// validate the writer
|
||||
|
||||
T_Ok(writer->current == 0);
|
||||
|
||||
Reference in New Issue
Block a user