-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Deal with more data, we're getting somewhere for sure!
- Loading branch information
1 parent
38a1c2b
commit a841a67
Showing
3 changed files
with
296 additions
and
244 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Oops, something went wrong.