mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 17:28:07 +00:00
emit simple DWARF line table
This commit is contained in:
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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: {
|
||||||
|
|||||||
+49
-26
@@ -110,9 +110,13 @@ dw_writer_begin(DW_Format format, DW_Version version, DW_CompUnitKind cu_kind, A
|
|||||||
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.max_ops_per_inst = max_ops_per_instruction_from_arch(arch);
|
||||||
|
writer->line.default_is_stmt = 1;
|
||||||
writer->line.line_base = -5;
|
writer->line.line_base = -5;
|
||||||
writer->line.line_range = 14;
|
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,28 +586,26 @@ 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) {
|
|
||||||
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNS_advance_pc(addr_delta));
|
|
||||||
}
|
|
||||||
|
|
||||||
S64 ln_delta = (S64)ln - (S64)writer->line.ln;
|
S64 ln_delta = (S64)ln - (S64)writer->line.ln;
|
||||||
if (ln_delta != 0) {
|
|
||||||
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNS_advance_line(ln_delta));
|
|
||||||
}
|
|
||||||
|
|
||||||
S64 col_delta = (S64)col - (S64)writer->line.col;
|
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
|
if (col_delta == 0 && (ln_delta > 0 || addr_delta > 0) &&
|
||||||
|
writer->line.line_base <= ln_delta && ln_delta < writer->line.line_range+writer->line.line_base &&
|
||||||
|
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());
|
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;
|
||||||
@@ -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
|
||||||
|
String8List dirs = {0};
|
||||||
HashTable *dir_ht = hash_table_init(scratch.arena, writer->line.file_count + 1);
|
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);
|
||||||
|
|||||||
@@ -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
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user