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]
Example #7
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()