4 #source of register info is from http://opensource.apple.com/source/gdb/gdb-962/src/gdb/arm-tdep.c
7 osplugin_target_obj
= None
9 class PluginValue(lldb
.SBValue
):
10 def GetChildMemberWithName(val
, name
):
11 val_type
= val
.GetType()
12 if val_type
.IsPointerType() == True:
13 val_type
= val_type
.GetPointeeType()
14 for i
in range(val_type
.GetNumberOfFields()):
15 if name
== val_type
.GetFieldAtIndex(i
).GetName():
16 return PluginValue(val
.GetChildAtIndex(i
))
19 class Armv8_RegisterSet(object):
20 """ register info set for armv8 64 bit architecture"""
21 register_info
= { 'sets' : ['GPR'],
23 {'name': 'x0' , 'bitsize':64, 'offset': 0, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 0, 'dwarf': 0, 'alt-name':'arg1', 'generic':'arg1'}
,
24 {'name': 'x1' , 'bitsize':64, 'offset': 8, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 1, 'dwarf': 1, 'alt-name':'arg2', 'generic':'arg2'}
,
25 {'name': 'x2' , 'bitsize':64, 'offset': 16, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 2, 'dwarf': 2, 'alt-name':'arg3', 'generic':'arg3'}
,
26 {'name': 'x3' , 'bitsize':64, 'offset': 24, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 3, 'dwarf': 3, 'alt-name':'arg4', 'generic':'arg4'}
,
27 {'name': 'x4' , 'bitsize':64, 'offset': 32, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 4, 'dwarf': 4, 'alt-name':'arg5', 'generic':'arg5'}
,
28 {'name': 'x5' , 'bitsize':64, 'offset': 40, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 5, 'dwarf': 5, 'alt-name':'arg6', 'generic':'arg6'}
,
29 {'name': 'x6' , 'bitsize':64, 'offset': 48, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 6, 'dwarf': 6, 'alt-name':'arg7', 'generic':'arg7'}
,
30 {'name': 'x7' , 'bitsize':64, 'offset': 56, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 7, 'dwarf': 7, 'alt-name':'arg8', 'generic':'arg8'}
,
31 {'name': 'x8' , 'bitsize':64, 'offset': 64, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 8, 'dwarf': 8}
,
32 {'name': 'x9' , 'bitsize':64, 'offset': 72, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 9, 'dwarf': 9}
,
33 {'name': 'x10' , 'bitsize':64, 'offset': 80, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':10, 'dwarf':10}
,
34 {'name': 'x11' , 'bitsize':64, 'offset': 88, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':11, 'dwarf':11}
,
35 {'name': 'x12' , 'bitsize':64, 'offset': 96, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':12, 'dwarf':12}
,
36 {'name': 'x13' , 'bitsize':64, 'offset':104, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':13, 'dwarf':13}
,
37 {'name': 'x14' , 'bitsize':64, 'offset':112, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':14, 'dwarf':14}
,
38 {'name': 'x15' , 'bitsize':64, 'offset':120, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':15, 'dwarf':15}
,
39 {'name': 'x16' , 'bitsize':64, 'offset':128, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':16, 'dwarf':16}
,
40 {'name': 'x17' , 'bitsize':64, 'offset':136, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':17, 'dwarf':17}
,
41 {'name': 'x18' , 'bitsize':64, 'offset':144, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':18, 'dwarf':18}
,
42 {'name': 'x19' , 'bitsize':64, 'offset':152, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':19, 'dwarf':19}
,
43 {'name': 'x20' , 'bitsize':64, 'offset':160, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':20, 'dwarf':20}
,
44 {'name': 'x21' , 'bitsize':64, 'offset':168, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':21, 'dwarf':21}
,
45 {'name': 'x22' , 'bitsize':64, 'offset':176, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':22, 'dwarf':22}
,
46 {'name': 'x23' , 'bitsize':64, 'offset':184, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':23, 'dwarf':23}
,
47 {'name': 'x24' , 'bitsize':64, 'offset':192, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':24, 'dwarf':24}
,
48 {'name': 'x25' , 'bitsize':64, 'offset':200, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':25, 'dwarf':25}
,
49 {'name': 'x26' , 'bitsize':64, 'offset':208, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':26, 'dwarf':26}
,
50 {'name': 'x27' , 'bitsize':64, 'offset':216, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':27, 'dwarf':27}
,
51 {'name': 'x28' , 'bitsize':64, 'offset':224, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':28, 'dwarf':28}
,
52 {'name': 'fp' , 'bitsize':64, 'offset':232, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':29, 'dwarf':29, 'alt-name': 'fp', 'generic':'fp'}
,
53 {'name': 'lr' , 'bitsize':64, 'offset':240, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':30, 'dwarf':30, 'alt-name': 'lr', 'generic':'lr'}
,
54 {'name': 'sp' , 'bitsize':64, 'offset':248, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':31, 'dwarf':31, 'alt-name': 'sp', 'generic':'sp'}
,
55 {'name': 'pc' , 'bitsize':64, 'offset':256, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':32, 'dwarf':32, 'alt-name': 'pc', 'generic':'pc'}
,
56 {'name': 'far' , 'bitsize':64, 'offset':264, 'encoding':'uint', 'format':'hex', 'set':0}
,
57 {'name': 'cpsr', 'bitsize':32, 'offset':272, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':33, 'dwarf':33, 'generic':'flags'}
,
58 {'name': 'esr' , 'bitsize':32, 'offset':276, 'encoding':'uint', 'format':'hex', 'set':0}
,
63 self
.switch_context_address
= osplugin_target_obj
.FindSymbols('Switch_context')[0].GetSymbol().GetStartAddress().GetLoadAddress(osplugin_target_obj
)
64 self
.ResetRegisterValues()
65 def ResetRegisterValues(self
):
106 def GetPackedRegisterState(self
):
107 return struct
.pack('34QII', self
.x0
, self
.x1
, self
.x2
, self
.x3
, self
.x4
, self
.x5
,
108 self
.x6
, self
.x7
, self
.x8
, self
.x9
, self
.x10
, self
.x11
, self
.x12
, self
.x13
,
109 self
.x14
, self
.x15
, self
.x16
, self
.x17
, self
.x18
, self
.x19
, self
.x20
, self
.x21
,
110 self
.x22
, self
.x23
, self
.x24
, self
.x25
, self
.x26
, self
.x27
, self
.x28
, self
.fp
,
111 self
.lr
, self
.sp
, self
.pc
, self
.far
, self
.cpsr
, self
.esr
)
113 def ReadRegisterDataFromKDPSavedState(self
, kdp_state
, kernel_version
):
114 """ Setup register values from KDP saved information.
116 saved_state
= kernel_version
.CreateValueFromExpression(None, '(struct arm_saved_state64 *) ' + str(kdp_state
.GetValueAsUnsigned()))
117 saved_state
= saved_state
.Dereference()
118 saved_state
= PluginValue(saved_state
)
119 self
.ResetRegisterValues()
120 self
.x0
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(0).GetValueAsUnsigned()
121 self
.x1
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(1).GetValueAsUnsigned()
122 self
.x2
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(2).GetValueAsUnsigned()
123 self
.x3
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(3).GetValueAsUnsigned()
124 self
.x4
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(4).GetValueAsUnsigned()
125 self
.x5
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(5).GetValueAsUnsigned()
126 self
.x6
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(6).GetValueAsUnsigned()
127 self
.x7
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(7).GetValueAsUnsigned()
128 self
.x8
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(8).GetValueAsUnsigned()
129 self
.x9
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(9).GetValueAsUnsigned()
130 self
.x10
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(10).GetValueAsUnsigned()
131 self
.x11
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(11).GetValueAsUnsigned()
132 self
.x12
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(12).GetValueAsUnsigned()
133 self
.x13
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(13).GetValueAsUnsigned()
134 self
.x14
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(14).GetValueAsUnsigned()
135 self
.x15
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(15).GetValueAsUnsigned()
136 self
.x16
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(16).GetValueAsUnsigned()
137 self
.x17
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(17).GetValueAsUnsigned()
138 self
.x18
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(18).GetValueAsUnsigned()
139 self
.x19
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(19).GetValueAsUnsigned()
140 self
.x20
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(20).GetValueAsUnsigned()
141 self
.x21
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(21).GetValueAsUnsigned()
142 self
.x22
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(22).GetValueAsUnsigned()
143 self
.x23
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(23).GetValueAsUnsigned()
144 self
.x24
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(24).GetValueAsUnsigned()
145 self
.x25
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(25).GetValueAsUnsigned()
146 self
.x26
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(26).GetValueAsUnsigned()
147 self
.x27
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(27).GetValueAsUnsigned()
148 self
.x28
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(28).GetValueAsUnsigned()
149 self
.fp
= saved_state
.GetChildMemberWithName('fp').GetValueAsUnsigned()
150 self
.lr
= saved_state
.GetChildMemberWithName('lr').GetValueAsUnsigned()
151 self
.sp
= saved_state
.GetChildMemberWithName('sp').GetValueAsUnsigned()
152 self
.pc
= saved_state
.GetChildMemberWithName('pc').GetValueAsUnsigned()
153 self
.far
= saved_state
.GetChildMemberWithName('far').GetValueAsUnsigned()
154 self
.cpsr
= saved_state
.GetChildMemberWithName('cpsr').GetValueAsUnsigned()
155 self
.esr
= saved_state
.GetChildMemberWithName('esr').GetValueAsUnsigned()
158 def ReadRegisterDataFromKernelStack(self
, kstack_saved_state_addr
, kernel_version
):
159 saved_state
= kernel_version
.CreateValueFromExpression(None, '(arm_kernel_saved_state_t *) '+ str(kstack_saved_state_addr
))
160 saved_state
= saved_state
.Dereference()
161 saved_state
= PluginValue(saved_state
)
162 self
.ResetRegisterValues()
163 self
.x16
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(0).GetValueAsUnsigned()
164 self
.x17
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(1).GetValueAsUnsigned()
165 self
.x19
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(2).GetValueAsUnsigned()
166 self
.x20
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(3).GetValueAsUnsigned()
167 self
.x21
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(4).GetValueAsUnsigned()
168 self
.x22
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(5).GetValueAsUnsigned()
169 self
.x23
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(6).GetValueAsUnsigned()
170 self
.x24
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(7).GetValueAsUnsigned()
171 self
.x25
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(8).GetValueAsUnsigned()
172 self
.x26
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(9).GetValueAsUnsigned()
173 self
.x27
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(10).GetValueAsUnsigned()
174 self
.x28
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(11).GetValueAsUnsigned()
175 self
.fp
= saved_state
.GetChildMemberWithName('fp').GetValueAsUnsigned()
176 self
.lr
= saved_state
.GetChildMemberWithName('lr').GetValueAsUnsigned()
177 self
.sp
= saved_state
.GetChildMemberWithName('sp').GetValueAsUnsigned()
178 # pc for a blocked thread is treated to be the next instruction it would run after thread switch.
179 self
.pc
= self
.switch_context_address
180 self
.cpsr
= saved_state
.GetChildMemberWithName('cpsr').GetValueAsUnsigned()
183 def ReadRegisterDataFromContinuation(self
, continuation_ptr
):
184 self
.ResetRegisterValues()
185 self
.pc
= continuation_ptr
189 def GetRegisterInfo(cls
, regnum
):
190 if regnum
< 0 or regnum
> len(cls
.register_info
['registers']):
193 reginfo
= cls
.register_info
['registers'][regnum
]
195 for i
in reginfo
.keys():
196 v_str
= str(reginfo
[i
])
198 v_str
= 'General Purpose Registers'
199 retval
+= "%s:%s;" % (str(i
), v_str
)
204 class Armv7_RegisterSet(object):
205 """ register info set for armv7 32 bit architecture """
206 register_info
= { 'sets' : ['GPR'],
208 { 'name':'r0' , 'bitsize' : 32, 'offset' : 0, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 0, 'dwarf' : 0}
,
209 { 'name':'r1' , 'bitsize' : 32, 'offset' : 4, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 1, 'dwarf' : 1}
,
210 { 'name':'r2' , 'bitsize' : 32, 'offset' : 8, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 2, 'dwarf' : 2}
,
211 { 'name':'r3' , 'bitsize' : 32, 'offset' : 12, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 3, 'dwarf' : 3}
,
212 { 'name':'r4' , 'bitsize' : 32, 'offset' : 16, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 4, 'dwarf' : 4}
,
213 { 'name':'r5' , 'bitsize' : 32, 'offset' : 20, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 5, 'dwarf' : 5}
,
214 { 'name':'r6' , 'bitsize' : 32, 'offset' : 24, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 6, 'dwarf' : 6}
,
215 { 'name':'r7' , 'bitsize' : 32, 'offset' : 28, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 7, 'dwarf' : 7}
,
216 { 'name':'r8' , 'bitsize' : 32, 'offset' : 32, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 8, 'dwarf' : 8}
,
217 { 'name':'r9' , 'bitsize' : 32, 'offset' : 36, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 9, 'dwarf' : 9}
,
218 { 'name':'r10' , 'bitsize' : 32, 'offset' : 40, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':10, 'dwarf' :10}
,
219 { 'name':'r11' , 'bitsize' : 32, 'offset' : 44, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':11, 'dwarf' :11, 'alt-name': 'fp', 'generic': 'fp'}
,
220 { 'name':'r12' , 'bitsize' : 32, 'offset' : 48, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':12, 'dwarf' :12}
,
221 { 'name':'sp' , 'bitsize' : 32, 'offset' : 52, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':13, 'dwarf' :13, 'generic': 'sp'}
,
222 { 'name':'lr' , 'bitsize' : 32, 'offset' : 56, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':14, 'dwarf' :14, 'generic': 'lr'}
,
223 { 'name':'pc' , 'bitsize' : 32, 'offset' : 60, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':15, 'dwarf' :15, 'generic': 'pc'}
,
224 { 'name':'cpsr' , 'bitsize' : 32, 'offset' : 64, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':16, 'dwarf' :16, 'generic':'flags'}
,
225 { 'name':'fsr' , 'bitsize' : 32, 'offset' : 68, 'encoding':'uint', 'format':'hex', 'set':0}
,
226 { 'name':'far' , 'bitsize' : 32, 'offset' : 72, 'encoding':'uint', 'format':'hex', 'set':0}
231 self
.switch_context_address
= osplugin_target_obj
.FindSymbols('load_reg')[0].GetSymbol().GetStartAddress().GetLoadAddress(osplugin_target_obj
) + 8
232 self
.ResetRegisterValues()
235 def GetRegisterInfo(cls
, regnum
):
236 if regnum
< 0 or regnum
> len(cls
.register_info
['registers']):
239 reginfo
= cls
.register_info
['registers'][regnum
]
241 for i
in reginfo
.keys():
242 v_str
= str(reginfo
[i
])
244 v_str
= 'General Purpose Registers'
245 retval
+= "%s:%s;" % (str(i
), v_str
)
248 def ResetRegisterValues(self
):
281 r10 = {o.r10: <#010x}
282 r11 = {o.r11: <#010x}
283 r12 = {o.r12: <#010x}
287 cpsr = {o.cpsr: <#010x}
288 fsr = {o.fsr : <#010x}
289 far = {o.far : <#010x}
292 def GetPackedRegisterState(self
):
293 return struct
.pack('19I', self
.r0
, self
.r1
, self
.r2
, self
.r3
,
294 self
.r4
, self
.r5
, self
.r6
, self
.r7
,
295 self
.r8
, self
.r9
, self
.r10
, self
.r11
,
296 self
.r12
, self
.sp
, self
.lr
, self
.pc
,
297 self
.cpsr
, self
.fsr
, self
.far
)
299 def ReadRegisterDataFromKDPSavedState(self
, kdp_state
, kernel_version
):
300 saved_state
= kernel_version
.CreateValueFromExpression(None, '(struct arm_saved_state *) ' + str(kdp_state
.GetValueAsUnsigned()))
301 saved_state
= saved_state
.Dereference()
302 saved_state
= PluginValue(saved_state
)
303 self
.ResetRegisterValues()
304 self
.r0
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(0).GetValueAsUnsigned()
305 self
.r1
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(1).GetValueAsUnsigned()
306 self
.r2
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(2).GetValueAsUnsigned()
307 self
.r3
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(3).GetValueAsUnsigned()
308 self
.r4
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(4).GetValueAsUnsigned()
309 self
.r5
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(5).GetValueAsUnsigned()
310 self
.r6
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(6).GetValueAsUnsigned()
311 self
.r7
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(7).GetValueAsUnsigned()
312 self
.r8
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(8).GetValueAsUnsigned()
313 self
.r9
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(9).GetValueAsUnsigned()
314 self
.r10
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(10).GetValueAsUnsigned()
315 self
.r11
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(11).GetValueAsUnsigned()
316 self
.r12
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(12).GetValueAsUnsigned()
317 self
.sp
= saved_state
.GetChildMemberWithName('sp').GetValueAsUnsigned()
318 self
.lr
= saved_state
.GetChildMemberWithName('lr').GetValueAsUnsigned()
319 self
.pc
= saved_state
.GetChildMemberWithName('pc').GetValueAsUnsigned()
320 self
.cpsr
= saved_state
.GetChildMemberWithName('cpsr').GetValueAsUnsigned()
321 self
.fsr
= saved_state
.GetChildMemberWithName('fsr').GetValueAsUnsigned()
322 self
.far
= saved_state
.GetChildMemberWithName('far').GetValueAsUnsigned()
325 def ReadRegisterDataFromKernelStack(self
, kstack_saved_state_addr
, kernel_version
):
326 saved_state
= kernel_version
.CreateValueFromExpression(None, '(struct arm_saved_state *) '+ str(kstack_saved_state_addr
))
327 saved_state
= saved_state
.Dereference()
328 saved_state
= PluginValue(saved_state
)
329 self
.ResetRegisterValues()
330 self
.r0
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(0).GetValueAsUnsigned()
331 self
.r1
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(1).GetValueAsUnsigned()
332 self
.r2
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(2).GetValueAsUnsigned()
333 self
.r3
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(3).GetValueAsUnsigned()
334 self
.r4
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(4).GetValueAsUnsigned()
335 self
.r5
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(5).GetValueAsUnsigned()
336 self
.r6
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(6).GetValueAsUnsigned()
337 self
.r7
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(7).GetValueAsUnsigned()
338 self
.r8
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(8).GetValueAsUnsigned()
339 self
.r9
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(9).GetValueAsUnsigned()
340 self
.r10
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(10).GetValueAsUnsigned()
341 self
.r11
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(11).GetValueAsUnsigned()
342 self
.r12
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(12).GetValueAsUnsigned()
343 self
.sp
= saved_state
.GetChildMemberWithName('sp').GetValueAsUnsigned()
344 self
.lr
= saved_state
.GetChildMemberWithName('lr').GetValueAsUnsigned()
345 # pc for a blocked thread is treated to be the next instruction it would run after thread switch.
346 self
.pc
= self
.switch_context_address
347 self
.cpsr
= saved_state
.GetChildMemberWithName('cpsr').GetValueAsUnsigned()
348 self
.fsr
= saved_state
.GetChildMemberWithName('fsr').GetValueAsUnsigned()
349 self
.far
= saved_state
.GetChildMemberWithName('far').GetValueAsUnsigned()
352 def ReadRegisterDataFromContinuation(self
, continuation_ptr
):
353 self
.ResetRegisterValues()
354 self
.pc
= continuation_ptr
358 class I386_RegisterSet(object):
359 """ register info set for i386 architecture
361 register_info
= { 'sets' : ['GPR'],
363 { 'name': 'eax' , 'bitsize': 32, 'offset' : 0, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 0, 'dwarf': 0}
,
364 { 'name': 'ebx' , 'bitsize': 32, 'offset' : 4, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 3, 'dwarf': 3}
,
365 { 'name': 'ecx' , 'bitsize': 32, 'offset' : 8, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 1, 'dwarf': 1}
,
366 { 'name': 'edx' , 'bitsize': 32, 'offset' :12, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 2, 'dwarf': 2}
,
367 { 'name': 'edi' , 'bitsize': 32, 'offset' :16, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 7, 'dwarf': 7}
,
368 { 'name': 'esi' , 'bitsize': 32, 'offset' :20, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 6, 'dwarf': 6}
,
369 { 'name': 'ebp' , 'bitsize': 32, 'offset' :24, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 4, 'dwarf': 5, 'generic': 'fp', 'alt-name': 'fp'}
,
370 { 'name': 'esp' , 'bitsize': 32, 'offset' :28, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 5, 'dwarf': 4, 'generic': 'sp', 'alt-name': 'sp'}
,
371 { 'name': 'ss' , 'bitsize': 32, 'offset' :32, 'encoding': 'uint' , 'format':'hex' , 'set': 0}
,
372 { 'name': 'eflags', 'bitsize': 32, 'offset' :36, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 9, 'dwarf': 9, 'generic': 'flags'}
,
373 { 'name': 'eip' , 'bitsize': 32, 'offset' :40, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' :8, 'dwarf':8, 'generic': 'pc', 'alt-name': 'pc'}
,
374 { 'name': 'cs' , 'bitsize': 32, 'offset' :44, 'encoding': 'uint' , 'format':'hex' , 'set': 0}
,
375 { 'name': 'ds' , 'bitsize': 32, 'offset' :48, 'encoding': 'uint' , 'format':'hex' , 'set': 0}
,
376 { 'name': 'es' , 'bitsize': 32, 'offset' :52, 'encoding': 'uint' , 'format':'hex' , 'set': 0}
,
377 { 'name': 'fs' , 'bitsize': 32, 'offset' :56, 'encoding': 'uint' , 'format':'hex' , 'set': 0}
,
378 { 'name': 'gs' , 'bitsize': 32, 'offset' :60, 'encoding': 'uint' , 'format':'hex' , 'set': 0}
,
383 self
.ResetRegisterValues()
386 def GetRegisterInfo(cls
, regnum
):
387 if regnum
< 0 or regnum
> len(cls
.register_info
['registers']):
390 reginfo
= cls
.register_info
['registers'][regnum
]
392 for i
in reginfo
.keys():
393 v_str
= str(reginfo
[i
])
395 v_str
= 'General Purpose Registers'
396 retval
+= "%s:%s;" % (str(i
), v_str
)
399 def ResetRegisterValues(self
):
400 """ set all registers to zero """
429 eflags = {o.eflags: #010x}
438 def GetPackedRegisterState(self
):
439 """ get a struct.pack register data """
440 return struct
.pack('16I', self
.eax
, self
.ebx
, self
.ecx
,
441 self
.edx
, self
.edi
, self
.esi
,
442 self
.ebp
, self
.esp
, self
.ss
,
443 self
.eflags
, self
.eip
, self
.cs
,
444 self
.ds
, self
.es
, self
.fs
, self
.gs
447 def ReadRegisterDataFromKDPSavedState(self
, kdp_state
, kernel_version
):
448 """ to be implemented"""
451 def ReadRegisterDataFromKernelStack(self
, kstack_saved_state_addr
, kernel_version
):
452 """ to be implemented """
455 def ReadRegisterDataFromContinuation(self
, continuation_ptr
):
456 self
.ResetRegisterValues()
457 self
.eip
= continuation_ptr
461 class X86_64RegisterSet(object):
462 """ register info set for x86_64 architecture """
463 register_info
= { 'sets' : ['GPR'],
465 { 'name':'rax' , 'bitsize' : 64, 'offset' : 0, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 0, 'dwarf' : 0}
,
466 { 'name':'rbx' , 'bitsize' : 64, 'offset' : 8, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 3, 'dwarf' : 3}
,
467 { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 2, 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', }
,
468 { 'name':'rdx' , 'bitsize' : 64, 'offset' : 24, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 1, 'dwarf' : 1, 'generic':'arg3', 'alt-name':'arg3', }
,
469 { 'name':'rdi' , 'bitsize' : 64, 'offset' : 32, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 5, 'dwarf' : 5, 'generic':'arg1', 'alt-name':'arg1', }
,
470 { 'name':'rsi' , 'bitsize' : 64, 'offset' : 40, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 4, 'dwarf' : 4, 'generic':'arg2', 'alt-name':'arg2', }
,
471 { 'name':'rbp' , 'bitsize' : 64, 'offset' : 48, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 6, 'dwarf' : 6, 'generic':'fp' , 'alt-name':'fp', }
,
472 { 'name':'rsp' , 'bitsize' : 64, 'offset' : 56, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 7, 'dwarf' : 7, 'generic':'sp' , 'alt-name':'sp', }
,
473 { 'name':'r8' , 'bitsize' : 64, 'offset' : 64, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 8, 'dwarf' : 8, 'generic':'arg5', 'alt-name':'arg5', }
,
474 { 'name':'r9' , 'bitsize' : 64, 'offset' : 72, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 9, 'dwarf' : 9, 'generic':'arg6', 'alt-name':'arg6', }
,
475 { 'name':'r10' , 'bitsize' : 64, 'offset' : 80, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 10, 'dwarf' : 10}
,
476 { 'name':'r11' , 'bitsize' : 64, 'offset' : 88, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 11, 'dwarf' : 11}
,
477 { 'name':'r12' , 'bitsize' : 64, 'offset' : 96, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 12, 'dwarf' : 12}
,
478 { 'name':'r13' , 'bitsize' : 64, 'offset' : 104, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 13, 'dwarf' : 13}
,
479 { 'name':'r14' , 'bitsize' : 64, 'offset' : 112, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 14, 'dwarf' : 14}
,
480 { 'name':'r15' , 'bitsize' : 64, 'offset' : 120, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 15, 'dwarf' : 15}
,
481 { 'name':'rip' , 'bitsize' : 64, 'offset' : 128, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 16, 'dwarf' : 16, 'generic':'pc', 'alt-name':'pc' }
,
482 { 'name':'rflags' , 'bitsize' : 64, 'offset' : 136, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'generic':'flags', 'alt-name':'flags' }
,
483 { 'name':'cs' , 'bitsize' : 64, 'offset' : 144, 'encoding':'uint' , 'format':'hex' , 'set': 0 }
,
484 { 'name':'fs' , 'bitsize' : 64, 'offset' : 152, 'encoding':'uint' , 'format':'hex' , 'set': 0 }
,
485 { 'name':'gs' , 'bitsize' : 64, 'offset' : 160, 'encoding':'uint' , 'format':'hex' , 'set': 0 }
,
489 self
.ResetRegisterValues()
492 def GetRegisterInfo(cls
, regnum
):
493 if regnum
< 0 or regnum
> len(cls
.register_info
['registers']):
496 reginfo
= cls
.register_info
['registers'][regnum
]
498 for i
in reginfo
.keys():
499 v_str
= str(reginfo
[i
])
501 v_str
= 'General Purpose Registers'
502 retval
+= "%s:%s;" % (str(i
), v_str
)
506 def ResetRegisterValues(self
):
507 """ set all the registers to zero. """
532 rax = {o.rax: <#018x}
533 rbx = {o.rbx: <#018x}
534 rcx = {o.rcx: <#018x}
535 rdx = {o.rdx: <#018x}
536 rdi = {o.rdi: <#018x}
537 rsi = {o.rsi: <#018x}
538 rbp = {o.rbp: <#018x}
539 rsp = {o.rsp: <#018x}
542 r10 = {o.r10: <#018x}
543 r11 = {o.r11: <#018x}
544 r12 = {o.r12: <#018x}
545 r13 = {o.r13: <#018x}
546 r14 = {o.r14: <#018x}
547 r15 = {o.r15: <#018x}
548 rip = {o.rip: <#018x}
549 rflags = {o.rflags: <#018x}
555 def GetPackedRegisterState(self
):
556 """ get a struct.pack register data for passing to C constructs """
557 return struct
.pack('21Q', self
.rax
, self
.rbx
, self
.rcx
, self
.rdx
, self
.rdi
,
558 self
.rsi
, self
.rbp
, self
.rsp
, self
.r8
, self
.r9
,
559 self
.r10
, self
.r11
, self
.r12
, self
.r13
, self
.r14
,
560 self
.r15
, self
.rip
, self
.rflags
, self
.cs
, self
.fs
, self
.gs
)
562 def ReadRegisterDataFromKDPSavedState(self
, kdp_state
, kernel_version
):
563 saved_state
= kernel_version
.CreateValueFromExpression(None, '(struct x86_saved_state64 *) '+ str(kdp_state
.GetValueAsUnsigned()))
564 saved_state
= saved_state
.Dereference()
565 saved_state
= PluginValue(saved_state
)
566 self
.ResetRegisterValues()
567 self
.rdi
= saved_state
.GetChildMemberWithName('rdi').GetValueAsUnsigned()
568 self
.rsi
= saved_state
.GetChildMemberWithName('rsi').GetValueAsUnsigned()
569 self
.rdx
= saved_state
.GetChildMemberWithName('rdx').GetValueAsUnsigned()
570 self
.r10
= saved_state
.GetChildMemberWithName('r10').GetValueAsUnsigned()
571 self
.r8
= saved_state
.GetChildMemberWithName('r8').GetValueAsUnsigned()
572 self
.r9
= saved_state
.GetChildMemberWithName('r9').GetValueAsUnsigned()
573 self
.r15
= saved_state
.GetChildMemberWithName('r15').GetValueAsUnsigned()
574 self
.r14
= saved_state
.GetChildMemberWithName('r14').GetValueAsUnsigned()
575 self
.r13
= saved_state
.GetChildMemberWithName('r13').GetValueAsUnsigned()
576 self
.r12
= saved_state
.GetChildMemberWithName('r12').GetValueAsUnsigned()
577 self
.r11
= saved_state
.GetChildMemberWithName('r11').GetValueAsUnsigned()
578 self
.rbp
= saved_state
.GetChildMemberWithName('rbp').GetValueAsUnsigned()
579 self
.rbx
= saved_state
.GetChildMemberWithName('rbx').GetValueAsUnsigned()
580 self
.rcx
= saved_state
.GetChildMemberWithName('rcx').GetValueAsUnsigned()
581 self
.rax
= saved_state
.GetChildMemberWithName('rax').GetValueAsUnsigned()
582 self
.rip
= saved_state
.GetChildMemberWithName('isf').GetChildMemberWithName('rip').GetValueAsUnsigned()
583 self
.rflags
= saved_state
.GetChildMemberWithName('isf').GetChildMemberWithName('rflags').GetValueAsUnsigned()
584 self
.rsp
= saved_state
.GetChildMemberWithName('isf').GetChildMemberWithName('rsp').GetValueAsUnsigned()
587 def ReadRegisterDataFromKernelStack(self
, kstack_saved_state_addr
, kernel_version
):
588 saved_state
= kernel_version
.CreateValueFromExpression(None, '(struct x86_kernel_state *) '+ str(kstack_saved_state_addr
))
589 saved_state
= saved_state
.Dereference()
590 saved_state
= PluginValue(saved_state
)
591 self
.ResetRegisterValues()
592 self
.rbx
= saved_state
.GetChildMemberWithName('k_rbx').GetValueAsUnsigned()
593 self
.rsp
= saved_state
.GetChildMemberWithName('k_rsp').GetValueAsUnsigned()
594 self
.rbp
= saved_state
.GetChildMemberWithName('k_rbp').GetValueAsUnsigned()
595 self
.r12
= saved_state
.GetChildMemberWithName('k_r12').GetValueAsUnsigned()
596 self
.r13
= saved_state
.GetChildMemberWithName('k_r13').GetValueAsUnsigned()
597 self
.r14
= saved_state
.GetChildMemberWithName('k_r14').GetValueAsUnsigned()
598 self
.r15
= saved_state
.GetChildMemberWithName('k_r15').GetValueAsUnsigned()
599 self
.rip
= saved_state
.GetChildMemberWithName('k_rip').GetValueAsUnsigned()
602 def ReadRegisterDataFromContinuation(self
, continuation_ptr
):
603 self
.ResetRegisterValues()
604 self
.rip
= continuation_ptr
610 def IterateQueue(queue_head
, element_ptr_type
, element_field_name
):
611 """ iterate over a queue in kernel of type queue_head_t. refer to osfmk/kern/queue.h
613 queue_head - lldb.SBValue : Value object for queue_head.
614 element_type - lldb.SBType : a pointer type of the element 'next' points to. Typically its structs like thread, task etc..
615 element_field_name - str : name of the field in target struct.
617 A generator does not return. It is used for iterating.
618 SBValue : an object thats of type (element_type) queue_head->next. Always a pointer object
620 queue_head_addr
= 0x0
621 if queue_head
.TypeIsPointerType():
622 queue_head_addr
= queue_head
.GetValueAsUnsigned()
624 queue_head_addr
= queue_head
.GetAddress().GetLoadAddress(osplugin_target_obj
)
625 cur_elt
= queue_head
.GetChildMemberWithName('next')
627 if not cur_elt
.IsValid() or cur_elt
.GetValueAsUnsigned() == 0 or cur_elt
.GetValueAsUnsigned() == queue_head_addr
:
629 elt
= cur_elt
.Cast(element_ptr_type
)
631 cur_elt
= elt
.GetChildMemberWithName(element_field_name
).GetChildMemberWithName('next')
633 def GetUniqueSessionID(process_obj
):
634 """ Create a unique session identifier.
636 process_obj: lldb.SBProcess object refering to connected process.
638 int - a unique number identified by processid and stopid.
641 if hasattr(process_obj
, "GetUniqueID"):
642 session_key_str
+= str(process_obj
.GetUniqueID()) + ":"
644 session_key_str
+= "0:"
646 if hasattr(process_obj
, "GetStopID"):
647 session_key_str
+= str(process_obj
.GetStopID())
649 session_key_str
+="1"
651 return hash(session_key_str
)
654 (archX86_64
, archARMv7
, archI386
, archARMv8
) = ("x86_64", "armv7", "i386", "arm64")
656 class OperatingSystemPlugIn(object):
657 """Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class"""
659 def __init__(self
, process
):
660 '''Initialization needs a valid.SBProcess object'''
662 self
.registers
= None
664 self
.thread_cache
= {}
665 self
.current_session_id
= 0
666 self
.kdp_thread
= None
667 if type(process
) is lldb
.SBProcess
and process
.IsValid():
668 global osplugin_target_obj
669 self
.process
= process
670 self
._target
= process
.target
671 osplugin_target_obj
= self
._target
672 self
.current_session_id
= GetUniqueSessionID(self
.process
)
673 self
.version
= self
._target
.FindGlobalVariables('version', 1).GetValueAtIndex(0)
674 self
.kernel_stack_size
= self
._target
.FindGlobalVariables('kernel_stack_size', 1).GetValueAtIndex(0).GetValueAsUnsigned()
675 self
.kernel_context_size
= 0
676 self
.connected_over_kdp
= False
677 # connected_to_debugserver signifies if we are connected to astris or other gdbserver instance
678 # that has the correct thread state for on core threads. For kdp and coredumps we rely on in memory
680 self
.connected_to_debugserver
= True
681 plugin_string
= self
.process
.GetPluginName().lower()
682 if plugin_string
.find("kdp") >=0:
683 self
.connected_over_kdp
= True
684 self
.connected_to_debugserver
= False
685 #print "version", self.version, "kernel_stack_size", self.kernel_stack_size, "context_size", self.kernel_context_size
686 self
.threads
= None # Will be an dictionary containing info for each thread
687 triple
= self
.process
.target
.triple
688 arch
= triple
.split('-')[0].lower()
689 self
.target_arch
= ""
690 self
.kernel_context_size
= 0
691 if arch
== archX86_64
:
692 self
.target_arch
= archX86_64
693 print "Target arch: x86_64"
694 self
.register_set
= X86_64RegisterSet()
695 self
.kernel_context_size
= self
._target
.FindFirstType('x86_kernel_state').GetByteSize()
696 self
.kernel_thread_state_size
= self
._target
.FindFirstType('struct thread_kernel_state').GetByteSize()
697 elif arch
.startswith(archARMv7
) :
698 self
.target_arch
= arch
699 print "Target arch: " + self
.target_arch
700 self
.register_set
= Armv7_RegisterSet()
701 elif arch
.startswith(archARMv8
):
702 self
.target_arch
= arch
703 print "Target arch: " + self
.target_arch
704 self
.register_set
= Armv8_RegisterSet()
705 # connection intel arm
708 # coredump Memory Server
709 if not self
.connected_over_kdp
:
710 if plugin_string
.find('core') >= 0 and self
.target_arch
== archX86_64
:
711 self
.connected_to_debugserver
= False
712 self
.registers
= self
.register_set
.register_info
713 if self
.connected_to_debugserver
:
714 print "Connected to live debugserver or arm core. Will associate on-core threads to registers reported by server."
716 print "Instantiating threads completely from saved state in memory."
718 def create_thread(self
, tid
, context
):
719 # tid == deadbeef means its a custom thread which kernel does not know of.
720 if tid
== 0xdeadbeef :
721 # tid manipulation should be the same as in "switchtoregs" code in lldbmacros/process.py .
722 tid
= 0xdead0000 |
(context
& ~
0xffff0000)
723 tid
= tid
& 0xdeadffff
724 thread_obj
= { 'tid' : tid
,
726 'name' : 'switchtoregs' + hex(context
),
729 'stop_reason' : 'none'
731 self
.thread_cache
[tid
] = thread_obj
735 th
= self
.version
.CreateValueFromExpression(str(th_ptr
),'(struct thread *)' + str(th_ptr
))
736 thread_id
= th
.GetChildMemberWithName('thread_id').GetValueAsUnsigned()
738 print "FATAL ERROR: Creating thread from memory 0x%x with tid in mem=%d when requested tid = %d " % (context
, thread_id
, tid
)
740 thread_obj
= { 'tid' : thread_id
,
741 'ptr' : th
.GetValueAsUnsigned(),
742 'name' : hex(th
.GetValueAsUnsigned()).rstrip('L'),
743 'queue' : hex(th
.GetChildMemberWithName('wait_queue').GetValueAsUnsigned()).rstrip('L'),
745 'stop_reason' : 'none'
747 if self
.current_session_id
!= GetUniqueSessionID(self
.process
):
748 self
.thread_cache
= {}
749 self
.current_session_id
= GetUniqueSessionID(self
.process
)
751 self
.thread_cache
[tid
] = thread_obj
755 def get_thread_info(self
):
756 self
.kdp_thread
= None
757 self
.kdp_state
= None
758 if self
.connected_over_kdp
:
759 kdp
= self
._target
.FindGlobalVariables('kdp',1).GetValueAtIndex(0)
760 kdp_state
= kdp
.GetChildMemberWithName('saved_state')
761 kdp_thread
= kdp
.GetChildMemberWithName('kdp_thread')
762 if kdp_thread
and kdp_thread
.GetValueAsUnsigned() != 0:
763 self
.kdp_thread
= kdp_thread
764 self
.kdp_state
= kdp_state
765 kdp_thid
= kdp_thread
.GetChildMemberWithName('thread_id').GetValueAsUnsigned()
766 self
.create_thread(kdp_thid
, kdp_thread
.GetValueAsUnsigned())
767 self
.thread_cache
[kdp_thid
]['core']=0
768 retval
= [self
.thread_cache
[kdp_thid
]]
771 print "FATAL FAILURE: Unable to find kdp_thread state for this connection."
774 num_threads
= self
._target
.FindGlobalVariables('threads_count',1).GetValueAtIndex(0).GetValueAsUnsigned()
775 #In case we are caught before threads are initialized. Fallback to threads known by astris/gdb server.
779 self
.current_session_id
= GetUniqueSessionID(self
.process
)
781 self
.thread_cache
= {}
784 processor_list_val
= PluginValue(self
._target
.FindGlobalVariables('processor_list',1).GetValueAtIndex(0))
785 while processor_list_val
.IsValid() and processor_list_val
.GetValueAsUnsigned() !=0 :
786 th
= processor_list_val
.GetChildMemberWithName('active_thread')
787 th_id
= th
.GetChildMemberWithName('thread_id').GetValueAsUnsigned()
788 cpu_id
= processor_list_val
.GetChildMemberWithName('cpu_id').GetValueAsUnsigned()
789 self
.processors
.append({'active_thread': th.GetValueAsUnsigned(), 'cpu_id': cpu_id}
)
790 self
.create_thread(th_id
, th
.GetValueAsUnsigned())
791 if self
.connected_to_debugserver
:
792 self
.thread_cache
[th_id
]['core'] = cpu_id
793 self
.thread_cache
[th_id
]['queue'] = "cpu-%d" % int(cpu_id
)
794 nth
= self
.thread_cache
[th_id
]
795 self
.threads
.append(nth
)
796 self
.thread_cache
[nth
['tid']] = nth
797 processor_list_val
= processor_list_val
.GetChildMemberWithName('processor_list')
798 except KeyboardInterrupt, ke
:
799 print "OS Plugin Interrupted during thread loading process. \nWARNING:Thread registers and backtraces may not be accurate."
802 if hasattr(self
.process
, 'CreateOSPluginThread'):
805 # FIXME remove legacy code
807 thread_q_head
= self
._target
.FindGlobalVariables('threads', 1).GetValueAtIndex(0)
808 thread_type
= self
._target
.FindFirstType('thread')
809 thread_ptr_type
= thread_type
.GetPointerType()
810 for th
in IterateQueue(thread_q_head
, thread_ptr_type
, 'threads'):
811 th_id
= th
.GetChildMemberWithName('thread_id').GetValueAsUnsigned()
812 self
.create_thread(th_id
, th
.GetValueAsUnsigned())
813 nth
= self
.thread_cache
[th_id
]
814 for cputhread
in self
.processors
:
815 if cputhread
['active_thread'] == nth
['ptr']:
816 nth
['core'] = cputhread
['cpu_id']
817 self
.threads
.append( nth
)
818 except KeyboardInterrupt, ke
:
819 print "OS Plugin Interrupted during thread loading process. \nWARNING:Thread registers and backtraces may not be accurate."
824 def get_register_info(self
):
825 if self
.registers
== None:
826 print "Register Information not found "
827 return self
.register_set
.register_info
829 def get_register_data(self
, tid
):
832 regs
= self
.register_set
833 if self
.current_session_id
!= GetUniqueSessionID(self
.process
):
834 self
.thread_cache
= {}
835 self
.current_session_id
= GetUniqueSessionID(self
.process
)
836 if tid
in self
.thread_cache
.keys():
838 #Check if the thread is a fake one. Then create and return registers directly
839 if self
.thread_cache
[tid
]['name'].find('switchtoregs') == 0:
840 savedstateobj
= self
.version
.CreateValueFromExpression(None, '(uintptr_t *) ' + str(self
.thread_cache
[tid
]['ptr']))
841 regs
.ReadRegisterDataFromKDPSavedState(savedstateobj
, self
.version
)
842 return regs
.GetPackedRegisterState()
844 thobj
= self
.version
.CreateValueFromExpression(self
.thread_cache
[tid
]['name'], '(struct thread *)' + str(self
.thread_cache
[tid
]['ptr']))
847 print "FATAL ERROR: Could not find thread with id %d" % tid
848 regs
.ResetRegisterValues()
849 return regs
.GetPackedRegisterState()
851 if self
.kdp_thread
and self
.kdp_thread
.GetValueAsUnsigned() == thobj
.GetValueAsUnsigned():
852 regs
.ReadRegisterDataFromKDPSavedState(self
.kdp_state
, self
.version
)
853 return regs
.GetPackedRegisterState()
854 if int(PluginValue(thobj
).GetChildMemberWithName('kernel_stack').GetValueAsUnsigned()) != 0 :
855 if self
.target_arch
== archX86_64
:
856 # we do have a stack so lets get register information
857 saved_state_addr
= PluginValue(thobj
).GetChildMemberWithName('kernel_stack').GetValueAsUnsigned() + self
.kernel_stack_size
- self
.kernel_thread_state_size
858 regs
.ReadRegisterDataFromKernelStack(saved_state_addr
, self
.version
)
859 return regs
.GetPackedRegisterState()
860 elif self
.target_arch
.startswith(archARMv7
) and int(PluginValue(thobj
).GetChildMemberWithName('machine').GetChildMemberWithName('kstackptr').GetValueAsUnsigned()) != 0:
861 #we have stack on the machine.kstackptr.
862 saved_state_addr
= PluginValue(thobj
).GetChildMemberWithName('machine').GetChildMemberWithName('kstackptr').GetValueAsUnsigned()
863 regs
.ReadRegisterDataFromKernelStack(saved_state_addr
, self
.version
)
864 return regs
.GetPackedRegisterState()
865 elif self
.target_arch
.startswith(archARMv8
) and int(PluginValue(thobj
).GetChildMemberWithName('machine').GetChildMemberWithName('kstackptr').GetValueAsUnsigned()) != 0:
866 saved_state_addr
= PluginValue(thobj
).GetChildMemberWithName('machine').GetChildMemberWithName('kstackptr').GetValueAsUnsigned()
867 arm_ctx
= PluginValue(self
.version
.CreateValueFromExpression(None, '(struct arm_kernel_context *) ' + str(saved_state_addr
)))
868 arm_ss_addr
= arm_ctx
.GetChildMemberWithName('ss').GetLoadAddress()
869 regs
.ReadRegisterDataFromKernelStack(arm_ss_addr
, self
.version
)
870 return regs
.GetPackedRegisterState()
871 elif self
.target_arch
== archX86_64
or self
.target_arch
.startswith(archARMv7
) or self
.target_arch
.startswith(archARMv8
):
872 regs
.ReadRegisterDataFromContinuation( PluginValue(thobj
).GetChildMemberWithName('continuation').GetValueAsAddress())
873 return regs
.GetPackedRegisterState()
874 #incase we failed very miserably
875 except KeyboardInterrupt, ke
:
876 print "OS Plugin Interrupted during thread register load. \nWARNING:Thread registers and backtraces may not be accurate. for tid = %d" % tid
877 regs
.ResetRegisterValues()
878 print "FATAL ERROR: Failed to get register state for thread id 0x%x " % tid
880 return regs
.GetPackedRegisterState()