1f440244dSNitesh Jain""" This module implement Dwarf expression opcode parser. """ 2f440244dSNitesh Jain 3f440244dSNitesh Jainimport lldb 4f440244dSNitesh Jain 5f440244dSNitesh Jain# DWARF Expression operators. 6f440244dSNitesh JainDW_OP_addr = 0x03 7f440244dSNitesh JainDW_OP_deref = 0x06 8f440244dSNitesh JainDW_OP_const1u = 0x08 9f440244dSNitesh JainDW_OP_const1s = 0x09 10f440244dSNitesh JainDW_OP_const2u = 0x0A 11f440244dSNitesh JainDW_OP_const2s = 0x0B 12f440244dSNitesh JainDW_OP_const4u = 0x0C 13f440244dSNitesh JainDW_OP_const4s = 0x0D 14f440244dSNitesh JainDW_OP_const8u = 0x0E 15f440244dSNitesh JainDW_OP_const8s = 0x0F 16f440244dSNitesh JainDW_OP_constu = 0x10 17f440244dSNitesh JainDW_OP_consts = 0x11 18f440244dSNitesh JainDW_OP_dup = 0x12 19f440244dSNitesh JainDW_OP_drop = 0x13 20f440244dSNitesh JainDW_OP_over = 0x14 21f440244dSNitesh JainDW_OP_pick = 0x15 22f440244dSNitesh JainDW_OP_swap = 0x16 23f440244dSNitesh JainDW_OP_rot = 0x17 24f440244dSNitesh JainDW_OP_xderef = 0x18 25f440244dSNitesh JainDW_OP_abs = 0x19 26f440244dSNitesh JainDW_OP_and = 0x1A 27f440244dSNitesh JainDW_OP_div = 0x1B 28f440244dSNitesh JainDW_OP_minus = 0x1C 29f440244dSNitesh JainDW_OP_mod = 0x1D 30f440244dSNitesh JainDW_OP_mul = 0x1E 31f440244dSNitesh JainDW_OP_neg = 0x1F 32f440244dSNitesh JainDW_OP_not = 0x20 33f440244dSNitesh JainDW_OP_or = 0x21 34f440244dSNitesh JainDW_OP_plus = 0x22 35f440244dSNitesh JainDW_OP_plus_uconst = 0x23 36f440244dSNitesh JainDW_OP_shl = 0x24 37f440244dSNitesh JainDW_OP_shr = 0x25 38f440244dSNitesh JainDW_OP_shra = 0x26 39f440244dSNitesh JainDW_OP_xor = 0x27 40f440244dSNitesh JainDW_OP_skip = 0x2F 41f440244dSNitesh JainDW_OP_bra = 0x28 42f440244dSNitesh JainDW_OP_eq = 0x29 43f440244dSNitesh JainDW_OP_ge = 0x2A 44f440244dSNitesh JainDW_OP_gt = 0x2B 45f440244dSNitesh JainDW_OP_le = 0x2C 46f440244dSNitesh JainDW_OP_lt = 0x2D 47f440244dSNitesh JainDW_OP_ne = 0x2E 48f440244dSNitesh JainDW_OP_lit0 = 0x30 49f440244dSNitesh JainDW_OP_lit1 = 0x31 50f440244dSNitesh JainDW_OP_lit2 = 0x32 51f440244dSNitesh JainDW_OP_lit3 = 0x33 52f440244dSNitesh JainDW_OP_lit4 = 0x34 53f440244dSNitesh JainDW_OP_lit5 = 0x35 54f440244dSNitesh JainDW_OP_lit6 = 0x36 55f440244dSNitesh JainDW_OP_lit7 = 0x37 56f440244dSNitesh JainDW_OP_lit8 = 0x38 57f440244dSNitesh JainDW_OP_lit9 = 0x39 58f440244dSNitesh JainDW_OP_lit10 = 0x3A 59f440244dSNitesh JainDW_OP_lit11 = 0x3B 60f440244dSNitesh JainDW_OP_lit12 = 0x3C 61f440244dSNitesh JainDW_OP_lit13 = 0x3D 62f440244dSNitesh JainDW_OP_lit14 = 0x3E 63f440244dSNitesh JainDW_OP_lit15 = 0x3F 64f440244dSNitesh JainDW_OP_lit16 = 0x40 65f440244dSNitesh JainDW_OP_lit17 = 0x41 66f440244dSNitesh JainDW_OP_lit18 = 0x42 67f440244dSNitesh JainDW_OP_lit19 = 0x43 68f440244dSNitesh JainDW_OP_lit20 = 0x44 69f440244dSNitesh JainDW_OP_lit21 = 0x45 70f440244dSNitesh JainDW_OP_lit22 = 0x46 71f440244dSNitesh JainDW_OP_lit23 = 0x47 72f440244dSNitesh JainDW_OP_lit24 = 0x48 73f440244dSNitesh JainDW_OP_lit25 = 0x49 74f440244dSNitesh JainDW_OP_lit26 = 0x4A 75f440244dSNitesh JainDW_OP_lit27 = 0x4B 76f440244dSNitesh JainDW_OP_lit28 = 0x4C 77f440244dSNitesh JainDW_OP_lit29 = 0x4D 78f440244dSNitesh JainDW_OP_lit30 = 0x4E 79f440244dSNitesh JainDW_OP_lit31 = 0x4F 80f440244dSNitesh JainDW_OP_reg0 = 0x50 81f440244dSNitesh JainDW_OP_reg1 = 0x51 82f440244dSNitesh JainDW_OP_reg2 = 0x52 83f440244dSNitesh JainDW_OP_reg3 = 0x53 84f440244dSNitesh JainDW_OP_reg4 = 0x54 85f440244dSNitesh JainDW_OP_reg5 = 0x55 86f440244dSNitesh JainDW_OP_reg6 = 0x56 87f440244dSNitesh JainDW_OP_reg7 = 0x57 88f440244dSNitesh JainDW_OP_reg8 = 0x58 89f440244dSNitesh JainDW_OP_reg9 = 0x59 90f440244dSNitesh JainDW_OP_reg10 = 0x5A 91f440244dSNitesh JainDW_OP_reg11 = 0x5B 92f440244dSNitesh JainDW_OP_reg12 = 0x5C 93f440244dSNitesh JainDW_OP_reg13 = 0x5D 94f440244dSNitesh JainDW_OP_reg14 = 0x5E 95f440244dSNitesh JainDW_OP_reg15 = 0x5F 96f440244dSNitesh JainDW_OP_reg16 = 0x60 97f440244dSNitesh JainDW_OP_reg17 = 0x61 98f440244dSNitesh JainDW_OP_reg18 = 0x62 99f440244dSNitesh JainDW_OP_reg19 = 0x63 100f440244dSNitesh JainDW_OP_reg20 = 0x64 101f440244dSNitesh JainDW_OP_reg21 = 0x65 102f440244dSNitesh JainDW_OP_reg22 = 0x66 103f440244dSNitesh JainDW_OP_reg23 = 0x67 104f440244dSNitesh JainDW_OP_reg24 = 0x68 105f440244dSNitesh JainDW_OP_reg25 = 0x69 106f440244dSNitesh JainDW_OP_reg26 = 0x6A 107f440244dSNitesh JainDW_OP_reg27 = 0x6B 108f440244dSNitesh JainDW_OP_reg28 = 0x6C 109f440244dSNitesh JainDW_OP_reg29 = 0x6D 110f440244dSNitesh JainDW_OP_reg30 = 0x6E 111f440244dSNitesh JainDW_OP_reg31 = 0x6F 112f440244dSNitesh JainDW_OP_breg0 = 0x70 113f440244dSNitesh JainDW_OP_breg1 = 0x71 114f440244dSNitesh JainDW_OP_breg2 = 0x72 115f440244dSNitesh JainDW_OP_breg3 = 0x73 116f440244dSNitesh JainDW_OP_breg4 = 0x74 117f440244dSNitesh JainDW_OP_breg5 = 0x75 118f440244dSNitesh JainDW_OP_breg6 = 0x76 119f440244dSNitesh JainDW_OP_breg7 = 0x77 120f440244dSNitesh JainDW_OP_breg8 = 0x78 121f440244dSNitesh JainDW_OP_breg9 = 0x79 122f440244dSNitesh JainDW_OP_breg10 = 0x7A 123f440244dSNitesh JainDW_OP_breg11 = 0x7B 124f440244dSNitesh JainDW_OP_breg12 = 0x7C 125f440244dSNitesh JainDW_OP_breg13 = 0x7D 126f440244dSNitesh JainDW_OP_breg14 = 0x7E 127f440244dSNitesh JainDW_OP_breg15 = 0x7F 128f440244dSNitesh JainDW_OP_breg16 = 0x80 129f440244dSNitesh JainDW_OP_breg17 = 0x81 130f440244dSNitesh JainDW_OP_breg18 = 0x82 131f440244dSNitesh JainDW_OP_breg19 = 0x83 132f440244dSNitesh JainDW_OP_breg20 = 0x84 133f440244dSNitesh JainDW_OP_breg21 = 0x85 134f440244dSNitesh JainDW_OP_breg22 = 0x86 135f440244dSNitesh JainDW_OP_breg23 = 0x87 136f440244dSNitesh JainDW_OP_breg24 = 0x88 137f440244dSNitesh JainDW_OP_breg25 = 0x89 138f440244dSNitesh JainDW_OP_breg26 = 0x8A 139f440244dSNitesh JainDW_OP_breg27 = 0x8B 140f440244dSNitesh JainDW_OP_breg28 = 0x8C 141f440244dSNitesh JainDW_OP_breg29 = 0x8D 142f440244dSNitesh JainDW_OP_breg30 = 0x8E 143f440244dSNitesh JainDW_OP_breg31 = 0x8F 144f440244dSNitesh JainDW_OP_regx = 0x90 145f440244dSNitesh JainDW_OP_fbreg = 0x91 146f440244dSNitesh JainDW_OP_bregx = 0x92 147f440244dSNitesh JainDW_OP_piece = 0x93 148f440244dSNitesh JainDW_OP_deref_size = 0x94 149f440244dSNitesh JainDW_OP_xderef_size = 0x95 150f440244dSNitesh JainDW_OP_nop = 0x96 151f440244dSNitesh JainDW_OP_push_object_address = 0x97 152f440244dSNitesh JainDW_OP_call2 = 0x98 153f440244dSNitesh JainDW_OP_call4 = 0x99 154f440244dSNitesh JainDW_OP_call_ref = 0x9A 155f440244dSNitesh JainDW_OP_form_tls_address = 0x9B 156f440244dSNitesh JainDW_OP_call_frame_cfa = 0x9C 157f440244dSNitesh JainDW_OP_bit_piece = 0x9D 158f440244dSNitesh JainDW_OP_implicit_value = 0x9E 159f440244dSNitesh JainDW_OP_stack_value = 0x9F 160f440244dSNitesh JainDW_OP_lo_user = 0xE0 161f440244dSNitesh JainDW_OP_GNU_push_tls_address = 0xE0 162f440244dSNitesh JainDW_OP_hi_user = 0xFF 163f440244dSNitesh Jain 164f440244dSNitesh Jain 165f440244dSNitesh Jainclass DwarfOpcodeParser(object): 166f440244dSNitesh Jain def updateRegInfoBitsize(self, reg_info, byte_order): 167f440244dSNitesh Jain """Update the regInfo bit size.""" 168f440244dSNitesh Jain 169f440244dSNitesh Jain # Evaluate Dwarf Expression 170*2238dcc3SJonas Devlieghere expr_result = self.evaluateDwarfExpression( 171*2238dcc3SJonas Devlieghere reg_info["dynamic_size_dwarf_expr_bytes"], byte_order 172*2238dcc3SJonas Devlieghere ) 173f440244dSNitesh Jain 174f440244dSNitesh Jain if expr_result == 0: 175f440244dSNitesh Jain reg_info["bitsize"] = 32 176f440244dSNitesh Jain elif expr_result == 1: 177f440244dSNitesh Jain reg_info["bitsize"] = 64 178f440244dSNitesh Jain 179f440244dSNitesh Jain def evaluateDwarfExpression(self, dwarf_opcode, byte_order): 180f440244dSNitesh Jain """Evaluate Dwarf Expression.""" 181f440244dSNitesh Jain 182f440244dSNitesh Jain dwarf_opcode = [dwarf_opcode[i : i + 2] for i in range(0, len(dwarf_opcode), 2)] 183f440244dSNitesh Jain dwarf_data = [] 184f440244dSNitesh Jain for index in range(len(dwarf_opcode)): 185f440244dSNitesh Jain if index < len(dwarf_opcode): 186f440244dSNitesh Jain val = int(dwarf_opcode[index], 16) 187f440244dSNitesh Jain else: 188f440244dSNitesh Jain break 189f440244dSNitesh Jain 190f440244dSNitesh Jain if val == DW_OP_regx: 191f440244dSNitesh Jain # Read register number 192f440244dSNitesh Jain self.assertTrue(len(dwarf_opcode) > (index + 1)) 193f440244dSNitesh Jain reg_no = int(dwarf_opcode.pop(index + 1), 16) 194f440244dSNitesh Jain 195f440244dSNitesh Jain self.reset_test_sequence() 196f440244dSNitesh Jain # Read register value 197f440244dSNitesh Jain self.test_sequence.add_log_lines( 198*2238dcc3SJonas Devlieghere [ 199*2238dcc3SJonas Devlieghere "read packet: $p{0:x}#00".format(reg_no), 200*2238dcc3SJonas Devlieghere { 201*2238dcc3SJonas Devlieghere "direction": "send", 202*2238dcc3SJonas Devlieghere "regex": r"^\$([0-9a-fA-F]+)#", 203*2238dcc3SJonas Devlieghere "capture": {1: "p_response"}, 204*2238dcc3SJonas Devlieghere }, 205*2238dcc3SJonas Devlieghere ], 206*2238dcc3SJonas Devlieghere True, 207*2238dcc3SJonas Devlieghere ) 208f440244dSNitesh Jain 209f440244dSNitesh Jain Context = self.expect_gdbremote_sequence() 210f440244dSNitesh Jain self.assertIsNotNone(Context) 211f440244dSNitesh Jain p_response = Context.get("p_response") 212f440244dSNitesh Jain self.assertIsNotNone(p_response) 213f440244dSNitesh Jain 214f440244dSNitesh Jain if byte_order == lldb.eByteOrderLittle: 215f440244dSNitesh Jain # In case of little endian 216f440244dSNitesh Jain # first decode the HEX ASCII bytes and then reverse it 217f440244dSNitesh Jain # to get actual value of SR register 218*2238dcc3SJonas Devlieghere p_response = "".join( 219*2238dcc3SJonas Devlieghere reversed( 220*2238dcc3SJonas Devlieghere [ 221*2238dcc3SJonas Devlieghere p_response[i : i + 2] 222*2238dcc3SJonas Devlieghere for i in range(0, len(p_response), 2) 223*2238dcc3SJonas Devlieghere ] 224*2238dcc3SJonas Devlieghere ) 225*2238dcc3SJonas Devlieghere ) 226f440244dSNitesh Jain # Push register value 227f440244dSNitesh Jain dwarf_data.append(int(p_response, 16)) 228f440244dSNitesh Jain 229f440244dSNitesh Jain elif val == DW_OP_lit1: 230f440244dSNitesh Jain # Push literal 1 231f440244dSNitesh Jain dwarf_data.append(1) 232f440244dSNitesh Jain 233f440244dSNitesh Jain elif val == DW_OP_lit26: 234f440244dSNitesh Jain # Push literal 26 235f440244dSNitesh Jain dwarf_data.append(26) 236f440244dSNitesh Jain 237f440244dSNitesh Jain elif val == DW_OP_shl: 238f440244dSNitesh Jain # left shift and push the result back 239f440244dSNitesh Jain self.assertTrue(len(dwarf_data) > 1) 240f440244dSNitesh Jain shift_amount = dwarf_data.pop() 241f440244dSNitesh Jain val_to_shift = dwarf_data.pop() 242f440244dSNitesh Jain result = val_to_shift << shift_amount 243f440244dSNitesh Jain dwarf_data.append(result) 244f440244dSNitesh Jain 245f440244dSNitesh Jain elif val == DW_OP_shr: 246f440244dSNitesh Jain # Right shift and push the result back 247f440244dSNitesh Jain self.assertTrue(len(dwarf_data) > 1) 248f440244dSNitesh Jain shift_amount = dwarf_data.pop() 249f440244dSNitesh Jain val_to_shift = dwarf_data.pop() 250f440244dSNitesh Jain result = val_to_shift >> shift_amount 251f440244dSNitesh Jain dwarf_data.append(result) 252f440244dSNitesh Jain 253f440244dSNitesh Jain elif val == DW_OP_and: 254f440244dSNitesh Jain # And of topmost 2 elements and push the result back 255f440244dSNitesh Jain first_ele = dwarf_data.pop() 256f440244dSNitesh Jain second_ele = dwarf_data.pop() 257f440244dSNitesh Jain result = first_ele & second_ele 258f440244dSNitesh Jain dwarf_data.append(result) 259f440244dSNitesh Jain 260f440244dSNitesh Jain else: 261f440244dSNitesh Jain self.assertTrue(False and "Unprocess Dwarf Opcode") 262f440244dSNitesh Jain 263f440244dSNitesh Jain self.assertTrue(len(dwarf_data) == 1) 264f440244dSNitesh Jain expr_result = dwarf_data.pop() 265f440244dSNitesh Jain return expr_result 266