Skip to content

Commit

Permalink
More work on this
Browse files Browse the repository at this point in the history
  • Loading branch information
Victorious3 committed Nov 23, 2023
1 parent 1b04cf4 commit 7a1f005
Show file tree
Hide file tree
Showing 3 changed files with 240 additions and 50 deletions.
141 changes: 113 additions & 28 deletions attributes.pr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import vector
import merge

const DW_DLV_NO_ENTRY = -1
const DW_DLA_STRING = 0x01
const DW_DLA_LIST = 0x0f

export type Attr = interface {
def read(obj: &merge::Object, die: *s_Dwarf_Die_s, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) -> int
Expand Down Expand Up @@ -34,7 +36,7 @@ type Line = struct {
lineaddr: uint64
}

let attributes = map::make(int, type *runtime::Type)
export let attributes = map::make(int, type *runtime::Type)
attributes[0x3f] = type AT_external
attributes[0x03] = type AT_name
attributes[0x3a] = type AT_decl_file
Expand All @@ -53,6 +55,10 @@ attributes[0x3e] = type AT_encoding
attributes[0x0b] = type AT_byte_size
attributes[0x10] = type AT_stmt_list

// GNU Stuff
attributes[0x2116] = type AT_GNU_all_tail_call_sites
attributes[0x2117] = type AT_GNU_all_call_sites

export def parse(object: &merge::Object, die: *s_Dwarf_Die_s, attribute: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) -> &Attr {
var kind: ushort
dwarf_whatattr(attribute, *kind, err)
Expand Down Expand Up @@ -135,7 +141,7 @@ def read_location_expression(obj: &merge::Object, die: *s_Dwarf_Die_s, data: *,
}

// Attributes
type AT_external = struct { data: bool }
export type AT_external = struct { data: bool }
export def read(at: &AT_external, obj: &merge::Object, die: *s_Dwarf_Die_s, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) -> int {
var flag: int
let res = dwarf_formflag(attr, *flag, err)
Expand All @@ -146,7 +152,7 @@ export def write(at: &AT_external, obj: &merge::Object, pdie: &merge::DIE, attr:
return dwarf_add_AT_flag_a(obj.pdbg, pdie.die, 0x3f !ushort, at.data !uint8, attr, error)
}

type AT_name = struct { data: Str }
export type AT_name = struct { data: Str }
export def read(at: &AT_name, obj: &merge::Object, die: *s_Dwarf_Die_s, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) -> int {
var str: *char
let res = dwarf_formstring(attr, *str, err)
Expand All @@ -157,7 +163,7 @@ export def write(at: &AT_name, obj: &merge::Object, pdie: &merge::DIE, attr: **s
return dwarf_add_AT_name_a(pdie.die, at.data.to_array().value, attr, error)
}

type AT_producer = struct { data: Str }
export type AT_producer = struct { data: Str }
export def read(at: &AT_producer, obj: &merge::Object, die: *s_Dwarf_Die_s, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) -> int {
var str: *char
let res = dwarf_formstring(attr, *str, err)
Expand All @@ -168,31 +174,31 @@ export def write(at: &AT_producer, obj: &merge::Object, pdie: &merge::DIE, attr:
return dwarf_add_AT_producer_a(pdie.die, at.data.to_array().value, attr, error)
}

type AT_decl_file = struct { data: uint64 }
export type AT_decl_file = struct { data: uint64 }
export def read(at: &AT_decl_file, obj: &merge::Object, die: *s_Dwarf_Die_s, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) -> int {
return dwarf_formudata(attr, *at.data, err)
}
export def write(at: &AT_decl_file, obj: &merge::Object, pdie: &merge::DIE, attr: **s_Dwarf_P_Attribute_s, error: **s_Dwarf_Error_s) -> int {
return dwarf_add_AT_unsigned_const_a(obj.pdbg, pdie.die, 0x3a !ushort, at.data, attr, error)
}

type AT_decl_line = struct { data: uint64 }
export type AT_decl_line = struct { data: uint64 }
export def read(at: &AT_decl_line, obj: &merge::Object, die: *s_Dwarf_Die_s, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) -> int {
return dwarf_formudata(attr, *at.data, err)
}
export def write(at: &AT_decl_line, obj: &merge::Object, pdie: &merge::DIE, attr: **s_Dwarf_P_Attribute_s, error: **s_Dwarf_Error_s) -> int {
return dwarf_add_AT_unsigned_const_a(obj.pdbg, pdie.die, 0x3b !ushort, at.data, attr, error)
}

type AT_decl_column = struct { data: uint64 }
export type AT_decl_column = struct { data: uint64 }
export def read(at: &AT_decl_column, obj: &merge::Object, die: *s_Dwarf_Die_s, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) -> int {
return dwarf_formudata(attr, *at.data, err)
}
export def write(at: &AT_decl_column, obj: &merge::Object, pdie: &merge::DIE, attr: **s_Dwarf_P_Attribute_s, error: **s_Dwarf_Error_s) -> int {
return dwarf_add_AT_unsigned_const_a(obj.pdbg, pdie.die, 0x39 !ushort, at.data, attr, error)
}

type AT_prototyped = struct { data: bool }
export type AT_prototyped = struct { data: bool }
export def read(at: &AT_prototyped, obj: &merge::Object, die: *s_Dwarf_Die_s, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) -> int {
var flag: int
let res = dwarf_formflag(attr, *flag, err)
Expand All @@ -203,7 +209,7 @@ export def write(at: &AT_prototyped, obj: &merge::Object, pdie: &merge::DIE, att
return dwarf_add_AT_flag_a(obj.pdbg, pdie.die, 0x27 !ushort, at.data !uint8, attr, error)
}

type AT_type = struct { data: uint64 }
export type AT_type = struct { data: uint64 }
export def read(at: &AT_type, obj: &merge::Object, die: *s_Dwarf_Die_s, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) -> int {
var is_info: int
return dwarf_formref(attr, *at.data, *is_info, err)
Expand All @@ -214,39 +220,39 @@ export def write(at: &AT_type, obj: &merge::Object, pdie: &merge::DIE, attr: **s
return res
}

type AT_low_pc = struct { data: AddressData }
export type AT_low_pc = struct { data: AddressData }
export def read(at: &AT_low_pc, obj: &merge::Object, die: *s_Dwarf_Die_s, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) -> int {
return dwarf_formaddr(attr, *at.data.offset, err) // TODO find the symbol
return dwarf_formaddr(attr, *at.data.offset, err)
}
export def write(at: &AT_low_pc, obj: &merge::Object, pdie: &merge::DIE, attr: **s_Dwarf_P_Attribute_s, error: **s_Dwarf_Error_s) -> int {
return dwarf_add_AT_targ_address_c(obj.pdbg, pdie.die, 0x11 !ushort, at.data.offset, at.data.symbol, attr, error)
return dwarf_add_AT_targ_address_c(obj.pdbg, pdie.die, 0x11 !ushort, at.data.offset, find_symbol(obj, ".text").index, attr, error)
}

type AT_high_pc = struct { data: uint64 }
export type AT_high_pc = struct { data: uint64 }
export def read(at: &AT_high_pc, obj: &merge::Object, die: *s_Dwarf_Die_s, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) -> int {
return dwarf_formudata(attr, *at.data, err)
}
export def write(at: &AT_high_pc, obj: &merge::Object, pdie: &merge::DIE, attr: **s_Dwarf_P_Attribute_s, error: **s_Dwarf_Error_s) -> int {
return dwarf_add_AT_unsigned_const_a(obj.pdbg, pdie.die, 0x12 !ushort, at.data, attr, error)
}

type AT_encoding = struct { data: uint64 }
export type AT_encoding = struct { data: uint64 }
export def read(at: &AT_encoding, obj: &merge::Object, die: *s_Dwarf_Die_s, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) -> int {
return dwarf_formudata(attr, *at.data, err)
}
export def write(at: &AT_encoding, obj: &merge::Object, pdie: &merge::DIE, attr: **s_Dwarf_P_Attribute_s, error: **s_Dwarf_Error_s) -> int {
return dwarf_add_AT_unsigned_const_a(obj.pdbg, pdie.die, 0x3e !ushort, at.data, attr, error)
}

type AT_byte_size = struct { data: uint64 }
export type AT_byte_size = struct { data: uint64 }
export def read(at: &AT_byte_size, obj: &merge::Object, die: *s_Dwarf_Die_s, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) -> int {
return dwarf_formudata(attr, *at.data, err)
}
export def write(at: &AT_byte_size, obj: &merge::Object, pdie: &merge::DIE, attr: **s_Dwarf_P_Attribute_s, error: **s_Dwarf_Error_s) -> int {
return dwarf_add_AT_unsigned_const_a(obj.pdbg, pdie.die, 0x0b !ushort, at.data, attr, error)
}

type AT_frame_base = struct { data: &Vector(ExpressionData) }
export type AT_frame_base = struct { data: &Vector(ExpressionData) }
export def read(at: &AT_frame_base, obj: &merge::Object, die: *s_Dwarf_Die_s, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) -> int {
at.data = vector::make(ExpressionData)
var length: uint64
Expand All @@ -264,7 +270,7 @@ export def write(at: &AT_frame_base, obj: &merge::Object, pdie: &merge::DIE, att
return dwarf_add_AT_location_expr_a(obj.pdbg, pdie.die, 0x40 !ushort, expr, attr, error)
}

type AT_location = struct { data: &Vector(ExpressionData) }
export type AT_location = struct { data: &Vector(ExpressionData) }
export def read(at: &AT_location, obj: &merge::Object, die: *s_Dwarf_Die_s, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) -> int {
at.data = vector::make(ExpressionData)
var length: uint64
Expand All @@ -282,15 +288,15 @@ export def write(at: &AT_location, obj: &merge::Object, pdie: &merge::DIE, attr:
return dwarf_add_AT_location_expr_a(obj.pdbg, pdie.die, 0x02 !ushort, expr, attr, error)
}

type AT_language = struct { data: uint64 }
export type AT_language = struct { data: uint64 }
export def read(at: &AT_language, obj: &merge::Object, die: *s_Dwarf_Die_s, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) -> int {
return dwarf_formudata(attr, *at.data, err)
}
export def write(at: &AT_language, obj: &merge::Object, pdie: &merge::DIE, attr: **s_Dwarf_P_Attribute_s, error: **s_Dwarf_Error_s) -> int {
return dwarf_add_AT_unsigned_const_a(obj.pdbg, pdie.die, 0x13 !ushort, at.data, attr, error)
}

type AT_comp_dir = struct { data: Str }
export type AT_comp_dir = struct { data: Str }
export def read(at: &AT_comp_dir, obj: &merge::Object, die: *s_Dwarf_Die_s, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) -> int {
var str: *char
let res = dwarf_formstring(attr, *str, err)
Expand All @@ -301,18 +307,37 @@ export def write(at: &AT_comp_dir, obj: &merge::Object, pdie: &merge::DIE, attr:
return dwarf_add_AT_comp_dir_a(pdie.die, at.data.to_array().value, attr, error)
}

type AT_stmt_list = struct { data: &Vector(Line) }
export type AT_stmt_list = struct {
data: &Vector(Line)
offset: uint64
src_files: &Vector(&string)
}

export def read(at: &AT_stmt_list, obj: &merge::Object, die: *s_Dwarf_Die_s, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) -> int {
var count: int64
var context: *s_Dwarf_Line_Context_s
var linebuf: **s_Dwarf_Line_s
var table_count: uint8
var version: uint64

if dwarf_srclines_b(die, *version, *table_count, *context, err) == DW_DLV_ERROR { return DW_DLV_ERROR }
if dwarf_srclines_from_linecontext(context, *linebuf, *count, err) == DW_DLV_ERROR {
dwarf_srclines_dealloc_b(context)
at.src_files = vector::make(type &string)

// Source files
var sfcount: int64
var srcfiles: **char

if dwarf_srcfiles(die, *srcfiles, *sfcount, err) == DW_DLV_ERROR { return DW_DLV_ERROR }
for var i in 0..sfcount {
at.src_files.push(make_string(srcfiles[i]).to_array())

dwarf_dealloc(obj.dbg, srcfiles[i], DW_DLA_STRING)
}
dwarf_dealloc(obj.dbg, srcfiles, DW_DLA_LIST)

if dwarf_srclines_b(die, *version, *table_count, *context, err) == DW_DLV_ERROR { return DW_DLV_ERROR }
defer dwarf_srclines_dealloc_b(context)

if dwarf_srclines_from_linecontext(context, *linebuf, *count, err) == DW_DLV_ERROR { return DW_DLV_ERROR }

at.data = vector::make(Line)
for var i in 0..count {
Expand All @@ -333,13 +358,73 @@ export def read(at: &AT_stmt_list, obj: &merge::Object, die: *s_Dwarf_Die_s, att

return DW_DLV_OK
}

export def write(at: &AT_stmt_list, obj: &merge::Object, pdie: &merge::DIE, attr: **s_Dwarf_P_Attribute_s, error: **s_Dwarf_Error_s) -> int {

for var sf in at.src_files {
var file_entry_count: uint64
if dwarf_add_file_decl_a(obj.pdbg, sf.value, 0, 0, sf.size, *file_entry_count, error) == DW_DLV_ERROR { return DW_DLV_ERROR }
}

if dwarf_lne_set_address_a(obj.pdbg, pdie.find_attribute(AT_low_pc).data.offset, obj.find_symbol(".text").index, error) == DW_DLV_ERROR { return DW_DLV_ERROR }
let orig = pdie.obj
var i = 0
var first = true
var sym: &merge::Symbol
for var line in at.data {
/*if dwarf_add_line_entry_c(
obj.pdbg, line.file_index, line.lineaddr,
line.lineno, line.columnno, line.begin_stmt,
line.lineblock, line.epilogue_begin, line.prologue_end,
line.isa, line.discriminator, error) == DW_DLV_ERROR { return DW_DLV_ERROR }*/
if not sym {
sym = orig.find_symbol(line.lineaddr, ".text")
} else {
if line.lineaddr >= sym.location + sym.size {
sym = orig.find_symbol(line.lineaddr, ".text")
}
}

if sym { print(sym.name, " ") }
print(line.lineaddr, "\n")

if i == at.data.length - 1 {
if dwarf_lne_end_sequence_a(obj.pdbg, line.lineaddr, error) == DW_DLV_ERROR { return DW_DLV_ERROR }
} else {
if not sym {
i += 1
continue
}

if dwarf_add_line_entry_c(
obj.pdbg, line.file_index, line.lineaddr,
line.lineno, line.columnno, line.begin_stmt,
line.lineblock, line.epilogue_begin, line.prologue_end,
line.isa, line.discriminator, error) == DW_DLV_ERROR {

return DW_DLV_ERROR
}
}

i += 1
}
return DW_DLV_OK
}

// GNU Extensions
export type AT_GNU_all_tail_call_sites = struct { data: bool }
export def read(at: &AT_GNU_all_tail_call_sites, obj: &merge::Object, die: *s_Dwarf_Die_s, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) -> int {
var flag: int
let res = dwarf_formflag(attr, *flag, err)
at.data = flag !bool
return res
}
export def write(at: &AT_GNU_all_tail_call_sites, obj: &merge::Object, pdie: &merge::DIE, attr: **s_Dwarf_P_Attribute_s, error: **s_Dwarf_Error_s) -> int {
return dwarf_add_AT_flag_a(obj.pdbg, pdie.die, 0x2116 !ushort, at.data !uint8, attr, error)
}

export type AT_GNU_all_call_sites = struct { data: bool }
export def read(at: &AT_GNU_all_call_sites, obj: &merge::Object, die: *s_Dwarf_Die_s, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) -> int {
var flag: int
let res = dwarf_formflag(attr, *flag, err)
at.data = flag !bool
return res
}
export def write(at: &AT_GNU_all_call_sites, obj: &merge::Object, pdie: &merge::DIE, attr: **s_Dwarf_P_Attribute_s, error: **s_Dwarf_Error_s) -> int {
return dwarf_add_AT_flag_a(obj.pdbg, pdie.die, 0x2117 !ushort, at.data !uint8, attr, error)
}
3 changes: 3 additions & 0 deletions main.pr
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ def main {
new_obj.copy_symbols(obj_a)
new_obj.copy_symbols(obj_b)

new_obj.remove_dwarf_duplicates(obj_b)
new_obj.remove_dwarf_duplicates(obj_a)

new_obj.copy_debug_info(obj_a)
new_obj.copy_debug_info(obj_b)

Expand Down
Loading

0 comments on commit 7a1f005

Please sign in to comment.