From: Eli Bendersky Date: Fri, 13 Mar 2020 13:26:02 +0000 (-0700) Subject: DWARF expr: removing old GenericExprVisitor X-Git-Tag: v0.27~45 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4cf5cb07c772002ee736dba17fc685a260817b7a;p=pyelftools.git DWARF expr: removing old GenericExprVisitor --- diff --git a/elftools/dwarf/descriptions.py b/elftools/dwarf/descriptions.py index c77abb7..5007a80 100644 --- a/elftools/dwarf/descriptions.py +++ b/elftools/dwarf/descriptions.py @@ -9,7 +9,7 @@ from collections import defaultdict from .constants import * -from .dwarf_expr import GenericExprVisitor, parse_expr +from .dwarf_expr import parse_expr from .die import DIE from ..common.utils import preserve_stream_pos, dwarf_assert from ..common.py3compat import bytes2str diff --git a/elftools/dwarf/dwarf_expr.py b/elftools/dwarf/dwarf_expr.py index c5b6bda..4e47934 100644 --- a/elftools/dwarf/dwarf_expr.py +++ b/elftools/dwarf/dwarf_expr.py @@ -104,173 +104,6 @@ _generate_dynamic_values(DW_OP_name2opcode, 'DW_OP_breg', 0, 31, 0x70) DW_OP_opcode2name = dict((v, k) for k, v in iteritems(DW_OP_name2opcode)) -class GenericExprVisitor(object): - """ A DWARF expression is a sequence of instructions encoded in a block - of bytes. This class decodes the sequence into discrete instructions - with their arguments and allows generic "visiting" to process them. - - Usage: subclass this class, and override the needed methods. The - easiest way would be to just override _after_visit, which gets passed - each decoded instruction (with its arguments) in order. Clients of - the visitor then just execute process_expr. The subclass can keep - its own internal information updated in _after_visit and provide - methods to extract it. For a good example of this usage, see the - ExprDumper class in the descriptions module. - - A more complex usage could be to override visiting methods for - specific instructions, by placing them into the dispatch table. - """ - def __init__(self, structs): - self.structs = structs - self._init_dispatch_table() - self.stream = None - self._cur_opcode = None - self._cur_opcode_name = None - self._cur_args = [] - - def process_expr(self, expr): - """ Process (visit) a DWARF expression. expr should be a list of - (integer) byte values. - """ - self.stream = BytesIO(bytelist2string(expr)) - - while True: - # Get the next opcode from the stream. If nothing is left in the - # stream, we're done. - byte = self.stream.read(1) - if len(byte) == 0: - break - - # Decode the opcode and its name - self._cur_opcode = ord(byte) - self._cur_opcode_name = DW_OP_opcode2name.get( - self._cur_opcode, 'OP:0x%x' % self._cur_opcode) - # Will be filled in by visitors - self._cur_args = [] - - # Dispatch to a visitor function - visitor = self._dispatch_table.get( - self._cur_opcode, - self._default_visitor) - visitor(self._cur_opcode, self._cur_opcode_name) - - # Finally call the post-visit function - self._after_visit( - self._cur_opcode, self._cur_opcode_name, self._cur_args) - - def _after_visit(self, opcode, opcode_name, args): - pass - - def _default_visitor(self, opcode, opcode_name): - pass - - def _visit_OP_with_no_args(self, opcode, opcode_name): - self._cur_args = [] - - def _visit_OP_addr(self, opcode, opcode_name): - self._cur_args = [ - struct_parse(self.structs.Dwarf_target_addr(''), self.stream)] - - def _make_visitor_arg_struct(self, struct_arg): - """ Create a visitor method for an opcode that that accepts a single - argument, specified by a struct. - """ - def visitor(opcode, opcode_name): - self._cur_args = [struct_parse(struct_arg, self.stream)] - return visitor - - def _make_visitor_arg_struct2(self, struct_arg1, struct_arg2): - """ Create a visitor method for an opcode that that accepts two - arguments, specified by structs. - """ - def visitor(opcode, opcode_name): - self._cur_args = [ - struct_parse(struct_arg1, self.stream), - struct_parse(struct_arg2, self.stream)] - return visitor - - def _init_dispatch_table(self): - self._dispatch_table = {} - def add(opcode_name, func): - self._dispatch_table[DW_OP_name2opcode[opcode_name]] = func - - add('DW_OP_addr', self._visit_OP_addr) - add('DW_OP_const1u', - self._make_visitor_arg_struct(self.structs.Dwarf_uint8(''))) - add('DW_OP_const1s', - self._make_visitor_arg_struct(self.structs.Dwarf_int8(''))) - add('DW_OP_const2u', - self._make_visitor_arg_struct(self.structs.Dwarf_uint16(''))) - add('DW_OP_const2s', - self._make_visitor_arg_struct(self.structs.Dwarf_int16(''))) - add('DW_OP_const4u', - self._make_visitor_arg_struct(self.structs.Dwarf_uint32(''))) - add('DW_OP_const4s', - self._make_visitor_arg_struct(self.structs.Dwarf_int32(''))) - add('DW_OP_const8u', - self._make_visitor_arg_struct2( - self.structs.Dwarf_uint32(''), - self.structs.Dwarf_uint32(''))) - add('DW_OP_const8s', - self._make_visitor_arg_struct2( - self.structs.Dwarf_int32(''), - self.structs.Dwarf_int32(''))) - add('DW_OP_constu', - self._make_visitor_arg_struct(self.structs.Dwarf_uleb128(''))) - add('DW_OP_consts', - self._make_visitor_arg_struct(self.structs.Dwarf_sleb128(''))) - add('DW_OP_pick', - self._make_visitor_arg_struct(self.structs.Dwarf_uint8(''))) - add('DW_OP_plus_uconst', - self._make_visitor_arg_struct(self.structs.Dwarf_uleb128(''))) - add('DW_OP_bra', - self._make_visitor_arg_struct(self.structs.Dwarf_int16(''))) - add('DW_OP_skip', - self._make_visitor_arg_struct(self.structs.Dwarf_int16(''))) - - for opname in [ 'DW_OP_deref', 'DW_OP_dup', 'DW_OP_drop', 'DW_OP_over', - 'DW_OP_swap', 'DW_OP_swap', 'DW_OP_rot', 'DW_OP_xderef', - 'DW_OP_abs', 'DW_OP_and', 'DW_OP_div', 'DW_OP_minus', - 'DW_OP_mod', 'DW_OP_mul', 'DW_OP_neg', 'DW_OP_not', - 'DW_OP_plus', 'DW_OP_shl', 'DW_OP_shr', 'DW_OP_shra', - 'DW_OP_xor', 'DW_OP_eq', 'DW_OP_ge', 'DW_OP_gt', - 'DW_OP_le', 'DW_OP_lt', 'DW_OP_ne', 'DW_OP_nop', - 'DW_OP_push_object_address', 'DW_OP_form_tls_address', - 'DW_OP_call_frame_cfa']: - add(opname, self._visit_OP_with_no_args) - - for n in range(0, 32): - add('DW_OP_lit%s' % n, self._visit_OP_with_no_args) - add('DW_OP_reg%s' % n, self._visit_OP_with_no_args) - add('DW_OP_breg%s' % n, - self._make_visitor_arg_struct(self.structs.Dwarf_sleb128(''))) - - add('DW_OP_fbreg', - self._make_visitor_arg_struct(self.structs.Dwarf_sleb128(''))) - add('DW_OP_regx', - self._make_visitor_arg_struct(self.structs.Dwarf_uleb128(''))) - add('DW_OP_bregx', - self._make_visitor_arg_struct2( - self.structs.Dwarf_uleb128(''), - self.structs.Dwarf_sleb128(''))) - add('DW_OP_piece', - self._make_visitor_arg_struct(self.structs.Dwarf_uleb128(''))) - add('DW_OP_bit_piece', - self._make_visitor_arg_struct2( - self.structs.Dwarf_uleb128(''), - self.structs.Dwarf_uleb128(''))) - add('DW_OP_deref_size', - self._make_visitor_arg_struct(self.structs.Dwarf_int8(''))) - add('DW_OP_xderef_size', - self._make_visitor_arg_struct(self.structs.Dwarf_int8(''))) - add('DW_OP_call2', - self._make_visitor_arg_struct(self.structs.Dwarf_uint16(''))) - add('DW_OP_call4', - self._make_visitor_arg_struct(self.structs.Dwarf_uint32(''))) - add('DW_OP_call_ref', - self._make_visitor_arg_struct(self.structs.Dwarf_offset(''))) - - DwarfExprOp = namedtuple('DwarfExprOp', 'op op_name args')