diff --git a/main.py b/main.py index eb53385..8b8e953 100644 --- a/main.py +++ b/main.py @@ -1,15 +1,18 @@ #!/bin/python +import os import sys import math +import argparse from bear import formats from elftools.dwarf.locationlists import LocationParser, LocationExpr from elftools.dwarf.dwarf_expr import DWARFExprParser, DWARFExprOp, DW_OP_opcode2name from bear.dwarfone import DWARFExprParserV1 +SCRIPT_VERSION = '0.1.0' configuration = { - "include_file_name": False, + 'include_file_name': False, } @@ -43,7 +46,7 @@ def load_children(parent_die): # QMessageBox(QMessageBox.Icon.Warning, "DWARF Explorer", # "This executable file is corrupt or incompatible with the current version of DWARF Explorer. Please consider creating a new issue at https://github.com/sevaa/dwex/, and share this file with the tech support.", # QMessageBox.StandardButton.Ok, QApplication.instance().win).show() - print("This executable file is corrupt or incompatible with the current version of Bear.") + print("This executable file is corrupt or incompatible.") parent_die._children = [] @@ -69,7 +72,8 @@ class Bear(): cu._lineprogram = None cu._exprparser = None return cu - di._unsorted_CUs = [decorate_cu(cu, i) for (i, cu) in enumerate(di.iter_CUs())] # We'll need them first thing, might as well load here + # We'll need them first thing, might as well load here + di._unsorted_CUs = [decorate_cu(cu, i) for (i, cu) in enumerate(di.iter_CUs())] if not len(di._unsorted_CUs): return None # Weird, but saw it once - debug sections present, but no CUs # For quick CU search by offset within the info section, regardless of sorting @@ -157,7 +161,8 @@ class Bear(): if die_type.tag == 'DW_TAG_base_type': real_type_name = safe_DIE_name(die_type, '?') if real_type_name != '?' and real_type_name != entry['type']: - entry['type'] = '{name} ({real})'.format(name=entry['type'], real=safe_DIE_name(die_type, '?')) + entry['type'] = '{name} ({real})'.format(name=entry['type'], + real=safe_DIE_name(die_type, '?')) elif die_type.tag == "DW_TAG_structure_type": load_children(die_type) child_dies = [] @@ -214,14 +219,16 @@ class Bear(): for CU in self.myVariables: for child in CU['children']: if configuration["include_file_name"]: - self.pettanko(child, CU['name']) + self.pettanko(child, CU['name'], ":") else: self.pettanko(child) - def pettanko(self, entry : dict, a_parent_name : str = ""): + def pettanko(self, entry : dict, a_parent_name : str = '', separator : str = '.'): flat_entry = dict() if a_parent_name: - flat_entry['name'] = '{0}.{1}'.format(a_parent_name, entry['name']) + flat_entry['name'] = '{parent}{separator}{child}'.format(parent=a_parent_name, + separator=separator, + child=entry['name']) else: flat_entry['name'] = entry['name'] @@ -245,7 +252,7 @@ class Bear(): if 'number_of_elements' in entry: for index in range(0, entry['number_of_elements']): kid = flat_entry.copy() - kid['name'] = '{0}[{1}]'.format(flat_entry['name'], index) + kid['name'] = '{name}[{index}]'.format(name=flat_entry['name'], index=index) kid['address'] = hex(int(flat_entry['address'], 16) + entry['size_byte'] * index) self.pettanko(kid) @@ -258,7 +265,8 @@ class Bear(): def pretty_print(self): for entry in self.flat_list: - print('{address}\t{variable_name}'.format(address=entry['address'], variable_name=entry['name'])) + print('{address}\t{variable_name}'.format(address=entry['address'], + variable_name=entry['name'])) def parse_location(self, die, attr): di = die.dwarfinfo @@ -287,7 +295,27 @@ def main(): from bear.patch import monkeypatch monkeypatch() - bear = Bear("/home/juraj/projects/Playground_C/build/playground_c") + parser = argparse.ArgumentParser( + description='Expands symbols (global variables) types.', + epilog='Data displayed by this script are informative only!' + ) + parser.add_argument('elf_file', metavar='file', type=str, nargs='?', + help='ELF file to try to extract symbols') + parser.add_argument('--include-file-name', dest='include_file_name', action='store_true', + help='Display filename at the beginning') + parser.add_argument('--version', action='version', + version='%(prog)s {version}'.format(version=SCRIPT_VERSION)) + + args = parser.parse_args() + + from pprint import pprint + configuration['include_file_name'] = args.include_file_name + + if not os.path.exists(args.elf_file): + eprint('File {elf_file} does not exist!'.format(elf_file=args.elf_file)) + exit(1) + + bear = Bear(args.elf_file) bear.flatten_type() bear.pretty_print()