emit simple DWARF line table

This commit is contained in:
Nikita Smith
2026-02-20 18:08:45 -08:00
parent 121c211d81
commit 4b88258a30
6 changed files with 133 additions and 63 deletions
+22
View File
@@ -1029,3 +1029,25 @@ dw_form_match(DW_Form a, DW_Form b)
return is_match; return is_match;
} }
internal U64
dw_length_from_std_opcode(DW_StdOpcode opcode)
{
switch (opcode) {
case DW_StdOpcode_ExtendedOpcode: return 0;
case DW_StdOpcode_Copy: return 0;
case DW_StdOpcode_AdvancePc: return 1;
case DW_StdOpcode_AdvanceLine: return 1;
case DW_StdOpcode_SetFile: return 1;
case DW_StdOpcode_SetColumn: return 1;
case DW_StdOpcode_NegateStmt: return 0;
case DW_StdOpcode_SetBasicBlock: return 0;
case DW_StdOpcode_ConstAddPc: return 0;
case DW_StdOpcode_FixedAdvancePc: return 1;
case DW_StdOpcode_SetPrologueEnd: return 0;
case DW_StdOpcode_SetEpilogueBegin: return 0;
case DW_StdOpcode_SetIsa: return 1;
default: InvalidPath; break;
}
return 0;
}
+5
View File
@@ -1829,4 +1829,9 @@ internal void * dw_serial_push_sleb128(Arena *arena, String8List *srl, S64 v);
internal B32 dw_form_match(DW_Form a, DW_Form b); internal B32 dw_form_match(DW_Form a, DW_Form b);
////////////////////////////////
// Line
internal U64 dw_length_from_std_opcode(DW_StdOpcode opcode);
#endif // DWARF_H #endif // DWARF_H
+10 -11
View File
@@ -2586,10 +2586,11 @@ dw_line_vm_step(DW_LineVM *vm)
// extended opcodes // extended opcodes
case DW_StdOpcode_ExtendedOpcode: { case DW_StdOpcode_ExtendedOpcode: {
TryRead(str8_deserial_read_uleb128(vm->program, vm->cursor, &vm->ext_length), vm->cursor, exit); TryRead(str8_deserial_read_uleb128(vm->program, vm->cursor, &vm->ext_length), vm->cursor, exit);
String8 ext_data = str8_substr(vm->program, r1u64(vm->cursor, vm->cursor + vm->ext_length));
vm->cursor += vm->ext_length;
U64 extended_opl = vm->cursor + vm->ext_length; U64 ext_cursor = 0;
TryRead(str8_deserial_read_struct(ext_data, ext_cursor, &vm->ext_opcode), vm->cursor, exit);
TryRead(str8_deserial_read_struct(vm->program, vm->cursor, &vm->ext_opcode), vm->cursor, exit);
switch (vm->ext_opcode) { switch (vm->ext_opcode) {
case DW_ExtOpcode_EndSequence: { case DW_ExtOpcode_EndSequence: {
@@ -2599,16 +2600,16 @@ dw_line_vm_step(DW_LineVM *vm)
} break; } break;
case DW_ExtOpcode_SetAddress: { case DW_ExtOpcode_SetAddress: {
TryRead(str8_deserial_read(vm->program, vm->cursor, &vm->operands[0].u64, vm->header.address_size, vm->header.address_size), vm->cursor, exit); TryRead(str8_deserial_read(ext_data, ext_cursor, &vm->operands[0].u64, vm->header.address_size, vm->header.address_size), vm->cursor, exit);
vm->state.address = vm->operands[0].u64; vm->state.address = vm->operands[0].u64;
vm->state.op_index = 0; vm->state.op_index = 0;
} break; } break;
case DW_ExtOpcode_DefineFile: { case DW_ExtOpcode_DefineFile: {
TryRead(str8_deserial_read_cstr (vm->program, vm->cursor, &vm->operands[0].string), vm->cursor, exit); // file name TryRead(str8_deserial_read_cstr (ext_data, ext_cursor, &vm->operands[0].string), vm->cursor, exit); // file name
TryRead(str8_deserial_read_uleb128(vm->program, vm->cursor, &vm->operands[1].u64), vm->cursor, exit); // dir index TryRead(str8_deserial_read_uleb128(ext_data, ext_cursor, &vm->operands[1].u64), vm->cursor, exit); // dir index
TryRead(str8_deserial_read_uleb128(vm->program, vm->cursor, &vm->operands[2].u64), vm->cursor, exit); // modify time TryRead(str8_deserial_read_uleb128(ext_data, ext_cursor, &vm->operands[2].u64), vm->cursor, exit); // modify time
TryRead(str8_deserial_read_uleb128(vm->program, vm->cursor, &vm->operands[3].u64), vm->cursor, exit); // file size TryRead(str8_deserial_read_uleb128(ext_data, ext_cursor, &vm->operands[3].u64), vm->cursor, exit); // file size
if (vm->ext_file_ht == 0) { if (vm->ext_file_ht == 0) {
vm->ext_file_ht = hash_table_init(vm->arena, 512); vm->ext_file_ht = hash_table_init(vm->arena, 512);
@@ -2629,14 +2630,12 @@ dw_line_vm_step(DW_LineVM *vm)
} break; } break;
case DW_ExtOpcode_SetDiscriminator: { case DW_ExtOpcode_SetDiscriminator: {
TryRead(str8_deserial_read_uleb128(vm->program, vm->cursor, &vm->operands[0].u64), vm->cursor, exit); TryRead(str8_deserial_read_uleb128(ext_data, ext_cursor, &vm->operands[0].u64), vm->cursor, exit);
vm->state.discriminator = vm->operands[0].u64; vm->state.discriminator = vm->operands[0].u64;
} break; } break;
default: { NotImplemented; } break; default: { NotImplemented; } break;
} }
vm->cursor = extended_opl;
} break; } break;
default: { default: {
+62 -39
View File
@@ -102,17 +102,21 @@ dw_writer_begin(DW_Format format, DW_Version version, DW_CompUnitKind cu_kind, A
{ {
Arena *arena = arena_alloc(); Arena *arena = arena_alloc();
DW_Writer *writer = push_array(arena, DW_Writer, 1); DW_Writer *writer = push_array(arena, DW_Writer, 1);
writer->arena = arena; writer->arena = arena;
writer->arch = arch; writer->arch = arch;
writer->format = format; writer->format = format;
writer->version = version; writer->version = version;
writer->cu_kind = cu_kind; writer->cu_kind = cu_kind;
writer->address_size = byte_size_from_arch(arch); writer->address_size = byte_size_from_arch(arch);
writer->current = 0; writer->current = 0;
writer->abbrev_id_map = hash_table_init(arena, 0x2000); writer->abbrev_id_map = hash_table_init(arena, 0x2000);
writer->line.opcode_base = DW_StdOpcode_Count; writer->line.min_inst_len = min_instruction_size_from_arch(arch);
writer->line.line_base = -5; writer->line.max_ops_per_inst = max_ops_per_instruction_from_arch(arch);
writer->line.line_range = 14; writer->line.default_is_stmt = 1;
writer->line.line_base = -5;
writer->line.line_range = 14;
writer->line.opcode_base = DW_StdOpcode_Count;
writer->line.ln = 1;
for EachElement(i, writer->sections) { for EachElement(i, writer->sections) {
str8_serial_begin(arena, &writer->sections[i].srl); str8_serial_begin(arena, &writer->sections[i].srl);
} }
@@ -461,7 +465,7 @@ dw_writer_push_attrib_expression(DW_Writer *writer, DW_AttribKind kind, DW_ExprE
} }
internal DW_WriterAttrib * internal DW_WriterAttrib *
dw_writer_push_attrib_line_ptr(DW_Writer *writer, DW_AttribKind kind, void *line_ptr) dw_writer_push_attrib_line_ptr(DW_Writer *writer, DW_AttribKind kind, U64 line_ptr)
{ {
return dw_writer_push_attrib(writer, kind, (DW_WriterForm){ .kind = DW_WriterFormKind_LinePtr, .line_ptr = line_ptr }); return dw_writer_push_attrib(writer, kind, (DW_WriterForm){ .kind = DW_WriterFormKind_LinePtr, .line_ptr = line_ptr });
} }
@@ -548,6 +552,7 @@ dw_data_from_line_insts(Arena *arena, U8 address_size, DW_LineInstList insts)
} break; } break;
default: { InvalidPath; } break; default: { InvalidPath; } break;
} }
ext_size += sizeof(DW_ExtOpcode);
// write ext header // write ext header
dw_serial_push_uleb128(arena, &srl, ext_size); dw_serial_push_uleb128(arena, &srl, ext_size);
@@ -569,7 +574,7 @@ dw_data_from_line_insts(Arena *arena, U8 address_size, DW_LineInstList insts)
} }
} break; } break;
// special opcode // special opcode
default: {} break; default: { } break;
} }
} }
@@ -581,29 +586,27 @@ dw_data_from_line_insts(Arena *arena, U8 address_size, DW_LineInstList insts)
internal void internal void
dw_writer_line_emit(DW_Writer *writer, DW_WriterFile *file, U64 ln, U64 col, U64 addr) dw_writer_line_emit(DW_Writer *writer, DW_WriterFile *file, U64 ln, U64 col, U64 addr)
{ {
if (writer->line.last_file != file) { if (writer->line.file != file) {
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNS_set_file(file)); dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNS_set_file(file));
} }
Assert(addr <= max_S64); Assert(addr <= max_S64);
S64 addr_delta = (S64)addr - (S64)writer->line.addr; S64 addr_delta = (S64)addr - (S64)writer->line.addr;
if (addr_delta != 0) { S64 ln_delta = (S64)ln - (S64)writer->line.ln;
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNS_advance_pc(addr_delta)); S64 col_delta = (S64)col - (S64)writer->line.col;
}
S64 ln_delta = (S64)ln - (S64)writer->line.ln; if (col_delta == 0 && (ln_delta > 0 || addr_delta > 0) &&
if (ln_delta != 0) { writer->line.line_base <= ln_delta && ln_delta < writer->line.line_range+writer->line.line_base &&
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNS_advance_line(ln_delta)); addr_delta < max_U8 - writer->line.opcode_base) {
U8 opcode = (ln_delta - writer->line.line_base) + (writer->line.line_range * addr_delta) + writer->line.opcode_base;
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, (DW_LineInst){ .opcode = opcode });
} else {
if (addr_delta != 0) { dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNS_advance_pc(addr_delta)); }
if (ln_delta != 0) { dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNS_advance_line(ln_delta)); }
if (col_delta != 0) { dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNS_set_column(col_delta)); }
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNS_copy());
} }
S64 col_delta = (S64)col - (S64)writer->line.col;
if (col_delta != 0) {
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNS_set_column(col_delta));
}
// append row
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNS_copy());
writer->line.file = file; writer->line.file = file;
writer->line.ln = ln; writer->line.ln = ln;
writer->line.col = col; writer->line.col = col;
@@ -714,7 +717,8 @@ dw_lower_attrib_forms(DW_Writer *writer, DW_WriterTag *tag)
} }
} break; } break;
case DW_WriterFormKind_LinePtr: { case DW_WriterFormKind_LinePtr: {
NotImplemented; attrib->form.reader.kind = DW_Form_SecOffset;
attrib->form.reader.sec_offset = attrib->form.writer.line_ptr;
} break; } break;
case DW_WriterFormKind_MacPtr: { case DW_WriterFormKind_MacPtr: {
NotImplemented; NotImplemented;
@@ -960,23 +964,29 @@ dw_writer_emit(DW_Writer *writer)
dw_serial_push_uleb128(writer->arena, srl, DW_LNCT_Path); dw_serial_push_uleb128(writer->arena, srl, DW_LNCT_Path);
dw_serial_push_uleb128(writer->arena, srl, DW_Form_String); dw_serial_push_uleb128(writer->arena, srl, DW_Form_String);
// dedup directories // dedup directories
HashTable *dir_ht = hash_table_init(scratch.arena, writer->line.file_count + 1); String8List dirs = {0};
HashTable *dir_ht = hash_table_init(scratch.arena, writer->line.file_count + 1);
// first entry must be compile unit directory // first entry must be compile unit directory
hash_table_push_string_u64(scratch.arena, dir_ht, comp_dir, dir_ht->count); hash_table_push_string_u64(scratch.arena, dir_ht, comp_dir, dir_ht->count);
str8_list_push(scratch.arena, &dirs, comp_dir);
for EachNode(file, DW_WriterFile, writer->line.first_file) { for EachNode(file, DW_WriterFile, writer->line.first_file) {
String8 path = str8_chop_last_slash(file->path); String8 path = str8_chop_last_slash(file->path);
if ( ! hash_table_search_string_u64(dir_ht, path, &file->dir_idx)) { if ( ! hash_table_search_string_u64(dir_ht, path, &file->dir_idx)) {
file->dir_idx = hash_table_push_string_u64(scratch.arena, dir_ht, path, dir_ht->count)->v.value_u64; file->dir_idx = hash_table_push_string_u64(scratch.arena, dir_ht, path, dir_ht->count)->v.value_u64;
str8_list_push(scratch.arena, &dirs, path);
} }
} }
KeyValuePair *dirs_kv = key_value_pairs_from_hash_table(scratch.arena, dir_ht); KeyValuePair *dirs_kv = key_value_pairs_from_hash_table(scratch.arena, dir_ht);
sort_key_value_pairs_as_string_sensitive(dirs_kv, dir_ht->count); //sort_key_value_pairs_as_string_sensitive(dirs_kv, dir_ht->count);
// (15) directories_count // (15) directories_count
dw_serial_push_uleb128(writer->arena, srl, dir_ht->count); dw_serial_push_uleb128(writer->arena, srl, dir_ht->count);
// (16) directories // (16) directories
for (U64 i = 1; i < dir_ht->count; i += 1) { for (U64 i = 0; i < dir_ht->count; i += 1) {
String8 dir = dirs_kv[i].key_string; String8 dir = dirs_kv[i].key_string;
dw_serial_push_form(writer->arena, srl, writer->version, writer->format, writer->address_size, 0, (DW_WriterXForm) { .reader = { .kind = DW_Form_String, .string = dir } }); dw_serial_push_form(writer->arena, srl, writer->version, writer->format, writer->address_size, 0, (DW_WriterXForm) { .reader = { .kind = DW_Form_String, .string = dir } });
} }
@@ -985,6 +995,7 @@ dw_writer_emit(DW_Writer *writer)
} }
String8List file_table_srl = {0}; String8List file_table_srl = {0};
str8_serial_begin(writer->arena, &file_table_srl);
{ {
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
String8List *srl = &file_table_srl; String8List *srl = &file_table_srl;
@@ -1010,11 +1021,11 @@ dw_writer_emit(DW_Writer *writer)
} }
// count needed encodings // count needed encodings
U64 enc_count = 0; U8 enc_count = 0;
for EachElement(i, encs) { if (encs[i].form_kind != DW_Form_Null) { enc_count += 1; } } for EachElement(i, encs) { if (encs[i].form_kind != DW_Form_Null) { enc_count += 1; } }
// (17) file_name_entry_format_count // (17) file_name_entry_format_count
str8_serial_push_u16(writer->arena, srl, enc_count); str8_serial_push_u8(writer->arena, srl, enc_count);
// (18) file_name_entry_format // (18) file_name_entry_format
for EachElement(i, encs) { for EachElement(i, encs) {
@@ -1038,6 +1049,9 @@ dw_writer_emit(DW_Writer *writer)
p->next = n->next; p->next = n->next;
n->next = writer->line.first_file; n->next = writer->line.first_file;
writer->line.first_file = n; writer->line.first_file = n;
if (writer->line.last_file == n) {
writer->line.last_file = p;
}
} }
break; break;
} }
@@ -1050,12 +1064,13 @@ dw_writer_emit(DW_Writer *writer)
// path // path
Assert(*(DW_FormKind *)hash_table_search_u64_raw(encs_ht, DW_LNCT_Path) == DW_Form_String); Assert(*(DW_FormKind *)hash_table_search_u64_raw(encs_ht, DW_LNCT_Path) == DW_Form_String);
DW_WriterXForm path_form = { .reader = { .kind = DW_Form_String, .string = file->path } }; String8 file_name = str8_skip_last_slash(file->path);
DW_WriterXForm path_form = { .reader = { .kind = DW_Form_String, .string = file_name } };
dw_serial_push_form(writer->arena, srl, writer->version, writer->format, writer->address_size, 0, path_form); dw_serial_push_form(writer->arena, srl, writer->version, writer->format, writer->address_size, 0, path_form);
// directory index // directory index
Assert(*(DW_FormKind *)hash_table_search_u64_raw(encs_ht, DW_LNCT_DirectoryIndex) == DW_Form_UData); Assert(*(DW_FormKind *)hash_table_search_u64_raw(encs_ht, DW_LNCT_DirectoryIndex) == DW_Form_UData);
DW_WriterXForm dir_idx_form = { .reader = { .kind = DW_Form_UData, .udata = file->time_stamp } }; DW_WriterXForm dir_idx_form = { .reader = { .kind = DW_Form_UData, .udata = file->dir_idx } };
dw_serial_push_form(writer->arena, srl, writer->version, writer->format, writer->address_size, 0, dir_idx_form); dw_serial_push_form(writer->arena, srl, writer->version, writer->format, writer->address_size, 0, dir_idx_form);
// time stamp // time stamp
@@ -1113,8 +1128,8 @@ dw_writer_emit(DW_Writer *writer)
// (4) segment_selector_size // (4) segment_selector_size
str8_serial_push_struct(writer->arena, srl, &writer->segsel_size); str8_serial_push_struct(writer->arena, srl, &writer->segsel_size);
// (5) header_length // (5) header_length
U64 header_size = srl->total_size + dir_table_srl.total_size + file_table_srl.total_size; void *header_length_ptr = dw_serial_push_uint(writer->arena, srl, writer->format, 0);
dw_serial_push_uint(writer->arena, srl, writer->format, header_size); U64 header_length_offset = srl->total_size;
// (6) minimum_instruction_length // (6) minimum_instruction_length
str8_serial_push_struct(writer->arena, srl, &writer->line.min_inst_len); str8_serial_push_struct(writer->arena, srl, &writer->line.min_inst_len);
// (7) maximum_operations_per_instruction // (7) maximum_operations_per_instruction
@@ -1128,11 +1143,19 @@ dw_writer_emit(DW_Writer *writer)
// (11) opcode_base // (11) opcode_base
str8_serial_push_struct(writer->arena, srl, &writer->line.opcode_base); str8_serial_push_struct(writer->arena, srl, &writer->line.opcode_base);
// (12) standard_opcode_lengths // (12) standard_opcode_lengths
str8_serial_push_struct(writer->arena, srl, &writer->line.std_op_lens); U8 *std_op_lens = push_array(writer->arena, U8, DW_StdOpcode_Count - 1);
for (U64 i = 1; i < DW_StdOpcode_Count; i += 1) { std_op_lens[i-1] = dw_length_from_std_opcode(i); }
str8_serial_push_string(writer->arena, srl, str8(std_op_lens, DW_StdOpcode_Count - 1));
// directory table // directory table
str8_list_concat_in_place(srl, &dir_table_srl); str8_list_concat_in_place(srl, &dir_table_srl);
// file table // file table
str8_list_concat_in_place(srl, &file_table_srl); str8_list_concat_in_place(srl, &file_table_srl);
// fixup header length
U64 bytes_to_line_program = srl->total_size - header_length_offset;
if (writer->format == DW_Format_32Bit) { *(U32 *)header_length_ptr = bytes_to_line_program; }
else { *(U64 *)header_length_ptr = bytes_to_line_program; }
// line program // line program
String8 line_program_data = dw_data_from_line_insts(writer->arena, writer->address_size, writer->line.line_insts); String8 line_program_data = dw_data_from_line_insts(writer->arena, writer->address_size, writer->line.line_insts);
str8_serial_push_string(writer->arena, srl, line_program_data); str8_serial_push_string(writer->arena, srl, line_program_data);
+3 -3
View File
@@ -47,7 +47,7 @@ typedef struct DW_WriterForm
union { union {
struct { struct {
struct DW_WriterTag *ref; struct DW_WriterTag *ref;
void *line_ptr; U64 line_ptr;
void *mac_ptr; void *mac_ptr;
void *rng_list_ptr; void *rng_list_ptr;
}; };
@@ -137,6 +137,7 @@ typedef struct DW_WriterFile
U64 size; U64 size;
String8 md5; String8 md5;
String8 source; String8 source;
// computed during line table emit step
U64 file_idx; U64 file_idx;
U64 dir_idx; U64 dir_idx;
} DW_WriterFile; } DW_WriterFile;
@@ -225,7 +226,6 @@ typedef struct DW_Writer
S8 line_base; S8 line_base;
U8 line_range; U8 line_range;
U8 opcode_base; U8 opcode_base;
U8 *std_op_lens;
DW_LineInstList line_insts; DW_LineInstList line_insts;
DW_WriterFile *file; DW_WriterFile *file;
@@ -275,7 +275,7 @@ internal DW_WriterAttrib * dw_writer_push_attrib_enum (DW_Writer *writer,
internal DW_WriterAttrib * dw_writer_push_attrib_ref (DW_Writer *writer, DW_AttribKind kind, DW_WriterTag *ref ); internal DW_WriterAttrib * dw_writer_push_attrib_ref (DW_Writer *writer, DW_AttribKind kind, DW_WriterTag *ref );
internal DW_WriterAttrib * dw_writer_push_attrib_exprloc (DW_Writer *writer, DW_AttribKind kind, String8 exprloc ); internal DW_WriterAttrib * dw_writer_push_attrib_exprloc (DW_Writer *writer, DW_AttribKind kind, String8 exprloc );
internal DW_WriterAttrib * dw_writer_push_attrib_expression (DW_Writer *writer, DW_AttribKind kind, DW_ExprEnc *encs, U64 encs_count); internal DW_WriterAttrib * dw_writer_push_attrib_expression (DW_Writer *writer, DW_AttribKind kind, DW_ExprEnc *encs, U64 encs_count);
internal DW_WriterAttrib * dw_writer_push_attrib_line_ptr (DW_Writer *writer, DW_AttribKind kind, void * line_ptr ); internal DW_WriterAttrib * dw_writer_push_attrib_line_ptr (DW_Writer *writer, DW_AttribKind kind, U64 line_ptr );
internal DW_WriterAttrib * dw_writer_push_attrib_mac_ptr (DW_Writer *writer, DW_AttribKind kind, void * mac_ptr ); internal DW_WriterAttrib * dw_writer_push_attrib_mac_ptr (DW_Writer *writer, DW_AttribKind kind, void * mac_ptr );
internal DW_WriterAttrib * dw_writer_push_attrib_rng_list_ptr(DW_Writer *writer, DW_AttribKind kind, void * rng_list_ptr); internal DW_WriterAttrib * dw_writer_push_attrib_rng_list_ptr(DW_Writer *writer, DW_AttribKind kind, void * rng_list_ptr);
internal DW_WriterAttrib * dw_writer_push_attrib_implicit (DW_Writer *writer, DW_AttribKind kind, S64 implicit ); internal DW_WriterAttrib * dw_writer_push_attrib_implicit (DW_Writer *writer, DW_AttribKind kind, S64 implicit );
+31 -10
View File
@@ -107,25 +107,40 @@ dwt_make_writer(void)
{ {
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
String8 comp_dir = t_make_file_path(scratch.arena, str8_lit(""));
String8 comp_name = str8_lit("test_code.txt");
String8 test_text = str8_lit("nop\nnop\nret\n");
String8 test_path = t_make_file_path(scratch.arena, comp_name);
t_write_file(comp_name, test_text);
DW_Writer *writer = dw_writer_begin(DW_Format_32Bit, DW_Version_Last, DW_CompUnitKind_Compile, Arch_x64); DW_Writer *writer = dw_writer_begin(DW_Format_32Bit, DW_Version_Last, DW_CompUnitKind_Compile, Arch_x64);
// line // line
{ {
DW_WriterFile *b_file = dw_writer_new_file(writer, str8_lit("~/devel/projects/b/b.c")); DW_WriterFile *a_file = dw_writer_new_file(writer, test_path);
DW_WriterFile *a_file = dw_writer_new_file(writer, str8_lit("~/devel/projects/a.c"));
dw_writer_line_set_prologue_end(writer); dw_writer_line_set_prologue_end(writer);
dw_writer_line_emit(writer, b_file, 10, 0, 0x140001000); dw_writer_line_emit(writer, a_file, 1, 0, 0x140001000);
dw_writer_line_emit(writer, b_file, 11, 0, 0x140001010); dw_writer_line_emit(writer, a_file, 2, 0, 0x140001001);
dw_writer_line_emit(writer, a_file, 1, 0, 0x140001016); dw_writer_line_emit(writer, a_file, 3, 0, 0x140001002);
dw_writer_line_emit(writer, a_file, 2, 0, 0x140001020);
//DW_WriterFile *b_file = dw_writer_new_file(writer, str8_lit("~/devel/projects/b/b.c"));
//DW_WriterFile *a_file = dw_writer_new_file(writer, str8_lit("~/devel/projects/a.c"));
//dw_writer_line_set_prologue_end(writer);
//dw_writer_line_emit(writer, b_file, 10, 0, 0x140001000);
//dw_writer_line_emit(writer, b_file, 11, 0, 0x140001010);
//dw_writer_line_emit(writer, a_file, 1, 0, 0x140001016);
//dw_writer_line_emit(writer, a_file, 2, 0, 0x140001020);
} }
// info // info
{ {
dw_writer_tag_begin(writer, DW_TagKind_CompileUnit); dw_writer_tag_begin(writer, DW_TagKind_CompileUnit);
dw_writer_push_attrib_string(writer, DW_AttribKind_Producer, str8_lit("RAD DWARF WRITER")); dw_writer_push_attrib_string(writer, DW_AttribKind_Producer, str8_lit("RAD DWARF WRITER"));
dw_writer_push_attrib_string(writer, DW_AttribKind_CompDir, str8_lit("~/devel/projects")); dw_writer_push_attrib_string(writer, DW_AttribKind_CompDir, comp_dir);
dw_writer_push_attrib_string(writer, DW_AttribKind_Name, str8_lit("a.c")); dw_writer_push_attrib_string(writer, DW_AttribKind_Name, comp_name);
dw_writer_push_attrib_enum(writer, DW_AttribKind_Language, DW_Language_C99); dw_writer_push_attrib_enum(writer, DW_AttribKind_Language, DW_Language_C99);
dw_writer_push_attrib_flag(writer, DW_AttribKind_UseUtf8, 1); dw_writer_push_attrib_flag(writer, DW_AttribKind_UseUtf8, 1);
dw_writer_push_attrib_line_ptr(writer, DW_AttribKind_StmtList, 0);
dw_writer_push_attrib_address(writer, DW_AttribKind_LowPc, 0x140001000);
dw_writer_push_attrib_address(writer, DW_AttribKind_HighPc, 0x140001003);
{ {
DW_WriterTag *char_type = dw_writer_tag_begin(writer, DW_TagKind_BaseType); DW_WriterTag *char_type = dw_writer_tag_begin(writer, DW_TagKind_BaseType);
dw_writer_push_attrib_sint(writer, DW_AttribKind_ByteSize, 1); dw_writer_push_attrib_sint(writer, DW_AttribKind_ByteSize, 1);
@@ -167,8 +182,8 @@ dwt_make_writer(void)
dw_writer_tag_begin(writer, DW_TagKind_SubProgram); dw_writer_tag_begin(writer, DW_TagKind_SubProgram);
dw_writer_push_attrib_flag(writer, DW_AttribKind_External, 1); dw_writer_push_attrib_flag(writer, DW_AttribKind_External, 1);
dw_writer_push_attrib_flag(writer, DW_AttribKind_Prototyped, 1); dw_writer_push_attrib_flag(writer, DW_AttribKind_Prototyped, 1);
dw_writer_push_attrib_address(writer, DW_AttribKind_LowPc, 0x14012f2f0); dw_writer_push_attrib_address(writer, DW_AttribKind_LowPc, 0x140001000);
dw_writer_push_attrib_address(writer, DW_AttribKind_HighPc, 0x14012f405); dw_writer_push_attrib_address(writer, DW_AttribKind_HighPc, 0x140001003);
dw_writer_push_attrib_string(writer, DW_AttribKind_Name, str8_lit("main")); dw_writer_push_attrib_string(writer, DW_AttribKind_Name, str8_lit("main"));
dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, simple_struct_tag); dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, simple_struct_tag);
dw_writer_push_attrib_expression(writer, DW_AttribKind_FrameBase, &(DW_ExprEnc)DW_ExprEnc_Op(Reg7), 1); dw_writer_push_attrib_expression(writer, DW_AttribKind_FrameBase, &(DW_ExprEnc)DW_ExprEnc_Op(Reg7), 1);
@@ -182,6 +197,8 @@ dwt_make_writer(void)
{ {
OBJ *obj = obj_alloc(0, Arch_x64); OBJ *obj = obj_alloc(0, Arch_x64);
OBJ_Section *text_section = obj_push_section(obj, str8_lit(".text"), OBJ_SectionFlag_Read|OBJ_SectionFlag_Exec|OBJ_SectionFlag_Load); OBJ_Section *text_section = obj_push_section(obj, str8_lit(".text"), OBJ_SectionFlag_Read|OBJ_SectionFlag_Exec|OBJ_SectionFlag_Load);
str8_serial_push_u8(obj->arena, &text_section->data, 0x90);
str8_serial_push_u8(obj->arena, &text_section->data, 0x90);
str8_serial_push_u8(obj->arena, &text_section->data, 0xc3); str8_serial_push_u8(obj->arena, &text_section->data, 0xc3);
obj_push_symbol(obj, str8_lit("entry"), OBJ_SymbolScope_Global, OBJ_RefKind_Section, text_section); obj_push_symbol(obj, str8_lit("entry"), OBJ_SymbolScope_Global, OBJ_RefKind_Section, text_section);
@@ -195,6 +212,10 @@ dwt_make_writer(void)
String8 string_table = str8_substr(raw_coff, obj_coff_header.string_table_range); String8 string_table = str8_substr(raw_coff, obj_coff_header.string_table_range);
input = dw_input_from_coff_section_table(scratch.arena, raw_coff, string_table, section_count, section_table); input = dw_input_from_coff_section_table(scratch.arena, raw_coff, string_table, section_count, section_table);
t_write_file(str8_lit("dwarf.obj"), raw_coff);
t_invoke(str8_lit("radlink"), str8_lit("/subsystem:console /entry:entry /out:a.exe /debug:full dwarf.obj"), max_U64);
obj_release(&obj); obj_release(&obj);
} }