reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
  187
  188
  189
  190
  191
  192
  193
  194
  195
  196
  197
  198
  199
  200
  201
  202
  203
  204
  205
  206
  207
  208
  209
  210
  211
  212
  213
  214
  215
  216
  217
  218
  219
  220
  221
  222
  223
  224
  225
  226
  227
  228
  229
  230
  231
  232
  233
  234
  235
  236
  237
  238
  239
  240
  241
  242
  243
  244
  245
  246
  247
  248
  249
  250
  251
  252
  253
  254
  255
  256
""" This module implement Dwarf expression opcode parser. """

import lldb

# DWARF Expression operators.
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_skip                          = 0x2F
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_lit0                          = 0x30
DW_OP_lit1                          = 0x31
DW_OP_lit2                          = 0x32
DW_OP_lit3                          = 0x33
DW_OP_lit4                          = 0x34
DW_OP_lit5                          = 0x35
DW_OP_lit6                          = 0x36
DW_OP_lit7                          = 0x37
DW_OP_lit8                          = 0x38
DW_OP_lit9                          = 0x39
DW_OP_lit10                         = 0x3A
DW_OP_lit11                         = 0x3B
DW_OP_lit12                         = 0x3C
DW_OP_lit13                         = 0x3D
DW_OP_lit14                         = 0x3E
DW_OP_lit15                         = 0x3F
DW_OP_lit16                         = 0x40
DW_OP_lit17                         = 0x41
DW_OP_lit18                         = 0x42
DW_OP_lit19                         = 0x43
DW_OP_lit20                         = 0x44
DW_OP_lit21                         = 0x45
DW_OP_lit22                         = 0x46
DW_OP_lit23                         = 0x47
DW_OP_lit24                         = 0x48
DW_OP_lit25                         = 0x49
DW_OP_lit26                         = 0x4A
DW_OP_lit27                         = 0x4B
DW_OP_lit28                         = 0x4C
DW_OP_lit29                         = 0x4D
DW_OP_lit30                         = 0x4E
DW_OP_lit31                         = 0x4F
DW_OP_reg0                          = 0x50
DW_OP_reg1                          = 0x51
DW_OP_reg2                          = 0x52
DW_OP_reg3                          = 0x53
DW_OP_reg4                          = 0x54
DW_OP_reg5                          = 0x55
DW_OP_reg6                          = 0x56
DW_OP_reg7                          = 0x57
DW_OP_reg8                          = 0x58
DW_OP_reg9                          = 0x59
DW_OP_reg10                         = 0x5A
DW_OP_reg11                         = 0x5B
DW_OP_reg12                         = 0x5C
DW_OP_reg13                         = 0x5D
DW_OP_reg14                         = 0x5E
DW_OP_reg15                         = 0x5F
DW_OP_reg16                         = 0x60
DW_OP_reg17                         = 0x61
DW_OP_reg18                         = 0x62
DW_OP_reg19                         = 0x63
DW_OP_reg20                         = 0x64
DW_OP_reg21                         = 0x65
DW_OP_reg22                         = 0x66
DW_OP_reg23                         = 0x67
DW_OP_reg24                         = 0x68
DW_OP_reg25                         = 0x69
DW_OP_reg26                         = 0x6A
DW_OP_reg27                         = 0x6B
DW_OP_reg28                         = 0x6C
DW_OP_reg29                         = 0x6D
DW_OP_reg30                         = 0x6E
DW_OP_reg31                         = 0x6F
DW_OP_breg0                         = 0x70
DW_OP_breg1                         = 0x71
DW_OP_breg2                         = 0x72
DW_OP_breg3                         = 0x73
DW_OP_breg4                         = 0x74
DW_OP_breg5                         = 0x75
DW_OP_breg6                         = 0x76
DW_OP_breg7                         = 0x77
DW_OP_breg8                         = 0x78
DW_OP_breg9                         = 0x79
DW_OP_breg10                        = 0x7A
DW_OP_breg11                        = 0x7B
DW_OP_breg12                        = 0x7C
DW_OP_breg13                        = 0x7D
DW_OP_breg14                        = 0x7E
DW_OP_breg15                        = 0x7F
DW_OP_breg16                        = 0x80
DW_OP_breg17                        = 0x81
DW_OP_breg18                        = 0x82
DW_OP_breg19                        = 0x83
DW_OP_breg20                        = 0x84
DW_OP_breg21                        = 0x85
DW_OP_breg22                        = 0x86
DW_OP_breg23                        = 0x87
DW_OP_breg24                        = 0x88
DW_OP_breg25                        = 0x89
DW_OP_breg26                        = 0x8A
DW_OP_breg27                        = 0x8B
DW_OP_breg28                        = 0x8C
DW_OP_breg29                        = 0x8D
DW_OP_breg30                        = 0x8E
DW_OP_breg31                        = 0x8F
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
DW_OP_implicit_value                = 0x9E
DW_OP_stack_value                   = 0x9F
DW_OP_lo_user                       = 0xE0
DW_OP_GNU_push_tls_address          = 0xE0
DW_OP_APPLE_uninit                  = 0xF0
DW_OP_hi_user                       = 0xFF


