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));
|
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
|
internal U8 UBSAN_NO_ALIGN
|
||||||
memory_read8(void *ptr)
|
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_write16(void *ptr, U16 v);
|
||||||
internal void memory_write32(void *ptr, U32 v);
|
internal void memory_write32(void *ptr, U32 v);
|
||||||
|
internal void memory_write64(void *ptr, U64 v);
|
||||||
|
|
||||||
internal U8 memory_read8(void *ptr);
|
internal U8 memory_read8(void *ptr);
|
||||||
internal U16 memory_read16(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_Ext_All = DW_Ext_GNU|DW_Ext_LLVM|DW_Ext_APPLE|DW_Ext_MIPS,
|
||||||
} DW_ExtEnum;
|
} DW_ExtEnum;
|
||||||
|
|
||||||
#define DW_FormatFromSize(size) ((size) >= max_U32 ? DW_Format_64Bit : DW_Format_32Bit)
|
|
||||||
typedef enum DW_Format
|
typedef enum DW_Format
|
||||||
{
|
{
|
||||||
DW_Format_Null,
|
DW_Format_Null,
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ dw_input_from_coff_section_table(Arena *arena,
|
|||||||
|
|
||||||
for (U64 i = 0; i < section_count; ++i) {
|
for (U64 i = 0; i < section_count; ++i) {
|
||||||
COFF_SectionHeader *header = §ion_table[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);
|
String8 name = coff_name_from_section_header(string_table, header);
|
||||||
|
|
||||||
DW_SectionKind s = dw_section_kind_from_string(name);
|
DW_SectionKind s = dw_section_kind_from_string(name);
|
||||||
|
|||||||
+28
-10
@@ -12,13 +12,14 @@ internal U64
|
|||||||
str8_deserial_read_dwarf_packed_size(String8 string, U64 off, U64 *size_out)
|
str8_deserial_read_dwarf_packed_size(String8 string, U64 off, U64 *size_out)
|
||||||
{
|
{
|
||||||
U64 bytes_read = 0;
|
U64 bytes_read = 0;
|
||||||
if (str8_deserial_read(string, off, size_out, sizeof(U32), sizeof(U32))) {
|
U32 first_four_bytes;
|
||||||
if (*size_out == max_U32) {
|
if (str8_deserial_read_struct(string, off, &first_four_bytes) == sizeof(first_four_bytes)) {
|
||||||
if (str8_deserial_read_struct(string, off+sizeof(U32), size_out)) {
|
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);
|
bytes_read = sizeof(U32) + sizeof(U64);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*size_out &= (U64)max_U32;
|
*size_out = first_four_bytes;
|
||||||
bytes_read = sizeof(U32);
|
bytes_read = sizeof(U32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -274,6 +275,10 @@ dw_read_list_unit_header_str_offsets(String8 unit_data, DW_ListUnit *lu_out)
|
|||||||
{
|
{
|
||||||
U64 header_size = 0;
|
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 = 0;
|
||||||
U64 unit_length_size = str8_deserial_read_dwarf_packed_size(unit_data, 0, &unit_length);
|
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->version = version;
|
||||||
lu_out->address_size = 0;
|
lu_out->address_size = 0;
|
||||||
lu_out->segment_selector_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);
|
lu_out->entries = str8_skip(unit_data, header_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exit:;
|
||||||
return header_size;
|
return header_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,6 +311,10 @@ dw_read_list_unit_header_list(String8 unit_data, DW_ListUnit *lu_out)
|
|||||||
{
|
{
|
||||||
U64 header_size = 0;
|
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 = 0;
|
||||||
U64 unit_length_size = str8_deserial_read_dwarf_packed_size(unit_data, 0, &unit_length);
|
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->version = version;
|
||||||
lu_out->address_size = address_size;
|
lu_out->address_size = address_size;
|
||||||
lu_out->segment_selector_size = segment_selector_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);
|
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;
|
return header_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1973,6 +1984,10 @@ dw_cu_from_info_off(Arena *arena, DW_Input *input, DW_ListUnitInput lu_input, U6
|
|||||||
{
|
{
|
||||||
DW_CompUnit cu = {0};
|
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
|
// read unit size in bytes
|
||||||
U64 length = 0;
|
U64 length = 0;
|
||||||
U64 length_size = str8_deserial_read_dwarf_packed_size(input->sec[DW_Section_Info].data, cu_header_offset, &length);
|
U64 length_size = str8_deserial_read_dwarf_packed_size(input->sec[DW_Section_Info].data, cu_header_offset, &length);
|
||||||
@@ -1987,7 +2002,6 @@ dw_cu_from_info_off(Arena *arena, DW_Input *input, DW_ListUnitInput lu_input, U6
|
|||||||
DW_Version version;
|
DW_Version version;
|
||||||
TryRead(str8_deserial_read_struct(info, info_cursor, &version), info_cursor, exit);
|
TryRead(str8_deserial_read_struct(info, info_cursor, &version), info_cursor, exit);
|
||||||
|
|
||||||
DW_Format format = DW_FormatFromSize(length);
|
|
||||||
U64 abbrev_base = max_U64;
|
U64 abbrev_base = max_U64;
|
||||||
U8 address_size = 0;
|
U8 address_size = 0;
|
||||||
DW_CompUnitKind unit_kind = DW_CompUnitKind_Reserved;
|
DW_CompUnitKind unit_kind = DW_CompUnitKind_Reserved;
|
||||||
@@ -2202,11 +2216,14 @@ dw_read_line_vm_header(Arena *arena,
|
|||||||
{
|
{
|
||||||
Temp scratch = scratch_begin(&arena, 1);
|
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
|
// read unit length
|
||||||
U64 length = 0;
|
U64 length = 0;
|
||||||
U64 length_size = str8_deserial_read_dwarf_packed_size(cu_stmt_list, 0, &length);
|
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;
|
U64 cursor = length_size;
|
||||||
String8 data = str8_substr(cu_stmt_list, r1u64(0, length + length_size));
|
String8 data = str8_substr(cu_stmt_list, r1u64(0, length + length_size));
|
||||||
|
|
||||||
@@ -2723,6 +2740,9 @@ dw_v4_pub_strings_table_from_section_kind(Arena *arena, DW_Input *input, DW_Sect
|
|||||||
|
|
||||||
String8 section_data = input->sec[section_kind].data;
|
String8 section_data = input->sec[section_kind].data;
|
||||||
for(U64 cursor = 0; cursor < section_data.size; ) {
|
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 = 0;
|
||||||
U64 unit_length_size = str8_deserial_read_dwarf_packed_size(section_data, cursor, &unit_length);
|
U64 unit_length_size = str8_deserial_read_dwarf_packed_size(section_data, cursor, &unit_length);
|
||||||
@@ -2742,8 +2762,6 @@ dw_v4_pub_strings_table_from_section_kind(Arena *arena, DW_Input *input, DW_Sect
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DW_Format format = DW_FormatFromSize(unit_length);
|
|
||||||
|
|
||||||
U64 debug_info_off = 0;
|
U64 debug_info_off = 0;
|
||||||
cursor += str8_deserial_read_dwarf_uint(section_data, cursor, format, &debug_info_off);
|
cursor += str8_deserial_read_dwarf_uint(section_data, cursor, format, &debug_info_off);
|
||||||
if (cursor >= cursor_opl) {
|
if (cursor >= cursor_opl) {
|
||||||
|
|||||||
@@ -1212,15 +1212,15 @@ dw_writer_emit(DW_Writer *writer)
|
|||||||
for EachElement(i, writer->sections) {
|
for EachElement(i, writer->sections) {
|
||||||
if (writer->sections[i].length) {
|
if (writer->sections[i].length) {
|
||||||
if (writer->format == DW_Format_64Bit) {
|
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);
|
U64 length_size = sizeof(U64) + sizeof(U32);
|
||||||
Assert(writer->sections[i].srl.total_size >= length_size);
|
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 {
|
} else {
|
||||||
U32 *length = writer->sections[i].length;
|
U32 *length = writer->sections[i].length;
|
||||||
U32 length_size = sizeof(U32);
|
U32 length_size = sizeof(U32);
|
||||||
Assert(writer->sections[i].srl.total_size >= length_size);
|
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;
|
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)
|
T_BeginTest(dwarf_line_opcodes)
|
||||||
{
|
{
|
||||||
DW_Writer *writer = dw_writer_begin(DW_Format_32Bit, DW_Version_5, DW_CompUnitKind_Compile, Arch_x64);
|
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);
|
DW_TagTree tag_tree = dw_tag_tree_from_cu(scratch.arena, &input, &cu);
|
||||||
AssertAlways(dwt_tags_must_match(writer->root, tag_tree.root));
|
AssertAlways(dwt_tags_must_match(writer->root, tag_tree.root));
|
||||||
|
|
||||||
|
|
||||||
// validate the writer
|
// validate the writer
|
||||||
|
|
||||||
T_Ok(writer->current == 0);
|
T_Ok(writer->current == 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user