def find_compile_unit(off): txts = dwarfutils.extract_dies_by_offset(args.dwarffile.name, off, parents=True) assert "TAG_compile_unit" in txts[0] cu_off = dwarfutils.extract_offset(txts[0]) return cu_off
def extract_and_parse_die(off): if off in DIEs: print("Using cached {}".format(DIEs[off]), file=sys.stderr) return txts = dwarfutils.extract_dies_by_offset(args.dwarffile.name, off) txt = txts[0] print(txt, file=sys.stderr) assert dwarfutils.extract_offset(txt) == off handlers = { "TAG_array_type": parse_array_type, "TAG_base_type": parse_base_type, "TAG_compile_unit": parse_compile_unit_type, "TAG_const_type": parse_const_type, "TAG_enumeration_type": parse_enumeration_type, "TAG_member": parse_member_type, "TAG_pointer_type": parse_pointer_type, "TAG_structure_type": parse_structure_type, "TAG_subroutine_type": parse_subroutine_type, "TAG_typedef": parse_typedef, "TAG_union_type": parse_union_type, "TAG_variable": parse_variable_type, "TAG_volatile_type": parse_volatile_type, } tag = dwarfutils.extract_tag(txt) try: return handlers[tag](txt) except KeyError: raise NotImplementedError
def parse_struct(parent_off): txts = dwarfutils.extract_dies_by_offset(args.dwarffile.name, parent_off, children=True) level = 0 for txt in txts[1:]: if "TAG_member" in txt: if level > 0: # ignore continue parse_member_type(txt) DIEs[parent_off].members.append(dwarfutils.extract_offset(txt)) elif "NULL" in txt: level -= 1 if level < 0: return elif "TAG_union_type" in txt: if not "AT_declaration" in txt: level += 1 if level == 0: parse_union_type(txt) elif "TAG_structure_type" in txt: if not "AT_declaration" in txt: level += 1 if level == 0: parse_structure_type(txt) else: raise NotImplementedError else: assert len(txts) == 1 or "AT_declaration" in txts[0]
def _extract_array_count(off): txts = dwarfutils.extract_dies_by_offset(args.dwarffile.name, off, children=True) assert dwarfutils.extract_tag(txts[0]) == "TAG_array_type" assert dwarfutils.extract_tag(txts[1]) == "TAG_subrange_type" try: count = dwarfutils.extract_count(txts[1]) except AttributeError: count = -1 return count
def parse_subroutine(parent_off): txts = dwarfutils.extract_dies_by_offset(args.dwarffile.name, parent_off, children=True) assert dwarfutils.extract_tag(txts[0]) == "TAG_subroutine_type" for txt in txts[1:]: if "TAG_formal_parameter" in txt: off = dwarfutils.extract_offset(txt) type_off, type_name = dwarfutils.extract_type(txt) extract_and_parse_die(type_off) DIEs[off] = DIEFormalParameter(ttype=(type_off, type_name)) DIEs[parent_off].members.append(off) elif "TAG_unspecified_parameters" in txt: pass elif "NULL" in txt: return else: raise NotImplementedError
def parse_enumeration(parent_off): txts = dwarfutils.extract_dies_by_offset(args.dwarffile.name, parent_off, children=True) assert dwarfutils.extract_tag(txts[0]) == "TAG_enumeration_type" for txt in txts[1:]: if "TAG_enumerator" in txt: off = dwarfutils.extract_offset(txt) DIEs[off] = DIEEnumerator( name=dwarfutils.extract_name(txt), const_value=dwarfutils.extract_const_value(txt)) DIEs[parent_off].members.append(off) elif "NULL" in txt: return else: raise NotImplementedError else: assert "AT_declaration" in txts[0]
#!/usr/bin/env python3 import argparse import dwarfutils if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("dwarffile", type=argparse.FileType()) parser.add_argument("symbol") parser.add_argument("--children", action="store_true") parser.add_argument("--filter") args = parser.parse_args() try: offset = int(args.symbol, 0) textdies = dwarfutils.extract_dies_by_offset(args.dwarffile.name, offset, children=args.children) except ValueError: name = args.symbol textdies = dwarfutils.extract_dies_by_name(args.dwarffile.name, name, children=args.children) for textdie in textdies: if not args.filter or args.filter in dwarfutils.extract_tag(textdie): print(textdie) print()