1#!/usr/bin/python 2# 3 4#source of register info is from http://opensource.apple.com/source/gdb/gdb-962/src/gdb/arm-tdep.c 5from __future__ import absolute_import, print_function 6 7from builtins import hex 8from builtins import range 9from builtins import object 10 11import struct 12import lldb 13 14 15osplugin_target_obj = None 16 17class PluginValue(lldb.SBValue): 18 def GetChildMemberWithName(val, name): 19 val_type = val.GetType() 20 if val_type.IsPointerType() == True: 21 val_type = val_type.GetPointeeType() 22 for i in range(val_type.GetNumberOfFields()): 23 if name == val_type.GetFieldAtIndex(i).GetName(): 24 return PluginValue(val.GetChildAtIndex(i)) 25 return None 26 27class Armv8_RegisterSet(object): 28 """ register info set for armv8 64 bit architecture""" 29 register_info = { 'sets' : ['GPR'], 30 'registers': [ 31 {'name': 'x0' , 'bitsize':64, 'offset': 0, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 0, 'dwarf': 0, 'alt-name':'arg1', 'generic':'arg1'}, 32 {'name': 'x1' , 'bitsize':64, 'offset': 8, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 1, 'dwarf': 1, 'alt-name':'arg2', 'generic':'arg2'}, 33 {'name': 'x2' , 'bitsize':64, 'offset': 16, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 2, 'dwarf': 2, 'alt-name':'arg3', 'generic':'arg3'}, 34 {'name': 'x3' , 'bitsize':64, 'offset': 24, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 3, 'dwarf': 3, 'alt-name':'arg4', 'generic':'arg4'}, 35 {'name': 'x4' , 'bitsize':64, 'offset': 32, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 4, 'dwarf': 4, 'alt-name':'arg5', 'generic':'arg5'}, 36 {'name': 'x5' , 'bitsize':64, 'offset': 40, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 5, 'dwarf': 5, 'alt-name':'arg6', 'generic':'arg6'}, 37 {'name': 'x6' , 'bitsize':64, 'offset': 48, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 6, 'dwarf': 6, 'alt-name':'arg7', 'generic':'arg7'}, 38 {'name': 'x7' , 'bitsize':64, 'offset': 56, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 7, 'dwarf': 7, 'alt-name':'arg8', 'generic':'arg8'}, 39 {'name': 'x8' , 'bitsize':64, 'offset': 64, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 8, 'dwarf': 8}, 40 {'name': 'x9' , 'bitsize':64, 'offset': 72, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 9, 'dwarf': 9}, 41 {'name': 'x10' , 'bitsize':64, 'offset': 80, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':10, 'dwarf':10}, 42 {'name': 'x11' , 'bitsize':64, 'offset': 88, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':11, 'dwarf':11}, 43 {'name': 'x12' , 'bitsize':64, 'offset': 96, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':12, 'dwarf':12}, 44 {'name': 'x13' , 'bitsize':64, 'offset':104, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':13, 'dwarf':13}, 45 {'name': 'x14' , 'bitsize':64, 'offset':112, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':14, 'dwarf':14}, 46 {'name': 'x15' , 'bitsize':64, 'offset':120, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':15, 'dwarf':15}, 47 {'name': 'x16' , 'bitsize':64, 'offset':128, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':16, 'dwarf':16}, 48 {'name': 'x17' , 'bitsize':64, 'offset':136, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':17, 'dwarf':17}, 49 {'name': 'x18' , 'bitsize':64, 'offset':144, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':18, 'dwarf':18}, 50 {'name': 'x19' , 'bitsize':64, 'offset':152, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':19, 'dwarf':19}, 51 {'name': 'x20' , 'bitsize':64, 'offset':160, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':20, 'dwarf':20}, 52 {'name': 'x21' , 'bitsize':64, 'offset':168, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':21, 'dwarf':21}, 53 {'name': 'x22' , 'bitsize':64, 'offset':176, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':22, 'dwarf':22}, 54 {'name': 'x23' , 'bitsize':64, 'offset':184, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':23, 'dwarf':23}, 55 {'name': 'x24' , 'bitsize':64, 'offset':192, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':24, 'dwarf':24}, 56 {'name': 'x25' , 'bitsize':64, 'offset':200, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':25, 'dwarf':25}, 57 {'name': 'x26' , 'bitsize':64, 'offset':208, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':26, 'dwarf':26}, 58 {'name': 'x27' , 'bitsize':64, 'offset':216, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':27, 'dwarf':27}, 59 {'name': 'x28' , 'bitsize':64, 'offset':224, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':28, 'dwarf':28}, 60 {'name': 'fp' , 'bitsize':64, 'offset':232, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':29, 'dwarf':29, 'alt-name': 'fp', 'generic':'fp'}, 61 {'name': 'lr' , 'bitsize':64, 'offset':240, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':30, 'dwarf':30, 'alt-name': 'lr', 'generic':'lr'}, 62 {'name': 'sp' , 'bitsize':64, 'offset':248, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':31, 'dwarf':31, 'alt-name': 'sp', 'generic':'sp'}, 63 {'name': 'pc' , 'bitsize':64, 'offset':256, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':32, 'dwarf':32, 'alt-name': 'pc', 'generic':'pc'}, 64 {'name': 'far' , 'bitsize':64, 'offset':264, 'encoding':'uint', 'format':'hex', 'set':0}, 65 {'name': 'cpsr', 'bitsize':32, 'offset':272, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':33, 'dwarf':33, 'generic':'flags'}, 66 {'name': 'esr' , 'bitsize':32, 'offset':276, 'encoding':'uint', 'format':'hex', 'set':0}, 67 ] 68 } 69 70 def __init__(self): 71 self.switch_context_address = osplugin_target_obj.FindSymbols('Switch_context')[0].GetSymbol().GetStartAddress().GetLoadAddress(osplugin_target_obj) 72 self.ResetRegisterValues() 73 def ResetRegisterValues(self): 74 self.x0 = 0 75 self.x1 = 0 76 self.x2 = 0 77 self.x3 = 0 78 self.x4 = 0 79 self.x5 = 0 80 self.x6 = 0 81 self.x7 = 0 82 self.x8 = 0 83 self.x9 = 0 84 self.x10 = 0 85 self.x11 = 0 86 self.x12 = 0 87 self.x13 = 0 88 self.x14 = 0 89 self.x15 = 0 90 self.x16 = 0 91 self.x17 = 0 92 self.x18 = 0 93 self.x19 = 0 94 self.x20 = 0 95 self.x21 = 0 96 self.x22 = 0 97 self.x23 = 0 98 self.x24 = 0 99 self.x25 = 0 100 self.x26 = 0 101 self.x27 = 0 102 self.x28 = 0 103 self.fp = 0 104 self.lr = 0 105 self.sp = 0 106 self.pc = 0 107 self.far = 0 108 self.cpsr = 0 109 self.esr = 0 110 111 def __str__(self): 112 return """ pc = """ 113 114 def GetPackedRegisterState(self): 115 return struct.pack('34QII', self.x0, self.x1, self.x2, self.x3, self.x4, self.x5, 116 self.x6, self.x7, self.x8, self.x9, self.x10, self.x11, self.x12, self.x13, 117 self.x14, self.x15, self.x16, self.x17, self.x18, self.x19, self.x20, self.x21, 118 self.x22, self.x23, self.x24, self.x25, self.x26, self.x27, self.x28, self.fp, 119 self.lr, self.sp, self.pc, self.far, self.cpsr, self.esr) 120 121 def ReadRegisterDataFromKDPSavedState(self, kdp_state, kernel_version): 122 """ Setup register values from KDP saved information. 123 """ 124 saved_state = kernel_version.CreateValueFromExpression(None, '(struct arm_saved_state64 *) ' + str(kdp_state.GetValueAsUnsigned())) 125 saved_state = saved_state.Dereference() 126 saved_state = PluginValue(saved_state) 127 self.ResetRegisterValues() 128 self.x0 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(0).GetValueAsUnsigned() 129 self.x1 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(1).GetValueAsUnsigned() 130 self.x2 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(2).GetValueAsUnsigned() 131 self.x3 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(3).GetValueAsUnsigned() 132 self.x4 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(4).GetValueAsUnsigned() 133 self.x5 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(5).GetValueAsUnsigned() 134 self.x6 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(6).GetValueAsUnsigned() 135 self.x7 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(7).GetValueAsUnsigned() 136 self.x8 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(8).GetValueAsUnsigned() 137 self.x9 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(9).GetValueAsUnsigned() 138 self.x10 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(10).GetValueAsUnsigned() 139 self.x11 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(11).GetValueAsUnsigned() 140 self.x12 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(12).GetValueAsUnsigned() 141 self.x13 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(13).GetValueAsUnsigned() 142 self.x14 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(14).GetValueAsUnsigned() 143 self.x15 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(15).GetValueAsUnsigned() 144 self.x16 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(16).GetValueAsUnsigned() 145 self.x17 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(17).GetValueAsUnsigned() 146 self.x18 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(18).GetValueAsUnsigned() 147 self.x19 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(19).GetValueAsUnsigned() 148 self.x20 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(20).GetValueAsUnsigned() 149 self.x21 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(21).GetValueAsUnsigned() 150 self.x22 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(22).GetValueAsUnsigned() 151 self.x23 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(23).GetValueAsUnsigned() 152 self.x24 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(24).GetValueAsUnsigned() 153 self.x25 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(25).GetValueAsUnsigned() 154 self.x26 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(26).GetValueAsUnsigned() 155 self.x27 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(27).GetValueAsUnsigned() 156 self.x28 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(28).GetValueAsUnsigned() 157 self.fp = saved_state.GetChildMemberWithName('fp').GetValueAsUnsigned() 158 self.lr = saved_state.GetChildMemberWithName('lr').GetValueAsUnsigned() 159 self.sp = saved_state.GetChildMemberWithName('sp').GetValueAsUnsigned() 160 self.pc = saved_state.GetChildMemberWithName('pc').GetValueAsUnsigned() 161 self.far = saved_state.GetChildMemberWithName('far').GetValueAsUnsigned() 162 self.cpsr = saved_state.GetChildMemberWithName('cpsr').GetValueAsUnsigned() 163 self.esr = saved_state.GetChildMemberWithName('esr').GetValueAsUnsigned() 164 return self 165 166 def ReadRegisterDataFromKernelStack(self, kstack_saved_state_addr, kernel_version): 167 saved_state = kernel_version.CreateValueFromExpression(None, '(arm_kernel_saved_state_t *) '+ str(kstack_saved_state_addr)) 168 saved_state = saved_state.Dereference() 169 saved_state = PluginValue(saved_state) 170 self.ResetRegisterValues() 171 self.x19 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(0).GetValueAsUnsigned() 172 self.x20 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(1).GetValueAsUnsigned() 173 self.x21 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(2).GetValueAsUnsigned() 174 self.x22 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(3).GetValueAsUnsigned() 175 self.x23 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(4).GetValueAsUnsigned() 176 self.x24 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(5).GetValueAsUnsigned() 177 self.x25 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(6).GetValueAsUnsigned() 178 self.x26 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(7).GetValueAsUnsigned() 179 self.x27 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(8).GetValueAsUnsigned() 180 self.x28 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(9).GetValueAsUnsigned() 181 self.fp = saved_state.GetChildMemberWithName('fp').GetValueAsUnsigned() 182 self.lr = saved_state.GetChildMemberWithName('lr').GetValueAsUnsigned() 183 self.sp = saved_state.GetChildMemberWithName('sp').GetValueAsUnsigned() 184 # pc for a blocked thread is treated to be the next instruction it would run after thread switch. 185 self.pc = self.switch_context_address 186 return self 187 188 def ReadRegisterDataFromContinuation(self, continuation_ptr): 189 self.ResetRegisterValues() 190 self.pc = continuation_ptr 191 return self 192 193 @classmethod 194 def GetRegisterInfo(cls, regnum): 195 if regnum < 0 or regnum > len(cls.register_info['registers']): 196 return '' 197 198 reginfo = cls.register_info['registers'][regnum] 199 retval = '' 200 for i in list(reginfo.keys()): 201 v_str = str(reginfo[i]) 202 if i == 'set': 203 v_str = 'General Purpose Registers' 204 retval += "%s:%s;" % (str(i), v_str) 205 return retval 206 207 208 209class Armv7_RegisterSet(object): 210 """ register info set for armv7 32 bit architecture """ 211 register_info = { 'sets' : ['GPR'], 212 'registers': [ 213 { 'name':'r0' , 'bitsize' : 32, 'offset' : 0, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 0, 'dwarf' : 0}, 214 { 'name':'r1' , 'bitsize' : 32, 'offset' : 4, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 1, 'dwarf' : 1}, 215 { 'name':'r2' , 'bitsize' : 32, 'offset' : 8, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 2, 'dwarf' : 2}, 216 { 'name':'r3' , 'bitsize' : 32, 'offset' : 12, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 3, 'dwarf' : 3}, 217 { 'name':'r4' , 'bitsize' : 32, 'offset' : 16, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 4, 'dwarf' : 4}, 218 { 'name':'r5' , 'bitsize' : 32, 'offset' : 20, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 5, 'dwarf' : 5}, 219 { 'name':'r6' , 'bitsize' : 32, 'offset' : 24, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 6, 'dwarf' : 6}, 220 { 'name':'r7' , 'bitsize' : 32, 'offset' : 28, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 7, 'dwarf' : 7}, 221 { 'name':'r8' , 'bitsize' : 32, 'offset' : 32, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 8, 'dwarf' : 8}, 222 { 'name':'r9' , 'bitsize' : 32, 'offset' : 36, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 9, 'dwarf' : 9}, 223 { 'name':'r10' , 'bitsize' : 32, 'offset' : 40, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':10, 'dwarf' :10}, 224 { 'name':'r11' , 'bitsize' : 32, 'offset' : 44, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':11, 'dwarf' :11, 'alt-name': 'fp', 'generic': 'fp'}, 225 { 'name':'r12' , 'bitsize' : 32, 'offset' : 48, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':12, 'dwarf' :12}, 226 { 'name':'sp' , 'bitsize' : 32, 'offset' : 52, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':13, 'dwarf' :13, 'generic': 'sp'}, 227 { 'name':'lr' , 'bitsize' : 32, 'offset' : 56, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':14, 'dwarf' :14, 'generic': 'lr'}, 228 { 'name':'pc' , 'bitsize' : 32, 'offset' : 60, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':15, 'dwarf' :15, 'generic': 'pc'}, 229 { 'name':'cpsr' , 'bitsize' : 32, 'offset' : 64, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':16, 'dwarf' :16, 'generic':'flags'}, 230 { 'name':'fsr' , 'bitsize' : 32, 'offset' : 68, 'encoding':'uint', 'format':'hex', 'set':0}, 231 { 'name':'far' , 'bitsize' : 32, 'offset' : 72, 'encoding':'uint', 'format':'hex', 'set':0} 232 ] 233 } 234 235 def __init__(self): 236 self.switch_context_address = osplugin_target_obj.FindSymbols('load_reg')[0].GetSymbol().GetStartAddress().GetLoadAddress(osplugin_target_obj) + 8 237 self.ResetRegisterValues() 238 239 @classmethod 240 def GetRegisterInfo(cls, regnum): 241 if regnum < 0 or regnum > len(cls.register_info['registers']): 242 return '' 243 244 reginfo = cls.register_info['registers'][regnum] 245 retval = '' 246 for i in list(reginfo.keys()): 247 v_str = str(reginfo[i]) 248 if i == 'set': 249 v_str = 'General Purpose Registers' 250 retval += "%s:%s;" % (str(i), v_str) 251 return retval 252 253 def ResetRegisterValues(self): 254 self.r0 = 0 255 self.r1 = 0 256 self.r2 = 0 257 self.r3 = 0 258 self.r4 = 0 259 self.r5 = 0 260 self.r6 = 0 261 self.r7 = 0 262 self.r8 = 0 263 self.r9 = 0 264 self.r10 = 0 265 self.r11 = 0 266 self.r12 = 0 267 self.sp = 0 268 self.lr = 0 269 self.pc = 0 270 self.cpsr = 0 271 self.fsr = 0 272 self.far = 0 273 274 def __str__(self): 275 return """ 276 r0 = {o.r0: <#010x} 277 r1 = {o.r1: <#010x} 278 r2 = {o.r2: <#010x} 279 r3 = {o.r3: <#010x} 280 r4 = {o.r4: <#010x} 281 r5 = {o.r5: <#010x} 282 r6 = {o.r6: <#010x} 283 r7 = {o.r7: <#010x} 284 r8 = {o.r8: <#010x} 285 r9 = {o.r9: <#010x} 286 r10 = {o.r10: <#010x} 287 r11 = {o.r11: <#010x} 288 r12 = {o.r12: <#010x} 289 sp = {o.sp: <#010x} 290 lr = {o.lr: <#010x} 291 pc = {o.pc: <#010x} 292 cpsr = {o.cpsr: <#010x} 293 fsr = {o.fsr : <#010x} 294 far = {o.far : <#010x} 295 """.format(o=self) 296 297 def GetPackedRegisterState(self): 298 return struct.pack('19I', self.r0, self.r1, self.r2, self.r3, 299 self.r4, self.r5, self.r6, self.r7, 300 self.r8, self.r9, self.r10, self.r11, 301 self.r12, self.sp, self.lr, self.pc, 302 self.cpsr, self.fsr, self.far) 303 304 def ReadRegisterDataFromKDPSavedState(self, kdp_state, kernel_version): 305 saved_state = kernel_version.CreateValueFromExpression(None, '(struct arm_saved_state *) ' + str(kdp_state.GetValueAsUnsigned())) 306 saved_state = saved_state.Dereference() 307 saved_state = PluginValue(saved_state) 308 self.ResetRegisterValues() 309 self.r0 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(0).GetValueAsUnsigned() 310 self.r1 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(1).GetValueAsUnsigned() 311 self.r2 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(2).GetValueAsUnsigned() 312 self.r3 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(3).GetValueAsUnsigned() 313 self.r4 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(4).GetValueAsUnsigned() 314 self.r5 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(5).GetValueAsUnsigned() 315 self.r6 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(6).GetValueAsUnsigned() 316 self.r7 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(7).GetValueAsUnsigned() 317 self.r8 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(8).GetValueAsUnsigned() 318 self.r9 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(9).GetValueAsUnsigned() 319 self.r10 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(10).GetValueAsUnsigned() 320 self.r11 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(11).GetValueAsUnsigned() 321 self.r12 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(12).GetValueAsUnsigned() 322 self.sp = saved_state.GetChildMemberWithName('sp').GetValueAsUnsigned() 323 self.lr = saved_state.GetChildMemberWithName('lr').GetValueAsUnsigned() 324 self.pc = saved_state.GetChildMemberWithName('pc').GetValueAsUnsigned() 325 self.cpsr = saved_state.GetChildMemberWithName('cpsr').GetValueAsUnsigned() 326 self.fsr = saved_state.GetChildMemberWithName('fsr').GetValueAsUnsigned() 327 self.far = saved_state.GetChildMemberWithName('far').GetValueAsUnsigned() 328 return self 329 330 def ReadRegisterDataFromKernelStack(self, kstack_saved_state_addr, kernel_version): 331 saved_state = kernel_version.CreateValueFromExpression(None, '(struct arm_saved_state *) '+ str(kstack_saved_state_addr)) 332 saved_state = saved_state.Dereference() 333 saved_state = PluginValue(saved_state) 334 self.ResetRegisterValues() 335 self.r0 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(0).GetValueAsUnsigned() 336 self.r1 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(1).GetValueAsUnsigned() 337 self.r2 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(2).GetValueAsUnsigned() 338 self.r3 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(3).GetValueAsUnsigned() 339 self.r4 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(4).GetValueAsUnsigned() 340 self.r5 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(5).GetValueAsUnsigned() 341 self.r6 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(6).GetValueAsUnsigned() 342 self.r7 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(7).GetValueAsUnsigned() 343 self.r8 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(8).GetValueAsUnsigned() 344 self.r9 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(9).GetValueAsUnsigned() 345 self.r10 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(10).GetValueAsUnsigned() 346 self.r11 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(11).GetValueAsUnsigned() 347 self.r12 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(12).GetValueAsUnsigned() 348 self.sp = saved_state.GetChildMemberWithName('sp').GetValueAsUnsigned() 349 self.lr = saved_state.GetChildMemberWithName('lr').GetValueAsUnsigned() 350 # pc for a blocked thread is treated to be the next instruction it would run after thread switch. 351 self.pc = self.switch_context_address 352 self.cpsr = saved_state.GetChildMemberWithName('cpsr').GetValueAsUnsigned() 353 self.fsr = saved_state.GetChildMemberWithName('fsr').GetValueAsUnsigned() 354 self.far = saved_state.GetChildMemberWithName('far').GetValueAsUnsigned() 355 return self 356 357 def ReadRegisterDataFromContinuation(self, continuation_ptr): 358 self.ResetRegisterValues() 359 self.pc = continuation_ptr 360 return self 361 362 363class I386_RegisterSet(object): 364 """ register info set for i386 architecture 365 """ 366 register_info = { 'sets' : ['GPR'], 367 'registers': [ 368 { 'name': 'eax' , 'bitsize': 32, 'offset' : 0, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 0, 'dwarf': 0}, 369 { 'name': 'ebx' , 'bitsize': 32, 'offset' : 4, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 3, 'dwarf': 3}, 370 { 'name': 'ecx' , 'bitsize': 32, 'offset' : 8, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 1, 'dwarf': 1}, 371 { 'name': 'edx' , 'bitsize': 32, 'offset' :12, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 2, 'dwarf': 2}, 372 { 'name': 'edi' , 'bitsize': 32, 'offset' :16, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 7, 'dwarf': 7}, 373 { 'name': 'esi' , 'bitsize': 32, 'offset' :20, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 6, 'dwarf': 6}, 374 { 'name': 'ebp' , 'bitsize': 32, 'offset' :24, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 4, 'dwarf': 5, 'generic': 'fp', 'alt-name': 'fp'}, 375 { 'name': 'esp' , 'bitsize': 32, 'offset' :28, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 5, 'dwarf': 4, 'generic': 'sp', 'alt-name': 'sp'}, 376 { 'name': 'ss' , 'bitsize': 32, 'offset' :32, 'encoding': 'uint' , 'format':'hex' , 'set': 0}, 377 { 'name': 'eflags', 'bitsize': 32, 'offset' :36, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 9, 'dwarf': 9, 'generic': 'flags'}, 378 { 'name': 'eip' , 'bitsize': 32, 'offset' :40, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' :8, 'dwarf':8, 'generic': 'pc', 'alt-name': 'pc'}, 379 { 'name': 'cs' , 'bitsize': 32, 'offset' :44, 'encoding': 'uint' , 'format':'hex' , 'set': 0}, 380 { 'name': 'ds' , 'bitsize': 32, 'offset' :48, 'encoding': 'uint' , 'format':'hex' , 'set': 0}, 381 { 'name': 'es' , 'bitsize': 32, 'offset' :52, 'encoding': 'uint' , 'format':'hex' , 'set': 0}, 382 { 'name': 'fs' , 'bitsize': 32, 'offset' :56, 'encoding': 'uint' , 'format':'hex' , 'set': 0}, 383 { 'name': 'gs' , 'bitsize': 32, 'offset' :60, 'encoding': 'uint' , 'format':'hex' , 'set': 0}, 384 ] 385 } 386 387 def __init__(self): 388 self.ResetRegisterValues() 389 390 @classmethod 391 def GetRegisterInfo(cls, regnum): 392 if regnum < 0 or regnum > len(cls.register_info['registers']): 393 return '' 394 395 reginfo = cls.register_info['registers'][regnum] 396 retval = '' 397 for i in list(reginfo.keys()): 398 v_str = str(reginfo[i]) 399 if i == 'set': 400 v_str = 'General Purpose Registers' 401 retval += "%s:%s;" % (str(i), v_str) 402 return retval 403 404 def ResetRegisterValues(self): 405 """ set all registers to zero """ 406 self.eax = 0 407 self.ebx = 0 408 self.ecx = 0 409 self.edx = 0 410 self.edi = 0 411 self.esi = 0 412 self.ebp = 0 413 self.esp = 0 414 self.ss = 0 415 self.eflags = 0 416 self.eip = 0 417 self.cs = 0 418 self.ds = 0 419 self.es = 0 420 self.fs = 0 421 self.gs = 0 422 423 def __str__(self): 424 return """ 425 eax = {o.eax: #010x} 426 ebx = {o.ebx: #010x} 427 ecx = {o.ecx: #010x} 428 edx = {o.edx: #010x} 429 edi = {o.edi: #010x} 430 esi = {o.esi: #010x} 431 ebp = {o.ebp: #010x} 432 esp = {o.esp: #010x} 433 ss = {o.ss: #010x} 434 eflags = {o.eflags: #010x} 435 eip = {o.eip: #010x} 436 cs = {o.cs: #010x} 437 ds = {o.ds: #010x} 438 es = {o.es: #010x} 439 fs = {o.fs: #010x} 440 gs = {o.gs: #010x} 441 """.format(o=self) 442 443 def GetPackedRegisterState(self): 444 """ get a struct.pack register data """ 445 return struct.pack('16I', self.eax, self.ebx, self.ecx, 446 self.edx, self.edi, self.esi, 447 self.ebp, self.esp, self.ss, 448 self.eflags, self.eip, self.cs, 449 self.ds, self.es, self.fs, self.gs 450 ) 451 452 def ReadRegisterDataFromKDPSavedState(self, kdp_state, kernel_version): 453 """ to be implemented""" 454 return None 455 456 def ReadRegisterDataFromKernelStack(self, kstack_saved_state_addr, kernel_version): 457 """ to be implemented """ 458 return None 459 460 def ReadRegisterDataFromContinuation(self, continuation_ptr): 461 self.ResetRegisterValues() 462 self.eip = continuation_ptr 463 return self 464 465 466class X86_64RegisterSet(object): 467 """ register info set for x86_64 architecture """ 468 register_info = { 'sets' : ['GPR'], 469 'registers': [ 470 { 'name':'rax' , 'bitsize' : 64, 'offset' : 0, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 0, 'dwarf' : 0}, 471 { 'name':'rbx' , 'bitsize' : 64, 'offset' : 8, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 3, 'dwarf' : 3}, 472 { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 2, 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', }, 473 { 'name':'rdx' , 'bitsize' : 64, 'offset' : 24, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 1, 'dwarf' : 1, 'generic':'arg3', 'alt-name':'arg3', }, 474 { 'name':'rdi' , 'bitsize' : 64, 'offset' : 32, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 5, 'dwarf' : 5, 'generic':'arg1', 'alt-name':'arg1', }, 475 { 'name':'rsi' , 'bitsize' : 64, 'offset' : 40, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 4, 'dwarf' : 4, 'generic':'arg2', 'alt-name':'arg2', }, 476 { 'name':'rbp' , 'bitsize' : 64, 'offset' : 48, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 6, 'dwarf' : 6, 'generic':'fp' , 'alt-name':'fp', }, 477 { 'name':'rsp' , 'bitsize' : 64, 'offset' : 56, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 7, 'dwarf' : 7, 'generic':'sp' , 'alt-name':'sp', }, 478 { 'name':'r8' , 'bitsize' : 64, 'offset' : 64, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 8, 'dwarf' : 8, 'generic':'arg5', 'alt-name':'arg5', }, 479 { 'name':'r9' , 'bitsize' : 64, 'offset' : 72, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 9, 'dwarf' : 9, 'generic':'arg6', 'alt-name':'arg6', }, 480 { 'name':'r10' , 'bitsize' : 64, 'offset' : 80, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 10, 'dwarf' : 10}, 481 { 'name':'r11' , 'bitsize' : 64, 'offset' : 88, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 11, 'dwarf' : 11}, 482 { 'name':'r12' , 'bitsize' : 64, 'offset' : 96, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 12, 'dwarf' : 12}, 483 { 'name':'r13' , 'bitsize' : 64, 'offset' : 104, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 13, 'dwarf' : 13}, 484 { 'name':'r14' , 'bitsize' : 64, 'offset' : 112, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 14, 'dwarf' : 14}, 485 { 'name':'r15' , 'bitsize' : 64, 'offset' : 120, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 15, 'dwarf' : 15}, 486 { 'name':'rip' , 'bitsize' : 64, 'offset' : 128, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 16, 'dwarf' : 16, 'generic':'pc', 'alt-name':'pc' }, 487 { 'name':'rflags' , 'bitsize' : 64, 'offset' : 136, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'generic':'flags', 'alt-name':'flags' }, 488 { 'name':'cs' , 'bitsize' : 64, 'offset' : 144, 'encoding':'uint' , 'format':'hex' , 'set': 0 }, 489 { 'name':'fs' , 'bitsize' : 64, 'offset' : 152, 'encoding':'uint' , 'format':'hex' , 'set': 0 }, 490 { 'name':'gs' , 'bitsize' : 64, 'offset' : 160, 'encoding':'uint' , 'format':'hex' , 'set': 0 }, 491 ] 492 } 493 def __init__(self): 494 self.ResetRegisterValues() 495 496 @classmethod 497 def GetRegisterInfo(cls, regnum): 498 if regnum < 0 or regnum > len(cls.register_info['registers']): 499 return '' 500 501 reginfo = cls.register_info['registers'][regnum] 502 retval = '' 503 for i in list(reginfo.keys()): 504 v_str = str(reginfo[i]) 505 if i == 'set': 506 v_str = 'General Purpose Registers' 507 retval += "%s:%s;" % (str(i), v_str) 508 return retval 509 510 511 def ResetRegisterValues(self): 512 """ set all the registers to zero. """ 513 self.rax = 0 514 self.rbx = 0 515 self.rcx = 0 516 self.rdx = 0 517 self.rdi = 0 518 self.rsi = 0 519 self.rbp = 0 520 self.rsp = 0 521 self.r8 = 0 522 self.r9 = 0 523 self.r10 = 0 524 self.r11 = 0 525 self.r12 = 0 526 self.r13 = 0 527 self.r14 = 0 528 self.r15 = 0 529 self.rip = 0 530 self.rflags = 0 531 self.cs = 0 532 self.fs = 0 533 self.gs = 0 534 535 def __str__(self): 536 return """ 537 rax = {o.rax: <#018x} 538 rbx = {o.rbx: <#018x} 539 rcx = {o.rcx: <#018x} 540 rdx = {o.rdx: <#018x} 541 rdi = {o.rdi: <#018x} 542 rsi = {o.rsi: <#018x} 543 rbp = {o.rbp: <#018x} 544 rsp = {o.rsp: <#018x} 545 r8 = {o.r8: <#018x} 546 r9 = {o.r9: <#018x} 547 r10 = {o.r10: <#018x} 548 r11 = {o.r11: <#018x} 549 r12 = {o.r12: <#018x} 550 r13 = {o.r13: <#018x} 551 r14 = {o.r14: <#018x} 552 r15 = {o.r15: <#018x} 553 rip = {o.rip: <#018x} 554 rflags = {o.rflags: <#018x} 555 cs = {o.cs: <#018x} 556 fs = {o.fs: <#018x} 557 gs = {o.gs: <#018x} 558 """.format(o=self) 559 560 def GetPackedRegisterState(self): 561 """ get a struct.pack register data for passing to C constructs """ 562 return struct.pack('21Q', self.rax, self.rbx, self.rcx, self.rdx, self.rdi, 563 self.rsi, self.rbp, self.rsp, self.r8, self.r9, 564 self.r10, self.r11, self.r12, self.r13, self.r14, 565 self.r15, self.rip, self.rflags, self.cs, self.fs, self.gs) 566 567 def ReadRegisterDataFromKDPSavedState(self, kdp_state, kernel_version): 568 saved_state = kernel_version.CreateValueFromExpression(None, '(struct x86_saved_state64 *) '+ str(kdp_state.GetValueAsUnsigned())) 569 saved_state = saved_state.Dereference() 570 saved_state = PluginValue(saved_state) 571 self.ResetRegisterValues() 572 self.rdi = saved_state.GetChildMemberWithName('rdi').GetValueAsUnsigned() 573 self.rsi = saved_state.GetChildMemberWithName('rsi').GetValueAsUnsigned() 574 self.rdx = saved_state.GetChildMemberWithName('rdx').GetValueAsUnsigned() 575 self.r10 = saved_state.GetChildMemberWithName('r10').GetValueAsUnsigned() 576 self.r8 = saved_state.GetChildMemberWithName('r8').GetValueAsUnsigned() 577 self.r9 = saved_state.GetChildMemberWithName('r9').GetValueAsUnsigned() 578 self.r15 = saved_state.GetChildMemberWithName('r15').GetValueAsUnsigned() 579 self.r14 = saved_state.GetChildMemberWithName('r14').GetValueAsUnsigned() 580 self.r13 = saved_state.GetChildMemberWithName('r13').GetValueAsUnsigned() 581 self.r12 = saved_state.GetChildMemberWithName('r12').GetValueAsUnsigned() 582 self.r11 = saved_state.GetChildMemberWithName('r11').GetValueAsUnsigned() 583 self.rbp = saved_state.GetChildMemberWithName('rbp').GetValueAsUnsigned() 584 self.rbx = saved_state.GetChildMemberWithName('rbx').GetValueAsUnsigned() 585 self.rcx = saved_state.GetChildMemberWithName('rcx').GetValueAsUnsigned() 586 self.rax = saved_state.GetChildMemberWithName('rax').GetValueAsUnsigned() 587 self.rip = saved_state.GetChildMemberWithName('isf').GetChildMemberWithName('rip').GetValueAsUnsigned() 588 self.rflags = saved_state.GetChildMemberWithName('isf').GetChildMemberWithName('rflags').GetValueAsUnsigned() 589 self.rsp = saved_state.GetChildMemberWithName('isf').GetChildMemberWithName('rsp').GetValueAsUnsigned() 590 return self 591 592 def ReadRegisterDataFromKernelStack(self, kstack_saved_state_addr, kernel_version): 593 saved_state = kernel_version.CreateValueFromExpression(None, '(struct x86_kernel_state *) '+ str(kstack_saved_state_addr)) 594 saved_state = saved_state.Dereference() 595 saved_state = PluginValue(saved_state) 596 self.ResetRegisterValues() 597 self.rbx = saved_state.GetChildMemberWithName('k_rbx').GetValueAsUnsigned() 598 self.rsp = saved_state.GetChildMemberWithName('k_rsp').GetValueAsUnsigned() 599 self.rbp = saved_state.GetChildMemberWithName('k_rbp').GetValueAsUnsigned() 600 self.r12 = saved_state.GetChildMemberWithName('k_r12').GetValueAsUnsigned() 601 self.r13 = saved_state.GetChildMemberWithName('k_r13').GetValueAsUnsigned() 602 self.r14 = saved_state.GetChildMemberWithName('k_r14').GetValueAsUnsigned() 603 self.r15 = saved_state.GetChildMemberWithName('k_r15').GetValueAsUnsigned() 604 self.rip = saved_state.GetChildMemberWithName('k_rip').GetValueAsUnsigned() 605 return self 606 607 def ReadRegisterDataFromContinuation(self, continuation_ptr): 608 self.ResetRegisterValues() 609 self.rip = continuation_ptr 610 return self 611 612 613 614 615def IterateQueue(queue_head, element_ptr_type, element_field_name): 616 """ iterate over a queue in kernel of type queue_head_t. refer to osfmk/kern/queue.h 617 params: 618 queue_head - lldb.SBValue : Value object for queue_head. 619 element_type - lldb.SBType : a pointer type of the element 'next' points to. Typically its structs like thread, task etc.. 620 element_field_name - str : name of the field in target struct. 621 returns: 622 A generator does not return. It is used for iterating. 623 SBValue : an object thats of type (element_type) queue_head->next. Always a pointer object 624 """ 625 queue_head_addr = 0x0 626 if queue_head.TypeIsPointerType(): 627 queue_head_addr = queue_head.GetValueAsUnsigned() 628 else: 629 queue_head_addr = queue_head.GetAddress().GetLoadAddress(osplugin_target_obj) 630 cur_elt = queue_head.GetChildMemberWithName('next') 631 while True: 632 if not cur_elt.IsValid() or cur_elt.GetValueAsUnsigned() == 0 or cur_elt.GetValueAsUnsigned() == queue_head_addr: 633 break 634 elt = cur_elt.Cast(element_ptr_type) 635 yield elt 636 cur_elt = elt.GetChildMemberWithName(element_field_name).GetChildMemberWithName('next') 637 638def GetUniqueSessionID(process_obj): 639 """ Create a unique session identifier. 640 params: 641 process_obj: lldb.SBProcess object refering to connected process. 642 returns: 643 int - a unique number identified by processid and stopid. 644 """ 645 session_key_str = "" 646 if hasattr(process_obj, "GetUniqueID"): 647 session_key_str += str(process_obj.GetUniqueID()) + ":" 648 else: 649 session_key_str += "0:" 650 651 if hasattr(process_obj, "GetStopID"): 652 session_key_str += str(process_obj.GetStopID()) 653 else: 654 session_key_str +="1" 655 656 return hash(session_key_str) 657 658 659(archX86_64, archARMv7, archI386, archARMv8) = ("x86_64", "armv7", "i386", "arm64") 660 661class OperatingSystemPlugIn(object): 662 """Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class""" 663 664 def __init__(self, process): 665 '''Initialization needs a valid.SBProcess object''' 666 self.process = None 667 self.registers = None 668 self.threads = None 669 self.thread_cache = {} 670 self.current_session_id = 0 671 self.kdp_thread = None 672 if type(process) is lldb.SBProcess and process.IsValid(): 673 global osplugin_target_obj 674 self.process = process 675 self._target = process.target 676 osplugin_target_obj = self._target 677 self.current_session_id = GetUniqueSessionID(self.process) 678 self.version = self._target.FindGlobalVariables('version', 1).GetValueAtIndex(0) 679 self.kernel_stack_size = self._target.FindGlobalVariables('kernel_stack_size', 1).GetValueAtIndex(0).GetValueAsUnsigned() 680 self.kernel_context_size = 0 681 self.connected_over_kdp = False 682 # connected_to_debugserver signifies if we are connected to astris or other gdbserver instance 683 # that has the correct thread state for on core threads. For kdp and coredumps we rely on in memory 684 # state of threads. 685 self.connected_to_debugserver = True 686 plugin_string = self.process.GetPluginName().lower() 687 if plugin_string.find("kdp") >=0: 688 self.connected_over_kdp = True 689 self.connected_to_debugserver = False 690 #print "version", self.version, "kernel_stack_size", self.kernel_stack_size, "context_size", self.kernel_context_size 691 self.threads = None # Will be an dictionary containing info for each thread 692 triple = self.process.target.triple 693 arch = triple.split('-')[0].lower() 694 self.target_arch = "" 695 self.kernel_context_size = 0 696 if arch == archX86_64 : 697 self.target_arch = archX86_64 698 print("Target arch: x86_64") 699 self.register_set = X86_64RegisterSet() 700 self.kernel_context_size = self._target.FindFirstType('x86_kernel_state').GetByteSize() 701 self.kernel_thread_state_size = self._target.FindFirstType('struct thread_kernel_state').GetByteSize() 702 elif arch.startswith(archARMv7) : 703 self.target_arch = arch 704 print("Target arch: " + self.target_arch) 705 self.register_set = Armv7_RegisterSet() 706 elif arch.startswith(archARMv8): 707 self.target_arch = arch 708 print("Target arch: " + self.target_arch) 709 self.register_set = Armv8_RegisterSet() 710 # connection intel arm 711 # kdp Memory Memory 712 # gdb Server Server 713 # coredump Memory Server 714 if not self.connected_over_kdp : 715 if plugin_string.find('core') >= 0 and self.target_arch == archX86_64: 716 self.connected_to_debugserver = False 717 self.registers = self.register_set.register_info 718 if self.connected_to_debugserver: 719 print("Connected to live debugserver or arm core. Will associate on-core threads to registers reported by server.") 720 else: 721 print("Instantiating threads completely from saved state in memory.") 722 723 def create_thread(self, tid, context): 724 # tid == deadbeef means its a custom thread which kernel does not know of. 725 if tid == 0xdeadbeef : 726 # tid manipulation should be the same as in "switchtoregs" code in lldbmacros/process.py . 727 tid = 0xdead0000 | (context & ~0xffff0000) 728 tid = tid & 0xdeadffff 729 thread_obj = { 'tid' : tid, 730 'ptr' : context, 731 'name' : 'switchtoregs' + hex(context), 732 'queue' : 'None', 733 'state' : 'stopped', 734 'stop_reason' : 'none' 735 } 736 self.thread_cache[tid] = thread_obj 737 return thread_obj 738 739 th_ptr = context 740 th = self.version.CreateValueFromExpression(str(th_ptr), '(struct thread *)' + str(th_ptr)) 741 thread_id = th.GetChildMemberWithName('thread_id').GetValueAsUnsigned() 742 if tid != thread_id: 743 print("FATAL ERROR: Creating thread from memory 0x%x with tid in mem=%d when requested tid = %d " % (context, thread_id, tid)) 744 return None 745 thread_obj = { 'tid' : thread_id, 746 'ptr' : th.GetValueAsUnsigned(), 747 'name' : hex(th.GetValueAsUnsigned()).rstrip('L'), 748 'queue' : hex(th.GetChildMemberWithName('wait_queue').GetValueAsUnsigned()).rstrip('L'), 749 'state' : 'stopped', 750 'stop_reason' : 'none' 751 } 752 if self.current_session_id != GetUniqueSessionID(self.process): 753 self.thread_cache = {} 754 self.current_session_id = GetUniqueSessionID(self.process) 755 756 self.thread_cache[tid] = thread_obj 757 return thread_obj 758 759 760 def get_thread_info(self): 761 self.kdp_thread = None 762 self.kdp_state = None 763 if self.connected_over_kdp : 764 kdp = self._target.FindGlobalVariables('kdp',1).GetValueAtIndex(0) 765 kdp_state = kdp.GetChildMemberWithName('saved_state') 766 kdp_thread = kdp.GetChildMemberWithName('kdp_thread') 767 if kdp_thread and kdp_thread.GetValueAsUnsigned() != 0: 768 self.kdp_thread = kdp_thread 769 self.kdp_state = kdp_state 770 kdp_thid = kdp_thread.GetChildMemberWithName('thread_id').GetValueAsUnsigned() 771 self.create_thread(kdp_thid, kdp_thread.GetValueAsUnsigned()) 772 self.thread_cache[kdp_thid]['core']=0 773 retval = [self.thread_cache[kdp_thid]] 774 return retval 775 else: 776 print("FATAL FAILURE: Unable to find kdp_thread state for this connection.") 777 return [] 778 779 num_threads = self._target.FindGlobalVariables('threads_count',1).GetValueAtIndex(0).GetValueAsUnsigned() 780 #In case we are caught before threads are initialized. Fallback to threads known by astris/gdb server. 781 if num_threads <=0 : 782 return [] 783 784 self.current_session_id = GetUniqueSessionID(self.process) 785 self.threads = [] 786 self.thread_cache = {} 787 self.processors = [] 788 try: 789 processor_list_val = PluginValue(self._target.FindGlobalVariables('processor_list',1).GetValueAtIndex(0)) 790 while processor_list_val.IsValid() and processor_list_val.GetValueAsUnsigned() !=0 : 791 th = processor_list_val.GetChildMemberWithName('active_thread') 792 th_id = th.GetChildMemberWithName('thread_id').GetValueAsUnsigned() 793 cpu_id = processor_list_val.GetChildMemberWithName('cpu_id').GetValueAsUnsigned() 794 self.processors.append({'active_thread': th.GetValueAsUnsigned(), 'cpu_id': cpu_id}) 795 self.create_thread(th_id, th.GetValueAsUnsigned()) 796 if self.connected_to_debugserver: 797 self.thread_cache[th_id]['core'] = cpu_id 798 self.thread_cache[th_id]['queue'] = "cpu-%d" % int(cpu_id) 799 nth = self.thread_cache[th_id] 800 self.threads.append(nth) 801 self.thread_cache[nth['tid']] = nth 802 processor_list_val = processor_list_val.GetChildMemberWithName('processor_list') 803 except KeyboardInterrupt as ke: 804 print("OS Plugin Interrupted during thread loading process. \nWARNING:Thread registers and backtraces may not be accurate.") 805 return self.threads 806 807 if hasattr(self.process, 'CreateOSPluginThread'): 808 return self.threads 809 810 # FIXME remove legacy code 811 try: 812 thread_q_head = self._target.FindGlobalVariables('threads', 1).GetValueAtIndex(0) 813 thread_type = self._target.FindFirstType('thread') 814 thread_ptr_type = thread_type.GetPointerType() 815 for th in IterateQueue(thread_q_head, thread_ptr_type, 'threads'): 816 th_id = th.GetChildMemberWithName('thread_id').GetValueAsUnsigned() 817 self.create_thread(th_id, th.GetValueAsUnsigned()) 818 nth = self.thread_cache[th_id] 819 for cputhread in self.processors: 820 if cputhread['active_thread'] == nth['ptr']: 821 nth['core'] = cputhread['cpu_id'] 822 self.threads.append( nth ) 823 except KeyboardInterrupt as ke: 824 print("OS Plugin Interrupted during thread loading process. \nWARNING:Thread registers and backtraces may not be accurate.") 825 return self.threads 826 # end legacy code 827 return self.threads 828 829 def get_register_info(self): 830 if self.registers == None: 831 print("Register Information not found ") 832 return self.register_set.register_info 833 834 def get_register_data(self, tid): 835 thobj = None 836 try: 837 regs = self.register_set 838 if self.current_session_id != GetUniqueSessionID(self.process): 839 self.thread_cache = {} 840 self.current_session_id = GetUniqueSessionID(self.process) 841 if tid in self.thread_cache: 842 843 #Check if the thread is a fake one. Then create and return registers directly 844 if self.thread_cache[tid]['name'].find('switchtoregs') == 0: 845 savedstateobj = self.version.CreateValueFromExpression(None, '(uintptr_t *) ' + str(self.thread_cache[tid]['ptr'])) 846 regs.ReadRegisterDataFromKDPSavedState(savedstateobj, self.version) 847 return regs.GetPackedRegisterState() 848 849 thobj = self.version.CreateValueFromExpression(self.thread_cache[tid]['name'], '(struct thread *)' + str(self.thread_cache[tid]['ptr'])) 850 851 if thobj == None : 852 print("FATAL ERROR: Could not find thread with id %d" % tid) 853 regs.ResetRegisterValues() 854 return regs.GetPackedRegisterState() 855 856 if self.kdp_thread and self.kdp_thread.GetValueAsUnsigned() == thobj.GetValueAsUnsigned(): 857 regs.ReadRegisterDataFromKDPSavedState(self.kdp_state, self.version) 858 return regs.GetPackedRegisterState() 859 if int(PluginValue(thobj).GetChildMemberWithName('kernel_stack').GetValueAsUnsigned()) != 0 : 860 if self.target_arch == archX86_64 : 861 # we do have a stack so lets get register information 862 saved_state_addr = PluginValue(thobj).GetChildMemberWithName('kernel_stack').GetValueAsUnsigned() + self.kernel_stack_size - self.kernel_thread_state_size 863 regs.ReadRegisterDataFromKernelStack(saved_state_addr, self.version) 864 return regs.GetPackedRegisterState() 865 elif self.target_arch.startswith(archARMv7) and int(PluginValue(thobj).GetChildMemberWithName('machine').GetChildMemberWithName('kstackptr').GetValueAsUnsigned()) != 0: 866 #we have stack on the machine.kstackptr. 867 saved_state_addr = PluginValue(thobj).GetChildMemberWithName('machine').GetChildMemberWithName('kstackptr').GetValueAsUnsigned() 868 regs.ReadRegisterDataFromKernelStack(saved_state_addr, self.version) 869 return regs.GetPackedRegisterState() 870 elif self.target_arch.startswith(archARMv8) and int(PluginValue(thobj).GetChildMemberWithName('machine').GetChildMemberWithName('kstackptr').GetValueAsUnsigned()) != 0: 871 saved_state_addr = PluginValue(thobj).GetChildMemberWithName('machine').GetChildMemberWithName('kstackptr').GetValueAsUnsigned() 872 arm_ctx = PluginValue(self.version.CreateValueFromExpression(None, '(struct arm_kernel_context *) ' + str(saved_state_addr))) 873 arm_ss_addr = arm_ctx.GetChildMemberWithName('ss').GetLoadAddress() 874 regs.ReadRegisterDataFromKernelStack(arm_ss_addr, self.version) 875 return regs.GetPackedRegisterState() 876 elif self.target_arch == archX86_64 or self.target_arch.startswith(archARMv7) or self.target_arch.startswith(archARMv8): 877 regs.ReadRegisterDataFromContinuation( PluginValue(thobj).GetChildMemberWithName('continuation').GetValueAsAddress()) 878 return regs.GetPackedRegisterState() 879 #incase we failed very miserably 880 except KeyboardInterrupt as ke: 881 print("OS Plugin Interrupted during thread register load. \nWARNING:Thread registers and backtraces may not be accurate. for tid = %d" % tid) 882 regs.ResetRegisterValues() 883 print("FATAL ERROR: Failed to get register state for thread id 0x%x " % tid) 884 print(thobj) 885 return regs.GetPackedRegisterState() 886