~laumann/hadb

d608ee41924ee497c02590ed729cc8c9f607382f — Thomas Bracht Laumann Jespersen 4 months ago 31d85f2
format/dwarf: add another test for decodeabbrev
2 files changed, 93 insertions(+), 69 deletions(-)

M format/dwarf/abbrev.ha
M format/dwarf/debuginfo.ha
M format/dwarf/abbrev.ha => format/dwarf/abbrev.ha +93 -0
@@ 6,6 6,7 @@
// Ref: https://wiki.osdev.org/DWARF#The_.debug_abbrev_section
// DWARF 5, Section 7.5.3 (page 203)

// Free a list of abbrevs
export fn freeabbrevs(abbrevs: []abbrev) void = {
	for (let i = 0z; i < len(abbrevs); i += 1)
		free(abbrevs[i].attrs);


@@ 14,6 15,7 @@ export fn freeabbrevs(abbrevs: []abbrev) void = {

// Returns abbreviations in a list, but references to .debug_str are
// not resolved. The caller must free the return value.
//
export fn decodeabbrev(input: []u8) (([]abbrev, size) | partialread) = {
	// .debug_abbrev is a series of abbreviation declarations
	// each declaration specifies tag and attributes for a


@@ 134,3 136,94 @@ export fn decodeabbrev(input: []u8) (([]abbrev, size) | partialread) = {
	};
};

@test fn larger() void = {
	const bin: []u8 = [
		0x01, 0x11, 0x01, 0x25, 0x0e, 0x13, 0x0b, 0x03,
		0x0e, 0x1b, 0x0e, 0x11, 0x01, 0x12, 0x01, 0x10,
		0x06, 0x00, 0x00, 0x02, 0x2e, 0x01, 0x3f, 0x0c,
		0x03, 0x0e, 0x3a, 0x0b, 0x3b, 0x0b, 0x39, 0x0b, 
		0x49, 0x13, 0x11, 0x01, 0x12, 0x01, 0x40, 0x06,
		0x96, 0x42, 0x0c, 0x01, 0x13, 0x00, 0x00, 0x03,
		0x34, 0x00, 0x03, 0x08, 0x3a, 0x0b, 0x3b, 0x0b,
		0x39, 0x0b, 0x49, 0x13, 0x02, 0x0a, 0x00, 0x00,
		0x04, 0x24, 0x00, 0x0b, 0x0b, 0x3e, 0x0b, 0x03,
		0x08, 0x00, 0x00, 0x05, 0x24, 0x00, 0x0b, 0x0b,
		0x3e, 0x0b, 0x03, 0x0e, 0x00, 0x00, 0x06, 0x2e,
		0x01, 0x3f, 0x0c, 0x03, 0x0e, 0x3a, 0x0b, 0x3b,
		0x0b, 0x39, 0x0b, 0x49, 0x13, 0x11, 0x01, 0x12,
		0x01, 0x40, 0x06, 0x97, 0x42, 0x0c, 0x00, 0x00,
		0x00,
	];
	let (abbrevs, read) = decodeabbrev(bin)!;
	defer freeabbrevs(abbrevs);
	assert(read == len(bin));
	assert(len(abbrevs) == 6);
};

// readelf --debug-dump=abbrev --hex-dump=.debug_abbrev simple
//
// Hex dump of section '.debug_abbrev':
//   0x00000000 01110125 0e130b03 0e1b0e11 01120110 ...%............
//   0x00000010 06000002 2e013f0c 030e3a0b 3b0b390b ......?...:.;.9.
//   0x00000020 49131101 12014006 96420c01 13000003 I.....@..B......
//   0x00000030 34000308 3a0b3b0b 390b4913 020a0000 4...:.;.9.I.....
//   0x00000040 0424000b 0b3e0b03 08000005 24000b0b .$...>......$...
//   0x00000050 3e0b030e 0000062e 013f0c03 0e3a0b3b >........?...:.;
//   0x00000060 0b390b49 13110112 01400697 420c0000 .9.I.....@..B...
//   0x00000070 00                                  .

// Contents of the .debug_abbrev section:

//   Number TAG (0x0)
//    1      DW_TAG_compile_unit    [has children]
//     DW_AT_producer     DW_FORM_strp
//     DW_AT_language     DW_FORM_data1
//     DW_AT_name         DW_FORM_strp
//     DW_AT_comp_dir     DW_FORM_strp
//     DW_AT_low_pc       DW_FORM_addr
//     DW_AT_high_pc      DW_FORM_addr
//     DW_AT_stmt_list    DW_FORM_data4
//     DW_AT value: 0     DW_FORM value: 0
//    2      DW_TAG_subprogram    [has children]
//     DW_AT_external     DW_FORM_flag
//     DW_AT_name         DW_FORM_strp
//     DW_AT_decl_file    DW_FORM_data1
//     DW_AT_decl_line    DW_FORM_data1
//     DW_AT_decl_column  DW_FORM_data1
//     DW_AT_type         DW_FORM_ref4
//     DW_AT_low_pc       DW_FORM_addr
//     DW_AT_high_pc      DW_FORM_addr
//     DW_AT_frame_base   DW_FORM_data4
//     DW_AT_GNU_all_tail_call_sites DW_FORM_flag
//     DW_AT_sibling      DW_FORM_ref4
//     DW_AT value: 0     DW_FORM value: 0
//    3      DW_TAG_variable    [no children]
//     DW_AT_name         DW_FORM_string
//     DW_AT_decl_file    DW_FORM_data1
//     DW_AT_decl_line    DW_FORM_data1
//     DW_AT_decl_column  DW_FORM_data1
//     DW_AT_type         DW_FORM_ref4
//     DW_AT_location     DW_FORM_block1
//     DW_AT value: 0     DW_FORM value: 0
//    4      DW_TAG_base_type    [no children]
//     DW_AT_byte_size    DW_FORM_data1
//     DW_AT_encoding     DW_FORM_data1
//     DW_AT_name         DW_FORM_string
//     DW_AT value: 0     DW_FORM value: 0
//    5      DW_TAG_base_type    [no children]
//     DW_AT_byte_size    DW_FORM_data1
//     DW_AT_encoding     DW_FORM_data1
//     DW_AT_name         DW_FORM_strp
//     DW_AT value: 0     DW_FORM value: 0
//    6      DW_TAG_subprogram    [has children]
//     DW_AT_external     DW_FORM_flag
//     DW_AT_name         DW_FORM_strp
//     DW_AT_decl_file    DW_FORM_data1
//     DW_AT_decl_line    DW_FORM_data1
//     DW_AT_decl_column  DW_FORM_data1
//     DW_AT_type         DW_FORM_ref4
//     DW_AT_low_pc       DW_FORM_addr
//     DW_AT_high_pc      DW_FORM_addr
//     DW_AT_frame_base   DW_FORM_data4
//     DW_AT_GNU_all_call_sites DW_FORM_flag
//     DW_AT value: 0     DW_FORM value: 0

M format/dwarf/debuginfo.ha => format/dwarf/debuginfo.ha +0 -69
@@ 27,75 27,6 @@ export type abbrev = struct {
	attrs: [](attr, form),
};

// FIXME: Convert the following hex to a proper unit test
// readelf --debug-dump=abbrev --hex-dump=.debug_abbrev simple
//
// Hex dump of section '.debug_abbrev':
//   0x00000000 01110125 0e130b03 0e1b0e11 01120110 ...%............
//   0x00000010 06000002 2e013f0c 030e3a0b 3b0b390b ......?...:.;.9.
//   0x00000020 49131101 12014006 96420c01 13000003 I.....@..B......
//   0x00000030 34000308 3a0b3b0b 390b4913 020a0000 4...:.;.9.I.....
//   0x00000040 0424000b 0b3e0b03 08000005 24000b0b .$...>......$...
//   0x00000050 3e0b030e 0000062e 013f0c03 0e3a0b3b >........?...:.;
//   0x00000060 0b390b49 13110112 01400697 420c0000 .9.I.....@..B...
//   0x00000070 00                                  .

// Contents of the .debug_abbrev section:

//   Number TAG (0x0)
//    1      DW_TAG_compile_unit    [has children]
//     DW_AT_producer     DW_FORM_strp
//     DW_AT_language     DW_FORM_data1
//     DW_AT_name         DW_FORM_strp
//     DW_AT_comp_dir     DW_FORM_strp
//     DW_AT_low_pc       DW_FORM_addr
//     DW_AT_high_pc      DW_FORM_addr
//     DW_AT_stmt_list    DW_FORM_data4
//     DW_AT value: 0     DW_FORM value: 0
//    2      DW_TAG_subprogram    [has children]
//     DW_AT_external     DW_FORM_flag
//     DW_AT_name         DW_FORM_strp
//     DW_AT_decl_file    DW_FORM_data1
//     DW_AT_decl_line    DW_FORM_data1
//     DW_AT_decl_column  DW_FORM_data1
//     DW_AT_type         DW_FORM_ref4
//     DW_AT_low_pc       DW_FORM_addr
//     DW_AT_high_pc      DW_FORM_addr
//     DW_AT_frame_base   DW_FORM_data4
//     DW_AT_GNU_all_tail_call_sites DW_FORM_flag
//     DW_AT_sibling      DW_FORM_ref4
//     DW_AT value: 0     DW_FORM value: 0
//    3      DW_TAG_variable    [no children]
//     DW_AT_name         DW_FORM_string
//     DW_AT_decl_file    DW_FORM_data1
//     DW_AT_decl_line    DW_FORM_data1
//     DW_AT_decl_column  DW_FORM_data1
//     DW_AT_type         DW_FORM_ref4
//     DW_AT_location     DW_FORM_block1
//     DW_AT value: 0     DW_FORM value: 0
//    4      DW_TAG_base_type    [no children]
//     DW_AT_byte_size    DW_FORM_data1
//     DW_AT_encoding     DW_FORM_data1
//     DW_AT_name         DW_FORM_string
//     DW_AT value: 0     DW_FORM value: 0
//    5      DW_TAG_base_type    [no children]
//     DW_AT_byte_size    DW_FORM_data1
//     DW_AT_encoding     DW_FORM_data1
//     DW_AT_name         DW_FORM_strp
//     DW_AT value: 0     DW_FORM value: 0
//    6      DW_TAG_subprogram    [has children]
//     DW_AT_external     DW_FORM_flag
//     DW_AT_name         DW_FORM_strp
//     DW_AT_decl_file    DW_FORM_data1
//     DW_AT_decl_line    DW_FORM_data1
//     DW_AT_decl_column  DW_FORM_data1
//     DW_AT_type         DW_FORM_ref4
//     DW_AT_low_pc       DW_FORM_addr
//     DW_AT_high_pc      DW_FORM_addr
//     DW_AT_frame_base   DW_FORM_data4
//     DW_AT_GNU_all_call_sites DW_FORM_flag
//     DW_AT value: 0     DW_FORM value: 0

// $ readelf --debug-dump=info -x.debug_info simple

// Hex dump of section '.debug_info':