1*061da546Spatrick""" This module implement Dwarf expression opcode parser. """ 2*061da546Spatrick 3*061da546Spatrickimport lldb 4*061da546Spatrick 5*061da546Spatrick# DWARF Expression operators. 6*061da546SpatrickDW_OP_addr = 0x03 7*061da546SpatrickDW_OP_deref = 0x06 8*061da546SpatrickDW_OP_const1u = 0x08 9*061da546SpatrickDW_OP_const1s = 0x09 10*061da546SpatrickDW_OP_const2u = 0x0A 11*061da546SpatrickDW_OP_const2s = 0x0B 12*061da546SpatrickDW_OP_const4u = 0x0C 13*061da546SpatrickDW_OP_const4s = 0x0D 14*061da546SpatrickDW_OP_const8u = 0x0E 15*061da546SpatrickDW_OP_const8s = 0x0F 16*061da546SpatrickDW_OP_constu = 0x10 17*061da546SpatrickDW_OP_consts = 0x11 18*061da546SpatrickDW_OP_dup = 0x12 19*061da546SpatrickDW_OP_drop = 0x13 20*061da546SpatrickDW_OP_over = 0x14 21*061da546SpatrickDW_OP_pick = 0x15 22*061da546SpatrickDW_OP_swap = 0x16 23*061da546SpatrickDW_OP_rot = 0x17 24*061da546SpatrickDW_OP_xderef = 0x18 25*061da546SpatrickDW_OP_abs = 0x19 26*061da546SpatrickDW_OP_and = 0x1A 27*061da546SpatrickDW_OP_div = 0x1B 28*061da546SpatrickDW_OP_minus = 0x1C 29*061da546SpatrickDW_OP_mod = 0x1D 30*061da546SpatrickDW_OP_mul = 0x1E 31*061da546SpatrickDW_OP_neg = 0x1F 32*061da546SpatrickDW_OP_not = 0x20 33*061da546SpatrickDW_OP_or = 0x21 34*061da546SpatrickDW_OP_plus = 0x22 35*061da546SpatrickDW_OP_plus_uconst = 0x23 36*061da546SpatrickDW_OP_shl = 0x24 37*061da546SpatrickDW_OP_shr = 0x25 38*061da546SpatrickDW_OP_shra = 0x26 39*061da546SpatrickDW_OP_xor = 0x27 40*061da546SpatrickDW_OP_skip = 0x2F 41*061da546SpatrickDW_OP_bra = 0x28 42*061da546SpatrickDW_OP_eq = 0x29 43*061da546SpatrickDW_OP_ge = 0x2A 44*061da546SpatrickDW_OP_gt = 0x2B 45*061da546SpatrickDW_OP_le = 0x2C 46*061da546SpatrickDW_OP_lt = 0x2D 47*061da546SpatrickDW_OP_ne = 0x2E 48*061da546SpatrickDW_OP_lit0 = 0x30 49*061da546SpatrickDW_OP_lit1 = 0x31 50*061da546SpatrickDW_OP_lit2 = 0x32 51*061da546SpatrickDW_OP_lit3 = 0x33 52*061da546SpatrickDW_OP_lit4 = 0x34 53*061da546SpatrickDW_OP_lit5 = 0x35 54*061da546SpatrickDW_OP_lit6 = 0x36 55*061da546SpatrickDW_OP_lit7 = 0x37 56*061da546SpatrickDW_OP_lit8 = 0x38 57*061da546SpatrickDW_OP_lit9 = 0x39 58*061da546SpatrickDW_OP_lit10 = 0x3A 59*061da546SpatrickDW_OP_lit11 = 0x3B 60*061da546SpatrickDW_OP_lit12 = 0x3C 61*061da546SpatrickDW_OP_lit13 = 0x3D 62*061da546SpatrickDW_OP_lit14 = 0x3E 63*061da546SpatrickDW_OP_lit15 = 0x3F 64*061da546SpatrickDW_OP_lit16 = 0x40 65*061da546SpatrickDW_OP_lit17 = 0x41 66*061da546SpatrickDW_OP_lit18 = 0x42 67*061da546SpatrickDW_OP_lit19 = 0x43 68*061da546SpatrickDW_OP_lit20 = 0x44 69*061da546SpatrickDW_OP_lit21 = 0x45 70*061da546SpatrickDW_OP_lit22 = 0x46 71*061da546SpatrickDW_OP_lit23 = 0x47 72*061da546SpatrickDW_OP_lit24 = 0x48 73*061da546SpatrickDW_OP_lit25 = 0x49 74*061da546SpatrickDW_OP_lit26 = 0x4A 75*061da546SpatrickDW_OP_lit27 = 0x4B 76*061da546SpatrickDW_OP_lit28 = 0x4C 77*061da546SpatrickDW_OP_lit29 = 0x4D 78*061da546SpatrickDW_OP_lit30 = 0x4E 79*061da546SpatrickDW_OP_lit31 = 0x4F 80*061da546SpatrickDW_OP_reg0 = 0x50 81*061da546SpatrickDW_OP_reg1 = 0x51 82*061da546SpatrickDW_OP_reg2 = 0x52 83*061da546SpatrickDW_OP_reg3 = 0x53 84*061da546SpatrickDW_OP_reg4 = 0x54 85*061da546SpatrickDW_OP_reg5 = 0x55 86*061da546SpatrickDW_OP_reg6 = 0x56 87*061da546SpatrickDW_OP_reg7 = 0x57 88*061da546SpatrickDW_OP_reg8 = 0x58 89*061da546SpatrickDW_OP_reg9 = 0x59 90*061da546SpatrickDW_OP_reg10 = 0x5A 91*061da546SpatrickDW_OP_reg11 = 0x5B 92*061da546SpatrickDW_OP_reg12 = 0x5C 93*061da546SpatrickDW_OP_reg13 = 0x5D 94*061da546SpatrickDW_OP_reg14 = 0x5E 95*061da546SpatrickDW_OP_reg15 = 0x5F 96*061da546SpatrickDW_OP_reg16 = 0x60 97*061da546SpatrickDW_OP_reg17 = 0x61 98*061da546SpatrickDW_OP_reg18 = 0x62 99*061da546SpatrickDW_OP_reg19 = 0x63 100*061da546SpatrickDW_OP_reg20 = 0x64 101*061da546SpatrickDW_OP_reg21 = 0x65 102*061da546SpatrickDW_OP_reg22 = 0x66 103*061da546SpatrickDW_OP_reg23 = 0x67 104*061da546SpatrickDW_OP_reg24 = 0x68 105*061da546SpatrickDW_OP_reg25 = 0x69 106*061da546SpatrickDW_OP_reg26 = 0x6A 107*061da546SpatrickDW_OP_reg27 = 0x6B 108*061da546SpatrickDW_OP_reg28 = 0x6C 109*061da546SpatrickDW_OP_reg29 = 0x6D 110*061da546SpatrickDW_OP_reg30 = 0x6E 111*061da546SpatrickDW_OP_reg31 = 0x6F 112*061da546SpatrickDW_OP_breg0 = 0x70 113*061da546SpatrickDW_OP_breg1 = 0x71 114*061da546SpatrickDW_OP_breg2 = 0x72 115*061da546SpatrickDW_OP_breg3 = 0x73 116*061da546SpatrickDW_OP_breg4 = 0x74 117*061da546SpatrickDW_OP_breg5 = 0x75 118*061da546SpatrickDW_OP_breg6 = 0x76 119*061da546SpatrickDW_OP_breg7 = 0x77 120*061da546SpatrickDW_OP_breg8 = 0x78 121*061da546SpatrickDW_OP_breg9 = 0x79 122*061da546SpatrickDW_OP_breg10 = 0x7A 123*061da546SpatrickDW_OP_breg11 = 0x7B 124*061da546SpatrickDW_OP_breg12 = 0x7C 125*061da546SpatrickDW_OP_breg13 = 0x7D 126*061da546SpatrickDW_OP_breg14 = 0x7E 127*061da546SpatrickDW_OP_breg15 = 0x7F 128*061da546SpatrickDW_OP_breg16 = 0x80 129*061da546SpatrickDW_OP_breg17 = 0x81 130*061da546SpatrickDW_OP_breg18 = 0x82 131*061da546SpatrickDW_OP_breg19 = 0x83 132*061da546SpatrickDW_OP_breg20 = 0x84 133*061da546SpatrickDW_OP_breg21 = 0x85 134*061da546SpatrickDW_OP_breg22 = 0x86 135*061da546SpatrickDW_OP_breg23 = 0x87 136*061da546SpatrickDW_OP_breg24 = 0x88 137*061da546SpatrickDW_OP_breg25 = 0x89 138*061da546SpatrickDW_OP_breg26 = 0x8A 139*061da546SpatrickDW_OP_breg27 = 0x8B 140*061da546SpatrickDW_OP_breg28 = 0x8C 141*061da546SpatrickDW_OP_breg29 = 0x8D 142*061da546SpatrickDW_OP_breg30 = 0x8E 143*061da546SpatrickDW_OP_breg31 = 0x8F 144*061da546SpatrickDW_OP_regx = 0x90 145*061da546SpatrickDW_OP_fbreg = 0x91 146*061da546SpatrickDW_OP_bregx = 0x92 147*061da546SpatrickDW_OP_piece = 0x93 148*061da546SpatrickDW_OP_deref_size = 0x94 149*061da546SpatrickDW_OP_xderef_size = 0x95 150*061da546SpatrickDW_OP_nop = 0x96 151*061da546SpatrickDW_OP_push_object_address = 0x97 152*061da546SpatrickDW_OP_call2 = 0x98 153*061da546SpatrickDW_OP_call4 = 0x99 154*061da546SpatrickDW_OP_call_ref = 0x9A 155*061da546SpatrickDW_OP_form_tls_address = 0x9B 156*061da546SpatrickDW_OP_call_frame_cfa = 0x9C 157*061da546SpatrickDW_OP_bit_piece = 0x9D 158*061da546SpatrickDW_OP_implicit_value = 0x9E 159*061da546SpatrickDW_OP_stack_value = 0x9F 160*061da546SpatrickDW_OP_lo_user = 0xE0 161*061da546SpatrickDW_OP_GNU_push_tls_address = 0xE0 162*061da546SpatrickDW_OP_hi_user = 0xFF 163*061da546Spatrick 164*061da546Spatrick 165*061da546Spatrickclass DwarfOpcodeParser(object): 166*061da546Spatrick 167*061da546Spatrick def updateRegInfoBitsize(self, reg_info, byte_order): 168*061da546Spatrick """ Update the regInfo bit size. """ 169*061da546Spatrick 170*061da546Spatrick # Evaluate Dwarf Expression 171*061da546Spatrick expr_result = self.evaluateDwarfExpression(reg_info["dynamic_size_dwarf_expr_bytes"], 172*061da546Spatrick byte_order) 173*061da546Spatrick 174*061da546Spatrick if expr_result == 0: 175*061da546Spatrick reg_info["bitsize"] = 32 176*061da546Spatrick elif expr_result == 1: 177*061da546Spatrick reg_info["bitsize"] = 64 178*061da546Spatrick 179*061da546Spatrick 180*061da546Spatrick def evaluateDwarfExpression(self, dwarf_opcode, byte_order): 181*061da546Spatrick """Evaluate Dwarf Expression. """ 182*061da546Spatrick 183*061da546Spatrick dwarf_opcode = [dwarf_opcode[i:i+2] for i in range(0,len(dwarf_opcode),2)] 184*061da546Spatrick dwarf_data = [] 185*061da546Spatrick for index in range(len(dwarf_opcode)): 186*061da546Spatrick 187*061da546Spatrick if index < len(dwarf_opcode): 188*061da546Spatrick val = int(dwarf_opcode[index], 16) 189*061da546Spatrick else: 190*061da546Spatrick break 191*061da546Spatrick 192*061da546Spatrick if val == DW_OP_regx: 193*061da546Spatrick # Read register number 194*061da546Spatrick self.assertTrue(len(dwarf_opcode) > (index + 1)) 195*061da546Spatrick reg_no = int(dwarf_opcode.pop(index + 1), 16) 196*061da546Spatrick 197*061da546Spatrick self.reset_test_sequence() 198*061da546Spatrick # Read register value 199*061da546Spatrick self.test_sequence.add_log_lines( 200*061da546Spatrick ["read packet: $p{0:x}#00".format(reg_no), 201*061da546Spatrick {"direction": "send", "regex": r"^\$([0-9a-fA-F]+)#", 202*061da546Spatrick "capture": {1: "p_response"}}],True) 203*061da546Spatrick 204*061da546Spatrick Context = self.expect_gdbremote_sequence() 205*061da546Spatrick self.assertIsNotNone(Context) 206*061da546Spatrick p_response = Context.get("p_response") 207*061da546Spatrick self.assertIsNotNone(p_response) 208*061da546Spatrick 209*061da546Spatrick if byte_order == lldb.eByteOrderLittle: 210*061da546Spatrick # In case of little endian 211*061da546Spatrick # first decode the HEX ASCII bytes and then reverse it 212*061da546Spatrick # to get actual value of SR register 213*061da546Spatrick p_response = "".join(reversed([p_response[i:i+2] for i in range(0, 214*061da546Spatrick len(p_response),2)])) 215*061da546Spatrick # Push register value 216*061da546Spatrick dwarf_data.append(int(p_response,16)) 217*061da546Spatrick 218*061da546Spatrick elif val == DW_OP_lit1: 219*061da546Spatrick # Push literal 1 220*061da546Spatrick dwarf_data.append(1) 221*061da546Spatrick 222*061da546Spatrick elif val == DW_OP_lit26: 223*061da546Spatrick # Push literal 26 224*061da546Spatrick dwarf_data.append(26) 225*061da546Spatrick 226*061da546Spatrick elif val == DW_OP_shl: 227*061da546Spatrick # left shift and push the result back 228*061da546Spatrick self.assertTrue(len(dwarf_data) > 1) 229*061da546Spatrick shift_amount = dwarf_data.pop() 230*061da546Spatrick val_to_shift = dwarf_data.pop() 231*061da546Spatrick result = val_to_shift << shift_amount 232*061da546Spatrick dwarf_data.append(result) 233*061da546Spatrick 234*061da546Spatrick elif val == DW_OP_shr: 235*061da546Spatrick # Right shift and push the result back 236*061da546Spatrick self.assertTrue(len(dwarf_data) > 1) 237*061da546Spatrick shift_amount = dwarf_data.pop() 238*061da546Spatrick val_to_shift = dwarf_data.pop() 239*061da546Spatrick result = val_to_shift >> shift_amount 240*061da546Spatrick dwarf_data.append(result) 241*061da546Spatrick 242*061da546Spatrick elif val == DW_OP_and: 243*061da546Spatrick # And of topmost 2 elements and push the result back 244*061da546Spatrick first_ele = dwarf_data.pop() 245*061da546Spatrick second_ele = dwarf_data.pop() 246*061da546Spatrick result = first_ele & second_ele 247*061da546Spatrick dwarf_data.append(result) 248*061da546Spatrick 249*061da546Spatrick else: 250*061da546Spatrick self.assertTrue(False and "Unprocess Dwarf Opcode") 251*061da546Spatrick 252*061da546Spatrick self.assertTrue(len(dwarf_data) == 1) 253*061da546Spatrick expr_result = dwarf_data.pop() 254*061da546Spatrick return expr_result 255*061da546Spatrick 256