1""" This module implement Dwarf expression opcode parser. """ 2 3import lldb 4 5# DWARF Expression operators. 6DW_OP_addr = 0x03 7DW_OP_deref = 0x06 8DW_OP_const1u = 0x08 9DW_OP_const1s = 0x09 10DW_OP_const2u = 0x0A 11DW_OP_const2s = 0x0B 12DW_OP_const4u = 0x0C 13DW_OP_const4s = 0x0D 14DW_OP_const8u = 0x0E 15DW_OP_const8s = 0x0F 16DW_OP_constu = 0x10 17DW_OP_consts = 0x11 18DW_OP_dup = 0x12 19DW_OP_drop = 0x13 20DW_OP_over = 0x14 21DW_OP_pick = 0x15 22DW_OP_swap = 0x16 23DW_OP_rot = 0x17 24DW_OP_xderef = 0x18 25DW_OP_abs = 0x19 26DW_OP_and = 0x1A 27DW_OP_div = 0x1B 28DW_OP_minus = 0x1C 29DW_OP_mod = 0x1D 30DW_OP_mul = 0x1E 31DW_OP_neg = 0x1F 32DW_OP_not = 0x20 33DW_OP_or = 0x21 34DW_OP_plus = 0x22 35DW_OP_plus_uconst = 0x23 36DW_OP_shl = 0x24 37DW_OP_shr = 0x25 38DW_OP_shra = 0x26 39DW_OP_xor = 0x27 40DW_OP_skip = 0x2F 41DW_OP_bra = 0x28 42DW_OP_eq = 0x29 43DW_OP_ge = 0x2A 44DW_OP_gt = 0x2B 45DW_OP_le = 0x2C 46DW_OP_lt = 0x2D 47DW_OP_ne = 0x2E 48DW_OP_lit0 = 0x30 49DW_OP_lit1 = 0x31 50DW_OP_lit2 = 0x32 51DW_OP_lit3 = 0x33 52DW_OP_lit4 = 0x34 53DW_OP_lit5 = 0x35 54DW_OP_lit6 = 0x36 55DW_OP_lit7 = 0x37 56DW_OP_lit8 = 0x38 57DW_OP_lit9 = 0x39 58DW_OP_lit10 = 0x3A 59DW_OP_lit11 = 0x3B 60DW_OP_lit12 = 0x3C 61DW_OP_lit13 = 0x3D 62DW_OP_lit14 = 0x3E 63DW_OP_lit15 = 0x3F 64DW_OP_lit16 = 0x40 65DW_OP_lit17 = 0x41 66DW_OP_lit18 = 0x42 67DW_OP_lit19 = 0x43 68DW_OP_lit20 = 0x44 69DW_OP_lit21 = 0x45 70DW_OP_lit22 = 0x46 71DW_OP_lit23 = 0x47 72DW_OP_lit24 = 0x48 73DW_OP_lit25 = 0x49 74DW_OP_lit26 = 0x4A 75DW_OP_lit27 = 0x4B 76DW_OP_lit28 = 0x4C 77DW_OP_lit29 = 0x4D 78DW_OP_lit30 = 0x4E 79DW_OP_lit31 = 0x4F 80DW_OP_reg0 = 0x50 81DW_OP_reg1 = 0x51 82DW_OP_reg2 = 0x52 83DW_OP_reg3 = 0x53 84DW_OP_reg4 = 0x54 85DW_OP_reg5 = 0x55 86DW_OP_reg6 = 0x56 87DW_OP_reg7 = 0x57 88DW_OP_reg8 = 0x58 89DW_OP_reg9 = 0x59 90DW_OP_reg10 = 0x5A 91DW_OP_reg11 = 0x5B 92DW_OP_reg12 = 0x5C 93DW_OP_reg13 = 0x5D 94DW_OP_reg14 = 0x5E 95DW_OP_reg15 = 0x5F 96DW_OP_reg16 = 0x60 97DW_OP_reg17 = 0x61 98DW_OP_reg18 = 0x62 99DW_OP_reg19 = 0x63 100DW_OP_reg20 = 0x64 101DW_OP_reg21 = 0x65 102DW_OP_reg22 = 0x66 103DW_OP_reg23 = 0x67 104DW_OP_reg24 = 0x68 105DW_OP_reg25 = 0x69 106DW_OP_reg26 = 0x6A 107DW_OP_reg27 = 0x6B 108DW_OP_reg28 = 0x6C 109DW_OP_reg29 = 0x6D 110DW_OP_reg30 = 0x6E 111DW_OP_reg31 = 0x6F 112DW_OP_breg0 = 0x70 113DW_OP_breg1 = 0x71 114DW_OP_breg2 = 0x72 115DW_OP_breg3 = 0x73 116DW_OP_breg4 = 0x74 117DW_OP_breg5 = 0x75 118DW_OP_breg6 = 0x76 119DW_OP_breg7 = 0x77 120DW_OP_breg8 = 0x78 121DW_OP_breg9 = 0x79 122DW_OP_breg10 = 0x7A 123DW_OP_breg11 = 0x7B 124DW_OP_breg12 = 0x7C 125DW_OP_breg13 = 0x7D 126DW_OP_breg14 = 0x7E 127DW_OP_breg15 = 0x7F 128DW_OP_breg16 = 0x80 129DW_OP_breg17 = 0x81 130DW_OP_breg18 = 0x82 131DW_OP_breg19 = 0x83 132DW_OP_breg20 = 0x84 133DW_OP_breg21 = 0x85 134DW_OP_breg22 = 0x86 135DW_OP_breg23 = 0x87 136DW_OP_breg24 = 0x88 137DW_OP_breg25 = 0x89 138DW_OP_breg26 = 0x8A 139DW_OP_breg27 = 0x8B 140DW_OP_breg28 = 0x8C 141DW_OP_breg29 = 0x8D 142DW_OP_breg30 = 0x8E 143DW_OP_breg31 = 0x8F 144DW_OP_regx = 0x90 145DW_OP_fbreg = 0x91 146DW_OP_bregx = 0x92 147DW_OP_piece = 0x93 148DW_OP_deref_size = 0x94 149DW_OP_xderef_size = 0x95 150DW_OP_nop = 0x96 151DW_OP_push_object_address = 0x97 152DW_OP_call2 = 0x98 153DW_OP_call4 = 0x99 154DW_OP_call_ref = 0x9A 155DW_OP_form_tls_address = 0x9B 156DW_OP_call_frame_cfa = 0x9C 157DW_OP_bit_piece = 0x9D 158DW_OP_implicit_value = 0x9E 159DW_OP_stack_value = 0x9F 160DW_OP_lo_user = 0xE0 161DW_OP_GNU_push_tls_address = 0xE0 162DW_OP_APPLE_uninit = 0xF0 163DW_OP_hi_user = 0xFF 164 165 166class DwarfOpcodeParser(object): 167 168 def updateRegInfoBitsize(self, reg_info, byte_order): 169 """ Update the regInfo bit size. """ 170 171 # Evaluate Dwarf Expression 172 expr_result = self.evaluateDwarfExpression(reg_info["dynamic_size_dwarf_expr_bytes"], 173 byte_order) 174 175 if expr_result == 0: 176 reg_info["bitsize"] = 32 177 elif expr_result == 1: 178 reg_info["bitsize"] = 64 179 180 181 def evaluateDwarfExpression(self, dwarf_opcode, byte_order): 182 """Evaluate Dwarf Expression. """ 183 184 dwarf_opcode = [dwarf_opcode[i:i+2] for i in range(0,len(dwarf_opcode),2)] 185 dwarf_data = [] 186 for index in range(len(dwarf_opcode)): 187 188 if index < len(dwarf_opcode): 189 val = int(dwarf_opcode[index], 16) 190 else: 191 break 192 193 if val == DW_OP_regx: 194 # Read register number 195 self.assertTrue(len(dwarf_opcode) > (index + 1)) 196 reg_no = int(dwarf_opcode.pop(index + 1), 16) 197 198 self.reset_test_sequence() 199 # Read register value 200 self.test_sequence.add_log_lines( 201 ["read packet: $p{0:x}#00".format(reg_no), 202 {"direction": "send", "regex": r"^\$([0-9a-fA-F]+)#", 203 "capture": {1: "p_response"}}],True) 204 205 Context = self.expect_gdbremote_sequence() 206 self.assertIsNotNone(Context) 207 p_response = Context.get("p_response") 208 self.assertIsNotNone(p_response) 209 210 if byte_order == lldb.eByteOrderLittle: 211 # In case of little endian 212 # first decode the HEX ASCII bytes and then reverse it 213 # to get actual value of SR register 214 p_response = "".join(reversed([p_response[i:i+2] for i in range(0, 215 len(p_response),2)])) 216 # Push register value 217 dwarf_data.append(int(p_response,16)) 218 219 elif val == DW_OP_lit1: 220 # Push literal 1 221 dwarf_data.append(1) 222 223 elif val == DW_OP_lit26: 224 # Push literal 26 225 dwarf_data.append(26) 226 227 elif val == DW_OP_shl: 228 # left shift and push the result back 229 self.assertTrue(len(dwarf_data) > 1) 230 shift_amount = dwarf_data.pop() 231 val_to_shift = dwarf_data.pop() 232 result = val_to_shift << shift_amount 233 dwarf_data.append(result) 234 235 elif val == DW_OP_shr: 236 # Right shift and push the result back 237 self.assertTrue(len(dwarf_data) > 1) 238 shift_amount = dwarf_data.pop() 239 val_to_shift = dwarf_data.pop() 240 result = val_to_shift >> shift_amount 241 dwarf_data.append(result) 242 243 elif val == DW_OP_and: 244 # And of topmost 2 elements and push the result back 245 first_ele = dwarf_data.pop() 246 second_ele = dwarf_data.pop() 247 result = first_ele & second_ele 248 dwarf_data.append(result) 249 250 else: 251 self.assertTrue(False and "Unprocess Dwarf Opcode") 252 253 self.assertTrue(len(dwarf_data) == 1) 254 expr_result = dwarf_data.pop() 255 return expr_result 256 257