class DwarfOpcodeParser(object):

    def updateRegInfoBitsize(self, reg_info, byte_order):
        """ Update the regInfo bit size. """

        # Evaluate Dwarf Expression
        expr_result = self.evaluateDwarfExpression(reg_info["dynamic_size_dwarf_expr_bytes"],
                                                    byte_order)

        if expr_result == 0:
            reg_info["bitsize"] = 32
        elif expr_result == 1:
            reg_info["bitsize"] = 64


    def evaluateDwarfExpression(self, dwarf_opcode, byte_order):
        """Evaluate Dwarf Expression. """

        dwarf_opcode = [dwarf_opcode[i:i+2] for i in range(0,len(dwarf_opcode),2)]
        dwarf_data = []
        for index in range(len(dwarf_opcode)):

            if index < len(dwarf_opcode):
                val = int(dwarf_opcode[index], 16)
            else:
                break

            if val == DW_OP_regx:
                # Read register number
                self.assertTrue(len(dwarf_opcode) > (index + 1))
                reg_no = int(dwarf_opcode.pop(index + 1), 16)

                self.reset_test_sequence()
                # Read register value
                self.test_sequence.add_log_lines(
                             ["read packet: $p{0:x}#00".format(reg_no),
                             {"direction": "send", "regex": r"^\$([0-9a-fA-F]+)#",
                             "capture": {1: "p_response"}}],True)

                Context = self.expect_gdbremote_sequence()
                self.assertIsNotNone(Context)
                p_response = Context.get("p_response")
                self.assertIsNotNone(p_response)

                if byte_order == lldb.eByteOrderLittle:
                   # In case of little endian
                   # first decode the HEX ASCII bytes and then reverse it
                   # to get actual value of SR register
                   p_response = "".join(reversed([p_response[i:i+2] for i in range(0,
                                                  len(p_response),2)]))
                # Push register value
                dwarf_data.append(int(p_response,16))

            elif val == DW_OP_lit1:
                # Push literal 1
                dwarf_data.append(1)

            elif val == DW_OP_lit26:
                # Push literal 26
                dwarf_data.append(26)

            elif val == DW_OP_shl:
                # left shift and push the result back
                self.assertTrue(len(dwarf_data) > 1)
                shift_amount = dwarf_data.pop()
                val_to_shift = dwarf_data.pop()
                result = val_to_shift << shift_amount
                dwarf_data.append(result)

            elif val == DW_OP_shr:
                # Right shift and push the result back
                self.assertTrue(len(dwarf_data) > 1)
                shift_amount = dwarf_data.pop()
                val_to_shift = dwarf_data.pop()
                result = val_to_shift >> shift_amount
                dwarf_data.append(result)

            elif val == DW_OP_and:
                # And of topmost 2 elements and push the result back
                first_ele = dwarf_data.pop()
                second_ele = dwarf_data.pop()
                result = first_ele & second_ele
                dwarf_data.append(result)

            else:
                self.assertTrue(False and "Unprocess Dwarf Opcode")

        self.assertTrue(len(dwarf_data) == 1)
        expr_result = dwarf_data.pop()
        return expr_result