#-------------------------------------------------------------------------------
# elftools: dwarf/dwarf_expr.py
#
# Decoding DWARF expressions
#
# Eli Bendersky (eliben@gmail.com)
# This code is in the public domain
#-------------------------------------------------------------------------------
from cStringIO import StringIO

from ..common.utils import struct_parse, bytelist2string


# DWARF expression opcodes. name -> opcode mapping
DW_OP_name2opcode = dict(
    DW_OP_addr=0x03,
    DW_OP_deref=0x06,
    DW_OP_const1u=0x08,
    DW_OP_const1s=0x09,
    DW_OP_const2u=0x0a,
    DW_OP_const2s=0x0b,
    DW_OP_const4u=0x0c,
    DW_OP_const4s=0x0d,
    DW_OP_const8u=0x0e,
    DW_OP_const8s=0x0f,
    DW_OP_constu=0x10,
    DW_OP_consts=0x11,
    DW_OP_dup=0x12,
    DW_OP_drop=0x13,
    DW_OP_over=0x14,
    DW_OP_pick=0x15,
    DW_OP_swap=0x16,
    DW_OP_rot=0x17,
    DW_OP_xderef=0x18,
    DW_OP_abs=0x19,
    DW_OP_and=0x1a,
    DW_OP_div=0x1b,
    DW_OP_minus=0x1c,
    DW_OP_mod=0x1d,
    DW_OP_mul=0x1e,
    DW_OP_neg=0x1f,
    DW_OP_not=0x20,
    DW_OP_or=0x21,
    DW_OP_plus=0x22,
    DW_OP_plus_uconst=0x23,
    DW_OP_shl=0x24,
    DW_OP_shr=0x25,
    DW_OP_shra=0x26,
    DW_OP_xor=0x27,
    DW_OP_bra=0x28,
    DW_OP_eq=0x29,
    DW_OP_ge=0x2a,
    DW_OP_gt=0x2b,
    DW_OP_le=0x2c,
    DW_OP_lt=0x2d,
    DW_OP_ne=0x2e,
    DW_OP_skip=0x2f,
    DW_OP_regx=0x90,
    DW_OP_fbreg=0x91,
    DW_OP_bregx=0x92,
    DW_OP_piece=0x93,
    DW_OP_deref_size=0x94,
    DW_OP_xderef_size=0x95,
    DW_OP_nop=0x96,
    DW_OP_push_object_address=0x97,
    DW_OP_call2=0x98,
    DW_OP_call4=0x99,
    DW_OP_call_ref=0x9a,
    DW_OP_form_tls_address=0x9b,
    DW_OP_call_frame_cfa=0x9c,
    DW_OP_bit_piece=0x9d,
)

def _generate_dynamic_values(map, prefix, index_start, index_end, value_start):
    """ Generate values in a map (dict) dynamically. Each key starts with
        a (string) prefix, followed by an index in the inclusive range
        [index_start, index_end]. The values start at value_start.
    """
    for index in range(index_start, index_end + 1):
        name = '%s%s' % (prefix, index)
        value = value_start + index - index_start
        map[name] = value

_generate_dynamic_values(DW_OP_name2opcode, 'DW_OP_lit', 0, 31, 0x30)
_generate_dynamic_values(DW_OP_name2opcode, 'DW_OP_reg', 0, 31, 0x50)
_generate_dynamic_values(DW_OP_name2opcode, 'DW_OP_breg', 0, 31, 0x70)

# opcode -> name mapping
DW_OP_opcode2name = dict((v, k) for k, v in DW_OP_name2opcode.iteritems())


class GenericExprVisitor(object):
    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, loc_expr):
        """ Process (visit) a DWARF expression. Currently two possible
            types are supported for expr:

            1. File-like stream object
            2. List of byte values (the result of parsed DW_FORM_block*
               attributes).
        """
        if hasattr(loc_expr, 'read') and hasattr(loc_expr, 'seek'):
            # looks like a stream
            self.stream = loc_expr
        else:
            self.stream = StringIO(bytelist2string(loc_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('')))


class ExprDumper(GenericExprVisitor):
    def __init__(self, structs):
        super(ExprDumper, self).__init__(structs)
        self._init_lookups()
        self._str_parts = []

    def clear(self):
        self._str_parts = []

    def get_str(self):
        return '; '.join(self._str_parts)

    def _init_lookups(self):
        self._ops_with_decimal_arg = set([
            'DW_OP_const1u', 'DW_OP_const1s', 'DW_OP_const2u', 'DW_OP_const2s',
            'DW_OP_const4u', 'DW_OP_const4s', 'DW_OP_constu', 'DW_OP_consts',
            'DW_OP_pick', 'DW_OP_plus_uconst', 'DW_OP_bra', 'DW_OP_skip',
            'DW_OP_fbreg', 'DW_OP_piece', 'DW_OP_deref_size',
            'DW_OP_xderef_size', 'DW_OP_regx',])
        
        for n in range(0, 32):
            self._ops_with_decimal_arg.add('DW_OP_breg%s' % n)
        
        self._ops_with_two_decimal_args = set([
            'DW_OP_const8u', 'DW_OP_const8s', 'DW_OP_bregx', 'DW_OP_bit_piece'])

        self._ops_with_hex_arg = set(
            ['DW_OP_addr', 'DW_OP_call2', 'DW_OP_call4', 'DW_OP_call_ref'])

    def _after_visit(self, opcode, opcode_name, args):
        self._str_parts.append(self._dump_to_string(opcode, opcode_name, args))

    def _dump_to_string(self, opcode, opcode_name, args):
        if len(args) == 0:
            return opcode_name
        elif opcode_name in self._ops_with_decimal_arg:
            return '%s: %s' % (opcode_name, args[0])
        elif opcode_name in self._ops_with_hex_arg:
            return '%s: %x' % (opcode_name, args[0])
        elif opcode_name in self._ops_with_two_decimal_args:
            return '%s: %s %s' % (opcode_name, args[0], args[1])
        else:
            return '<unknown %s>' % opcode_name



