Skip to content

Commit

Permalink
Deal with more data, we're getting somewhere for sure!
Browse files Browse the repository at this point in the history
  • Loading branch information
Victorious3 committed Nov 17, 2023
1 parent 38a1c2b commit a841a67
Show file tree
Hide file tree
Showing 3 changed files with 296 additions and 244 deletions.
176 changes: 176 additions & 0 deletions attributes.pr
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
import libdwarf
import map

import merge

export type Attr = interface {
// TODO These should both return a status I think
def read(attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s)
def write(obj: &merge::Object, die: &merge::DIE, attr: **s_Dwarf_P_Attribute_s, err: **s_Dwarf_Error_s)
}

type AddressData = struct {
symbol: uint64
offset: uint64
}
type ExpressionData = struct {
op: uint8
val1: uint64
val2: uint64
}

let attributes = map::make(int, type *runtime::Type)
attributes[0x3f] = type AT_external
attributes[0x03] = type AT_name
attributes[0x3a] = type AT_decl_file
attributes[0x3b] = type AT_decl_line
attributes[0x39] = type AT_decl_column
attributes[0x27] = type AT_prototyped
attributes[0x49] = type AT_type
attributes[0x11] = type AT_low_pc
attributes[0x12] = type AT_high_pc
attributes[0x40] = type AT_frame_base
attributes[0x25] = type AT_producer
attributes[0x13] = type AT_language
attributes[0x1b] = type AT_comp_dir

export def parse(attribute: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) -> &Attr {
var kind: ushort
dwarf_whatattr(attribute, *kind, err)

if not attributes.contains(kind) {
error("Unknown attribute: ", kind, ", skipping\n")
return null
}

let tpe = attributes[kind]
let instance = zero_allocate(tpe.size)
let ref = make_ref(tpe, instance)
let attr = ref !&Attr

attr.read(attribute, err)
//print("Read attribute of type ", tpe.name, "\n")
return attr
}

// Attributes
type AT_external = struct { data: bool }
export def read(at: &AT_external, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) {
var flag: int
dwarf_formflag(attr, *flag, err)
at.data = flag !bool
}
export def write(at: &AT_external, obj: &merge::Object, pdie: &merge::DIE, attr: **s_Dwarf_P_Attribute_s, error: **s_Dwarf_Error_s) {
dwarf_add_AT_flag_a(obj.pdbg, pdie.die, 0x3f !ushort, at.data !uint8, attr, error)
}

type AT_name = struct { data: Str }
export def read(at: &AT_name, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) {
var str: *char
dwarf_formstring(attr, *str, err)
at.data = make_string(str)
}
export def write(at: &AT_name, obj: &merge::Object, pdie: &merge::DIE, attr: **s_Dwarf_P_Attribute_s, error: **s_Dwarf_Error_s) {
dwarf_add_AT_name_a(pdie.die, at.data.to_array().value, attr, error)
}

type AT_producer = struct { data: Str }
export def read(at: &AT_producer, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) {
var str: *char
dwarf_formstring(attr, *str, err)
at.data = make_string(str)
}
export def write(at: &AT_producer, obj: &merge::Object, pdie: &merge::DIE, attr: **s_Dwarf_P_Attribute_s, error: **s_Dwarf_Error_s) {
dwarf_add_AT_producer_a(pdie.die, at.data.to_array().value, attr, error)
}

type AT_decl_file = struct { data: uint64 }
export def read(at: &AT_decl_file, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) {
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) {
dwarf_add_AT_unsigned_const_a(obj.pdbg, pdie.die, 0x3a !ushort, at.data, attr, error)
}

type AT_decl_line = struct { data: uint64 }
export def read(at: &AT_decl_line, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) {
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) {
dwarf_add_AT_unsigned_const_a(obj.pdbg, pdie.die, 0x3b !ushort, at.data, attr, error)
}

type AT_decl_column = struct { data: uint64 }
export def read(at: &AT_decl_column, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) {
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) {
dwarf_add_AT_unsigned_const_a(obj.pdbg, pdie.die, 0x39 !ushort, at.data, attr, error)
}

type AT_prototyped = struct { data: bool }
export def read(at: &AT_prototyped, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) {
var flag: int
dwarf_formflag(attr, *flag, err)
at.data = flag !bool
}
export def write(at: &AT_prototyped, obj: &merge::Object, pdie: &merge::DIE, attr: **s_Dwarf_P_Attribute_s, error: **s_Dwarf_Error_s) {
dwarf_add_AT_flag_a(obj.pdbg, pdie.die, 0x27 !ushort, at.data !uint8, attr, error)
}

type AT_type = struct { data: uint64 }
export def read(at: &AT_type, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) {
var is_info: int
dwarf_formref(attr, *at.data, *is_info, err)
}
export def write(at: &AT_type, obj: &merge::Object, pdie: &merge::DIE, attr: **s_Dwarf_P_Attribute_s, error: **s_Dwarf_Error_s) {
dwarf_add_AT_reference_c(obj.pdbg, pdie.die, 0x49 !ushort, null, attr, error)
obj.add_reference_marker(pdie, 0x49 !ushort, at.data)
}

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

type AT_high_pc = struct { data: uint64 }
export def read(at: &AT_high_pc, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) {
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) {
dwarf_add_AT_unsigned_const_a(obj.pdbg, pdie.die, 0x12 !ushort, at.data, attr, error)
}

type AT_frame_base = struct { data: ExpressionData }
export def read(at: &AT_frame_base, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) {
var length: uint64
var data: *
dwarf_formexprloc(attr, *length, *data, err)
}
export def write(at: &AT_frame_base, obj: &merge::Object, pdie: &merge::DIE, attr: **s_Dwarf_P_Attribute_s, error: **s_Dwarf_Error_s) {
var expr: *s_Dwarf_P_Expr_s
dwarf_new_expr_a(obj.pdbg, *expr, error)
dwarf_add_expr_gen_a(expr, at.data.op, at.data.val1, at.data.val2, null, error)
dwarf_add_AT_location_expr_a(obj.pdbg, pdie.die, 0x40 !ushort, expr, attr, error)
}

type AT_language = struct { data: uint64 }
export def read(at: &AT_language, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) {
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) {
dwarf_add_AT_unsigned_const_a(obj.pdbg, pdie.die, 0x13 !ushort, at.data, attr, error)
}

type AT_comp_dir = struct { data: Str }
export def read(at: &AT_comp_dir, attr: *s_Dwarf_Attribute_s, err: **s_Dwarf_Error_s) {
var str: *char
dwarf_formstring(attr, *str, err)
at.data = make_string(str)
}
export def write(at: &AT_comp_dir, obj: &merge::Object, pdie: &merge::DIE, attr: **s_Dwarf_P_Attribute_s, error: **s_Dwarf_Error_s) {
dwarf_add_AT_comp_dir_a(pdie.die, at.data.to_array().value, attr, error)
}
59 changes: 59 additions & 0 deletions main.pr
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import merge

const file_a = "A.o"
const file_b = "B.o"
const file_r = "AB2.o"

def main {
let obj_a = open_object_read(file_a)
let obj_b = open_object_read(file_b)
let new_obj = open_object_write(file_r)
new_obj.copy_arch_mach(obj_a)

obj_a.initialize_section(".text")
obj_a.initialize_section(".data")
obj_a.initialize_section(".llvm_addrsig")

obj_b.initialize_section(".text")
obj_b.initialize_section(".data")
obj_b.initialize_section(".llvm_addrsig")

obj_a.load_symbols()
obj_b.load_symbols()

obj_a.load_section_data(".text")
obj_a.load_section_data(".data")
obj_a.load_section_data(".llvm_addrsig")

obj_b.load_section_data(".text")
obj_b.load_section_data(".data")
obj_b.load_section_data(".llvm_addrsig")

new_obj.merge_section_data(obj_a, ".text")
new_obj.merge_section_data(obj_a, ".data")
new_obj.merge_section_data(obj_a, ".llvm_addrsig")

new_obj.merge_section_data(obj_b, ".text")
new_obj.merge_section_data(obj_b, ".data")
new_obj.merge_section_data(obj_b, ".llvm_addrsig")

new_obj.copy_symbols(obj_a)
new_obj.copy_symbols(obj_b)

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

new_obj.write_debug_info()
new_obj.write_symbols()
new_obj.write_debug_sections()

new_obj.write_section_data(".text")
new_obj.write_section_data(".data")
new_obj.write_section_data(".llvm_addrsig")

delete(new_obj)
delete(obj_a)
delete(obj_b)
}

main
Loading

0 comments on commit a841a67

Please sign in to comment.