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, '(struct arm_saved_state64 *) '+ str(kstack_saved_state_addr
))
160 saved_state
= saved_state
.Dereference()
161 saved_state
= PluginValue(saved_state
)
162 self
.ResetRegisterValues()
163 self
.x0
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(0).GetValueAsUnsigned()
164 self
.x1
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(1).GetValueAsUnsigned()
165 self
.x2
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(2).GetValueAsUnsigned()
166 self
.x3
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(3).GetValueAsUnsigned()
167 self
.x4
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(4).GetValueAsUnsigned()
168 self
.x5
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(5).GetValueAsUnsigned()
169 self
.x6
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(6).GetValueAsUnsigned()
170 self
.x7
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(7).GetValueAsUnsigned()
171 self
.x8
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(8).GetValueAsUnsigned()
172 self
.x9
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(9).GetValueAsUnsigned()
173 self
.x10
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(10).GetValueAsUnsigned()
174 self
.x11
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(11).GetValueAsUnsigned()
175 self
.x12
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(12).GetValueAsUnsigned()
176 self
.x13
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(13).GetValueAsUnsigned()
177 self
.x14
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(14).GetValueAsUnsigned()
178 self
.x15
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(15).GetValueAsUnsigned()
179 self
.x16
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(16).GetValueAsUnsigned()
180 self
.x17
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(17).GetValueAsUnsigned()
181 self
.x18
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(18).GetValueAsUnsigned()
182 self
.x19
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(19).GetValueAsUnsigned()
183 self
.x20
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(20).GetValueAsUnsigned()
184 self
.x21
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(21).GetValueAsUnsigned()
185 self
.x22
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(22).GetValueAsUnsigned()
186 self
.x23
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(23).GetValueAsUnsigned()
187 self
.x24
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(24).GetValueAsUnsigned()
188 self
.x25
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(25).GetValueAsUnsigned()
189 self
.x26
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(26).GetValueAsUnsigned()
190 self
.x27
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(27).GetValueAsUnsigned()
191 self
.x28
= saved_state
.GetChildMemberWithName('x').GetChildAtIndex(28).GetValueAsUnsigned()
192 self
.fp
= saved_state
.GetChildMemberWithName('fp').GetValueAsUnsigned()
193 self
.lr
= saved_state
.GetChildMemberWithName('lr').GetValueAsUnsigned()
194 self
.sp
= saved_state
.GetChildMemberWithName('sp').GetValueAsUnsigned()
195 # pc for a blocked thread is treated to be the next instruction it would run after thread switch.
196 self
.pc
= self
.switch_context_address
197 self
.far
= saved_state
.GetChildMemberWithName('far').GetValueAsUnsigned()
198 self
.cpsr
= saved_state
.GetChildMemberWithName('cpsr').GetValueAsUnsigned()
199 self
.esr
= saved_state
.GetChildMemberWithName('esr').GetValueAsUnsigned()
202 def ReadRegisterDataFromContinuation(self
, continuation_ptr
):
203 self
.ResetRegisterValues()
204 self
.pc
= continuation_ptr
208 def GetRegisterInfo(cls
, regnum
):
209 if regnum
< 0 or regnum
> len(cls
.register_info
['registers']):
212 reginfo
= cls
.register_info
['registers'][regnum
]
214 for i
in reginfo
.keys():
215 v_str
= str(reginfo
[i
])
217 v_str
= 'General Purpose Registers'
218 retval
+= "%s:%s;" % (str(i
), v_str
)
223 class Armv7_RegisterSet(object):
224 """ register info set for armv7 32 bit architecture """
225 register_info
= { 'sets' : ['GPR'],
227 { 'name':'r0' , 'bitsize' : 32, 'offset' : 0, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 0, 'dwarf' : 0}
,
228 { 'name':'r1' , 'bitsize' : 32, 'offset' : 4, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 1, 'dwarf' : 1}
,
229 { 'name':'r2' , 'bitsize' : 32, 'offset' : 8, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 2, 'dwarf' : 2}
,
230 { 'name':'r3' , 'bitsize' : 32, 'offset' : 12, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 3, 'dwarf' : 3}
,
231 { 'name':'r4' , 'bitsize' : 32, 'offset' : 16, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 4, 'dwarf' : 4}
,
232 { 'name':'r5' , 'bitsize' : 32, 'offset' : 20, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 5, 'dwarf' : 5}
,
233 { 'name':'r6' , 'bitsize' : 32, 'offset' : 24, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 6, 'dwarf' : 6}
,
234 { 'name':'r7' , 'bitsize' : 32, 'offset' : 28, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 7, 'dwarf' : 7}
,
235 { 'name':'r8' , 'bitsize' : 32, 'offset' : 32, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 8, 'dwarf' : 8}
,
236 { 'name':'r9' , 'bitsize' : 32, 'offset' : 36, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 9, 'dwarf' : 9}
,
237 { 'name':'r10' , 'bitsize' : 32, 'offset' : 40, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':10, 'dwarf' :10}
,
238 { 'name':'r11' , 'bitsize' : 32, 'offset' : 44, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':11, 'dwarf' :11, 'alt-name': 'fp', 'generic': 'fp'}
,
239 { 'name':'r12' , 'bitsize' : 32, 'offset' : 48, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':12, 'dwarf' :12}
,
240 { 'name':'sp' , 'bitsize' : 32, 'offset' : 52, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':13, 'dwarf' :13, 'generic': 'sp'}
,
241 { 'name':'lr' , 'bitsize' : 32, 'offset' : 56, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':14, 'dwarf' :14, 'generic': 'lr'}
,
242 { 'name':'pc' , 'bitsize' : 32, 'offset' : 60, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':15, 'dwarf' :15, 'generic': 'pc'}
,
243 { 'name':'cpsr' , 'bitsize' : 32, 'offset' : 64, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':16, 'dwarf' :16, 'generic':'flags'}
,
244 { 'name':'fsr' , 'bitsize' : 32, 'offset' : 68, 'encoding':'uint', 'format':'hex', 'set':0}
,
245 { 'name':'far' , 'bitsize' : 32, 'offset' : 72, 'encoding':'uint', 'format':'hex', 'set':0}
250 self
.switch_context_address
= osplugin_target_obj
.FindSymbols('load_reg')[0].GetSymbol().GetStartAddress().GetLoadAddress(osplugin_target_obj
) + 8
251 self
.ResetRegisterValues()
254 def GetRegisterInfo(cls
, regnum
):
255 if regnum
< 0 or regnum
> len(cls
.register_info
['registers']):
258 reginfo
= cls
.register_info
['registers'][regnum
]
260 for i
in reginfo
.keys():
261 v_str
= str(reginfo
[i
])
263 v_str
= 'General Purpose Registers'
264 retval
+= "%s:%s;" % (str(i
), v_str
)
267 def ResetRegisterValues(self
):
300 r10 = {o.r10: <#010x}
301 r11 = {o.r11: <#010x}
302 r12 = {o.r12: <#010x}
306 cpsr = {o.cpsr: <#010x}
307 fsr = {o.fsr : <#010x}
308 far = {o.far : <#010x}
311 def GetPackedRegisterState(self
):
312 return struct
.pack('19I', self
.r0
, self
.r1
, self
.r2
, self
.r3
,
313 self
.r4
, self
.r5
, self
.r6
, self
.r7
,
314 self
.r8
, self
.r9
, self
.r10
, self
.r11
,
315 self
.r12
, self
.sp
, self
.lr
, self
.pc
,
316 self
.cpsr
, self
.fsr
, self
.far
)
318 def ReadRegisterDataFromKDPSavedState(self
, kdp_state
, kernel_version
):
319 saved_state
= kernel_version
.CreateValueFromExpression(None, '(struct arm_saved_state *) ' + str(kdp_state
.GetValueAsUnsigned()))
320 saved_state
= saved_state
.Dereference()
321 saved_state
= PluginValue(saved_state
)
322 self
.ResetRegisterValues()
323 self
.r0
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(0).GetValueAsUnsigned()
324 self
.r1
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(1).GetValueAsUnsigned()
325 self
.r2
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(2).GetValueAsUnsigned()
326 self
.r3
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(3).GetValueAsUnsigned()
327 self
.r4
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(4).GetValueAsUnsigned()
328 self
.r5
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(5).GetValueAsUnsigned()
329 self
.r6
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(6).GetValueAsUnsigned()
330 self
.r7
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(7).GetValueAsUnsigned()
331 self
.r8
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(8).GetValueAsUnsigned()
332 self
.r9
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(9).GetValueAsUnsigned()
333 self
.r10
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(10).GetValueAsUnsigned()
334 self
.r11
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(11).GetValueAsUnsigned()
335 self
.r12
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(12).GetValueAsUnsigned()
336 self
.sp
= saved_state
.GetChildMemberWithName('sp').GetValueAsUnsigned()
337 self
.lr
= saved_state
.GetChildMemberWithName('lr').GetValueAsUnsigned()
338 self
.pc
= saved_state
.GetChildMemberWithName('pc').GetValueAsUnsigned()
339 self
.cpsr
= saved_state
.GetChildMemberWithName('cpsr').GetValueAsUnsigned()
340 self
.fsr
= saved_state
.GetChildMemberWithName('fsr').GetValueAsUnsigned()
341 self
.far
= saved_state
.GetChildMemberWithName('far').GetValueAsUnsigned()
344 def ReadRegisterDataFromKernelStack(self
, kstack_saved_state_addr
, kernel_version
):
345 saved_state
= kernel_version
.CreateValueFromExpression(None, '(struct arm_saved_state *) '+ str(kstack_saved_state_addr
))
346 saved_state
= saved_state
.Dereference()
347 saved_state
= PluginValue(saved_state
)
348 self
.ResetRegisterValues()
349 self
.r0
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(0).GetValueAsUnsigned()
350 self
.r1
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(1).GetValueAsUnsigned()
351 self
.r2
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(2).GetValueAsUnsigned()
352 self
.r3
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(3).GetValueAsUnsigned()
353 self
.r4
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(4).GetValueAsUnsigned()
354 self
.r5
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(5).GetValueAsUnsigned()
355 self
.r6
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(6).GetValueAsUnsigned()
356 self
.r7
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(7).GetValueAsUnsigned()
357 self
.r8
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(8).GetValueAsUnsigned()
358 self
.r9
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(9).GetValueAsUnsigned()
359 self
.r10
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(10).GetValueAsUnsigned()
360 self
.r11
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(11).GetValueAsUnsigned()
361 self
.r12
= saved_state
.GetChildMemberWithName('r').GetChildAtIndex(12).GetValueAsUnsigned()
362 self
.sp
= saved_state
.GetChildMemberWithName('sp').GetValueAsUnsigned()
363 self
.lr
= saved_state
.GetChildMemberWithName('lr').GetValueAsUnsigned()
364 # pc for a blocked thread is treated to be the next instruction it would run after thread switch.
365 self
.pc
= self
.switch_context_address
366 self
.cpsr
= saved_state
.GetChildMemberWithName('cpsr').GetValueAsUnsigned()
367 self
.fsr
= saved_state
.GetChildMemberWithName('fsr').GetValueAsUnsigned()
368 self
.far
= saved_state
.GetChildMemberWithName('far').GetValueAsUnsigned()
371 def ReadRegisterDataFromContinuation(self
, continuation_ptr
):
372 self
.ResetRegisterValues()
373 self
.pc
= continuation_ptr
377 class I386_RegisterSet(object):
378 """ register info set for i386 architecture
380 register_info
= { 'sets' : ['GPR'],
382 { 'name': 'eax' , 'bitsize': 32, 'offset' : 0, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 0, 'dwarf': 0}
,
383 { 'name': 'ebx' , 'bitsize': 32, 'offset' : 4, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 3, 'dwarf': 3}
,
384 { 'name': 'ecx' , 'bitsize': 32, 'offset' : 8, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 1, 'dwarf': 1}
,
385 { 'name': 'edx' , 'bitsize': 32, 'offset' :12, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 2, 'dwarf': 2}
,
386 { 'name': 'edi' , 'bitsize': 32, 'offset' :16, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 7, 'dwarf': 7}
,
387 { 'name': 'esi' , 'bitsize': 32, 'offset' :20, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 6, 'dwarf': 6}
,
388 { 'name': 'ebp' , 'bitsize': 32, 'offset' :24, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 4, 'dwarf': 5, 'generic': 'fp', 'alt-name': 'fp'}
,
389 { 'name': 'esp' , 'bitsize': 32, 'offset' :28, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 5, 'dwarf': 4, 'generic': 'sp', 'alt-name': 'sp'}
,
390 { 'name': 'ss' , 'bitsize': 32, 'offset' :32, 'encoding': 'uint' , 'format':'hex' , 'set': 0}
,
391 { 'name': 'eflags', 'bitsize': 32, 'offset' :36, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 9, 'dwarf': 9, 'generic': 'flags'}
,
392 { 'name': 'eip' , 'bitsize': 32, 'offset' :40, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' :8, 'dwarf':8, 'generic': 'pc', 'alt-name': 'pc'}
,
393 { 'name': 'cs' , 'bitsize': 32, 'offset' :44, 'encoding': 'uint' , 'format':'hex' , 'set': 0}
,
394 { 'name': 'ds' , 'bitsize': 32, 'offset' :48, 'encoding': 'uint' , 'format':'hex' , 'set': 0}
,
395 { 'name': 'es' , 'bitsize': 32, 'offset' :52, 'encoding': 'uint' , 'format':'hex' , 'set': 0}
,
396 { 'name': 'fs' , 'bitsize': 32, 'offset' :56, 'encoding': 'uint' , 'format':'hex' , 'set': 0}
,
397 { 'name': 'gs' , 'bitsize': 32, 'offset' :60, 'encoding': 'uint' , 'format':'hex' , 'set': 0}
,
402 self
.ResetRegisterValues()
405 def GetRegisterInfo(cls
, regnum
):
406 if regnum
< 0 or regnum
> len(cls
.register_info
['registers']):
409 reginfo
= cls
.register_info
['registers'][regnum
]
411 for i
in reginfo
.keys():
412 v_str
= str(reginfo
[i
])
414 v_str
= 'General Purpose Registers'
415 retval
+= "%s:%s;" % (str(i
), v_str
)
418 def ResetRegisterValues(self
):
419 """ set all registers to zero """
448 eflags = {o.eflags: #010x}
457 def GetPackedRegisterState(self
):
458 """ get a struct.pack register data """
459 return struct
.pack('16I', self
.eax
, self
.ebx
, self
.ecx
,
460 self
.edx
, self
.edi
, self
.esi
,
461 self
.ebp
, self
.esp
, self
.ss
,
462 self
.eflags
, self
.eip
, self
.cs
,
463 self
.ds
, self
.es
, self
.fs
, self
.gs
466 def ReadRegisterDataFromKDPSavedState(self
, kdp_state
, kernel_version
):
467 """ to be implemented"""
470 def ReadRegisterDataFromKernelStack(self
, kstack_saved_state_addr
, kernel_version
):
471 """ to be implemented """
474 def ReadRegisterDataFromContinuation(self
, continuation_ptr
):
475 self
.ResetRegisterValues()
476 self
.eip
= continuation_ptr
480 class X86_64RegisterSet(object):
481 """ register info set for x86_64 architecture """
482 register_info
= { 'sets' : ['GPR'],
484 { 'name':'rax' , 'bitsize' : 64, 'offset' : 0, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 0, 'dwarf' : 0}
,
485 { 'name':'rbx' , 'bitsize' : 64, 'offset' : 8, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 3, 'dwarf' : 3}
,
486 { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 2, 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', }
,
487 { 'name':'rdx' , 'bitsize' : 64, 'offset' : 24, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 1, 'dwarf' : 1, 'generic':'arg3', 'alt-name':'arg3', }
,
488 { 'name':'rdi' , 'bitsize' : 64, 'offset' : 32, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 5, 'dwarf' : 5, 'generic':'arg1', 'alt-name':'arg1', }
,
489 { 'name':'rsi' , 'bitsize' : 64, 'offset' : 40, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 4, 'dwarf' : 4, 'generic':'arg2', 'alt-name':'arg2', }
,
490 { 'name':'rbp' , 'bitsize' : 64, 'offset' : 48, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 6, 'dwarf' : 6, 'generic':'fp' , 'alt-name':'fp', }
,
491 { 'name':'rsp' , 'bitsize' : 64, 'offset' : 56, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 7, 'dwarf' : 7, 'generic':'sp' , 'alt-name':'sp', }
,
492 { 'name':'r8' , 'bitsize' : 64, 'offset' : 64, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 8, 'dwarf' : 8, 'generic':'arg5', 'alt-name':'arg5', }
,
493 { 'name':'r9' , 'bitsize' : 64, 'offset' : 72, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 9, 'dwarf' : 9, 'generic':'arg6', 'alt-name':'arg6', }
,
494 { 'name':'r10' , 'bitsize' : 64, 'offset' : 80, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 10, 'dwarf' : 10}
,
495 { 'name':'r11' , 'bitsize' : 64, 'offset' : 88, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 11, 'dwarf' : 11}
,
496 { 'name':'r12' , 'bitsize' : 64, 'offset' : 96, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 12, 'dwarf' : 12}
,
497 { 'name':'r13' , 'bitsize' : 64, 'offset' : 104, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 13, 'dwarf' : 13}
,
498 { 'name':'r14' , 'bitsize' : 64, 'offset' : 112, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 14, 'dwarf' : 14}
,
499 { 'name':'r15' , 'bitsize' : 64, 'offset' : 120, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 15, 'dwarf' : 15}
,
500 { 'name':'rip' , 'bitsize' : 64, 'offset' : 128, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 16, 'dwarf' : 16, 'generic':'pc', 'alt-name':'pc' }
,
501 { 'name':'rflags' , 'bitsize' : 64, 'offset' : 136, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'generic':'flags', 'alt-name':'flags' }
,
502 { 'name':'cs' , 'bitsize' : 64, 'offset' : 144, 'encoding':'uint' , 'format':'hex' , 'set': 0 }
,
503 { 'name':'fs' , 'bitsize' : 64, 'offset' : 152, 'encoding':'uint' , 'format':'hex' , 'set': 0 }
,
504 { 'name':'gs' , 'bitsize' : 64, 'offset' : 160, 'encoding':'uint' , 'format':'hex' , 'set': 0 }
,
508 self
.ResetRegisterValues()
511 def GetRegisterInfo(cls
, regnum
):
512 if regnum
< 0 or regnum
> len(cls
.register_info
['registers']):
515 reginfo
= cls
.register_info
['registers'][regnum
]
517 for i
in reginfo
.keys():
518 v_str
= str(reginfo
[i
])
520 v_str
= 'General Purpose Registers'
521 retval
+= "%s:%s;" % (str(i
), v_str
)
525 def ResetRegisterValues(self
):
526 """ set all the registers to zero. """
551 rax = {o.rax: <#018x}
552 rbx = {o.rbx: <#018x}
553 rcx = {o.rcx: <#018x}
554 rdx = {o.rdx: <#018x}
555 rdi = {o.rdi: <#018x}
556 rsi = {o.rsi: <#018x}
557 rbp = {o.rbp: <#018x}
558 rsp = {o.rsp: <#018x}
561 r10 = {o.r10: <#018x}
562 r11 = {o.r11: <#018x}
563 r12 = {o.r12: <#018x}
564 r13 = {o.r13: <#018x}
565 r14 = {o.r14: <#018x}
566 r15 = {o.r15: <#018x}
567 rip = {o.rip: <#018x}
568 rflags = {o.rflags: <#018x}
574 def GetPackedRegisterState(self
):
575 """ get a struct.pack register data for passing to C constructs """
576 return struct
.pack('21Q', self
.rax
, self
.rbx
, self
.rcx
, self
.rdx
, self
.rdi
,
577 self
.rsi
, self
.rbp
, self
.rsp
, self
.r8
, self
.r9
,
578 self
.r10
, self
.r11
, self
.r12
, self
.r13
, self
.r14
,
579 self
.r15
, self
.rip
, self
.rflags
, self
.cs
, self
.fs
, self
.gs
)
581 def ReadRegisterDataFromKDPSavedState(self
, kdp_state
, kernel_version
):
582 saved_state
= kernel_version
.CreateValueFromExpression(None, '(struct x86_saved_state64 *) '+ str(kdp_state
.GetValueAsUnsigned()))
583 saved_state
= saved_state
.Dereference()
584 saved_state
= PluginValue(saved_state
)
585 self
.ResetRegisterValues()
586 self
.rdi
= saved_state
.GetChildMemberWithName('rdi').GetValueAsUnsigned()
587 self
.rsi
= saved_state
.GetChildMemberWithName('rsi').GetValueAsUnsigned()
588 self
.rdx
= saved_state
.GetChildMemberWithName('rdx').GetValueAsUnsigned()
589 self
.r10
= saved_state
.GetChildMemberWithName('r10').GetValueAsUnsigned()
590 self
.r8
= saved_state
.GetChildMemberWithName('r8').GetValueAsUnsigned()
591 self
.r9
= saved_state
.GetChildMemberWithName('r9').GetValueAsUnsigned()
592 self
.r15
= saved_state
.GetChildMemberWithName('r15').GetValueAsUnsigned()
593 self
.r14
= saved_state
.GetChildMemberWithName('r14').GetValueAsUnsigned()
594 self
.r13
= saved_state
.GetChildMemberWithName('r13').GetValueAsUnsigned()
595 self
.r12
= saved_state
.GetChildMemberWithName('r12').GetValueAsUnsigned()
596 self
.r11
= saved_state
.GetChildMemberWithName('r11').GetValueAsUnsigned()
597 self
.rbp
= saved_state
.GetChildMemberWithName('rbp').GetValueAsUnsigned()
598 self
.rbx
= saved_state
.GetChildMemberWithName('rbx').GetValueAsUnsigned()
599 self
.rcx
= saved_state
.GetChildMemberWithName('rcx').GetValueAsUnsigned()
600 self
.rax
= saved_state
.GetChildMemberWithName('rax').GetValueAsUnsigned()
601 self
.rip
= saved_state
.GetChildMemberWithName('isf').GetChildMemberWithName('rip').GetValueAsUnsigned()
602 self
.rflags
= saved_state
.GetChildMemberWithName('isf').GetChildMemberWithName('rflags').GetValueAsUnsigned()
603 self
.rsp
= saved_state
.GetChildMemberWithName('isf').GetChildMemberWithName('rsp').GetValueAsUnsigned()
606 def ReadRegisterDataFromKernelStack(self
, kstack_saved_state_addr
, kernel_version
):
607 saved_state
= kernel_version
.CreateValueFromExpression(None, '(struct x86_kernel_state *) '+ str(kstack_saved_state_addr
))
608 saved_state
= saved_state
.Dereference()
609 saved_state
= PluginValue(saved_state
)
610 self
.ResetRegisterValues()
611 self
.rbx
= saved_state
.GetChildMemberWithName('k_rbx').GetValueAsUnsigned()
612 self
.rsp
= saved_state
.GetChildMemberWithName('k_rsp').GetValueAsUnsigned()
613 self
.rbp
= saved_state
.GetChildMemberWithName('k_rbp').GetValueAsUnsigned()
614 self
.r12
= saved_state
.GetChildMemberWithName('k_r12').GetValueAsUnsigned()
615 self
.r13
= saved_state
.GetChildMemberWithName('k_r13').GetValueAsUnsigned()
616 self
.r14
= saved_state
.GetChildMemberWithName('k_r14').GetValueAsUnsigned()
617 self
.r15
= saved_state
.GetChildMemberWithName('k_r15').GetValueAsUnsigned()
618 self
.rip
= saved_state
.GetChildMemberWithName('k_rip').GetValueAsUnsigned()
621 def ReadRegisterDataFromContinuation(self
, continuation_ptr
):
622 self
.ResetRegisterValues()
623 self
.rip
= continuation_ptr
629 def IterateQueue(queue_head
, element_ptr_type
, element_field_name
):
630 """ iterate over a queue in kernel of type queue_head_t. refer to osfmk/kern/queue.h
632 queue_head - lldb.SBValue : Value object for queue_head.
633 element_type - lldb.SBType : a pointer type of the element 'next' points to. Typically its structs like thread, task etc..
634 element_field_name - str : name of the field in target struct.
636 A generator does not return. It is used for iterating.
637 SBValue : an object thats of type (element_type) queue_head->next. Always a pointer object
639 queue_head_addr
= 0x0
640 if queue_head
.TypeIsPointerType():
641 queue_head_addr
= queue_head
.GetValueAsUnsigned()
643 queue_head_addr
= queue_head
.GetAddress().GetLoadAddress(osplugin_target_obj
)
644 cur_elt
= queue_head
.GetChildMemberWithName('next')
646 if not cur_elt
.IsValid() or cur_elt
.GetValueAsUnsigned() == 0 or cur_elt
.GetValueAsUnsigned() == queue_head_addr
:
648 elt
= cur_elt
.Cast(element_ptr_type
)
650 cur_elt
= elt
.GetChildMemberWithName(element_field_name
).GetChildMemberWithName('next')
652 def GetUniqueSessionID(process_obj
):
653 """ Create a unique session identifier.
655 process_obj: lldb.SBProcess object refering to connected process.
657 int - a unique number identified by processid and stopid.
660 if hasattr(process_obj
, "GetUniqueID"):
661 session_key_str
+= str(process_obj
.GetUniqueID()) + ":"
663 session_key_str
+= "0:"
665 if hasattr(process_obj
, "GetStopID"):
666 session_key_str
+= str(process_obj
.GetStopID())
668 session_key_str
+="1"
670 return hash(session_key_str
)
673 (archX86_64
, archARMv7_family
, archI386
, archARMv8
) = ("x86_64", ("armv7", "armv7s", "armv7k") , "i386", "arm64")
675 class OperatingSystemPlugIn(object):
676 """Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class"""
678 def __init__(self
, process
):
679 '''Initialization needs a valid.SBProcess object'''
681 self
.registers
= None
683 self
.thread_cache
= {}
684 self
.current_session_id
= 0
685 self
.kdp_thread
= None
686 if type(process
) is lldb
.SBProcess
and process
.IsValid():
687 global osplugin_target_obj
688 self
.process
= process
689 self
._target
= process
.target
690 osplugin_target_obj
= self
._target
691 self
.current_session_id
= GetUniqueSessionID(self
.process
)
692 self
.version
= self
._target
.FindGlobalVariables('version', 1).GetValueAtIndex(0)
693 self
.kernel_stack_size
= self
._target
.FindGlobalVariables('kernel_stack_size', 1).GetValueAtIndex(0).GetValueAsUnsigned()
694 self
.kernel_context_size
= 0
695 self
.connected_over_kdp
= False
696 # connected_to_debugserver signifies if we are connected to astris or other gdbserver instance
697 # that has the correct thread state for on core threads. For kdp and coredumps we rely on in memory
699 self
.connected_to_debugserver
= True
700 plugin_string
= self
.process
.GetPluginName().lower()
701 if plugin_string
.find("kdp") >=0:
702 self
.connected_over_kdp
= True
703 self
.connected_to_debugserver
= False
704 #print "version", self.version, "kernel_stack_size", self.kernel_stack_size, "context_size", self.kernel_context_size
705 self
.threads
= None # Will be an dictionary containing info for each thread
706 triple
= self
.process
.target
.triple
707 arch
= triple
.split('-')[0].lower()
708 self
.target_arch
= ""
709 self
.kernel_context_size
= 0
710 if arch
== archX86_64
:
711 self
.target_arch
= archX86_64
712 print "Target arch: x86_64"
713 self
.register_set
= X86_64RegisterSet()
714 self
.kernel_context_size
= self
._target
.FindFirstType('x86_kernel_state').GetByteSize()
715 elif arch
in archARMv7_family
:
716 self
.target_arch
= arch
717 print "Target arch: " + self
.target_arch
718 self
.register_set
= Armv7_RegisterSet()
719 elif arch
== archARMv8
:
720 self
.target_arch
= arch
721 print "Target arch: " + self
.target_arch
722 self
.register_set
= Armv8_RegisterSet()
723 # connection intel arm
726 # coredump Memory Server
727 if not self
.connected_over_kdp
:
728 if plugin_string
.find('core') >= 0 and self
.target_arch
== archX86_64
:
729 self
.connected_to_debugserver
= False
730 self
.registers
= self
.register_set
.register_info
731 if self
.connected_to_debugserver
:
732 print "Connected to live debugserver or arm core. Will associate on-core threads to registers reported by server."
734 print "Instantiating threads completely from saved state in memory."
736 def create_thread(self
, tid
, context
):
737 # if tid is deadbeef means its a custom thread which kernel does not know of.
738 if tid
== 0xdeadbeef :
739 # tid manipulation should be the same as in "switchtoregs" code in lldbmacros/process.py .
740 tid
= 0xdead0000 |
(context
& ~
0xffff0000)
741 tid
= tid
& 0xdeadffff
742 thread_obj
= { 'tid' : tid
,
744 'name' : 'switchtoregs' + hex(context
),
747 'stop_reason' : 'none'
749 self
.thread_cache
[tid
] = thread_obj
753 th
= self
.version
.CreateValueFromExpression(str(th_ptr
),'(struct thread *)' + str(th_ptr
))
754 thread_id
= th
.GetChildMemberWithName('thread_id').GetValueAsUnsigned()
756 print "FATAL ERROR: Creating thread from memory 0x%x with tid in mem=%d when requested tid = %d " % (context
, thread_id
, tid
)
758 thread_obj
= { 'tid' : thread_id
,
759 'ptr' : th
.GetValueAsUnsigned(),
760 'name' : hex(th
.GetValueAsUnsigned()).rstrip('L'),
761 'queue' : hex(th
.GetChildMemberWithName('wait_queue').GetValueAsUnsigned()).rstrip('L'),
763 'stop_reason' : 'none'
765 if self
.current_session_id
!= GetUniqueSessionID(self
.process
):
766 self
.thread_cache
= {}
767 self
.current_session_id
= GetUniqueSessionID(self
.process
)
769 self
.thread_cache
[tid
] = thread_obj
773 def get_thread_info(self
):
774 self
.kdp_thread
= None
775 self
.kdp_state
= None
776 if self
.connected_over_kdp
:
777 kdp
= self
._target
.FindGlobalVariables('kdp',1).GetValueAtIndex(0)
778 kdp_state
= kdp
.GetChildMemberWithName('saved_state')
779 kdp_thread
= kdp
.GetChildMemberWithName('kdp_thread')
780 if kdp_thread
and kdp_thread
.GetValueAsUnsigned() != 0:
781 self
.kdp_thread
= kdp_thread
782 self
.kdp_state
= kdp_state
783 kdp_thid
= kdp_thread
.GetChildMemberWithName('thread_id').GetValueAsUnsigned()
784 self
.create_thread(kdp_thid
, kdp_thread
.GetValueAsUnsigned())
785 self
.thread_cache
[kdp_thid
]['core']=0
786 retval
= [self
.thread_cache
[kdp_thid
]]
789 print "FATAL FAILURE: Unable to find kdp_thread state for this connection."
792 num_threads
= self
._target
.FindGlobalVariables('threads_count',1).GetValueAtIndex(0).GetValueAsUnsigned()
793 #In case we are caught before threads are initialized. Fallback to threads known by astris/gdb server.
797 self
.current_session_id
= GetUniqueSessionID(self
.process
)
799 self
.thread_cache
= {}
802 processor_list_val
= PluginValue(self
._target
.FindGlobalVariables('processor_list',1).GetValueAtIndex(0))
803 while processor_list_val
.IsValid() and processor_list_val
.GetValueAsUnsigned() !=0 :
804 th
= processor_list_val
.GetChildMemberWithName('active_thread')
805 th_id
= th
.GetChildMemberWithName('thread_id').GetValueAsUnsigned()
806 cpu_id
= processor_list_val
.GetChildMemberWithName('cpu_id').GetValueAsUnsigned()
807 self
.processors
.append({'active_thread': th.GetValueAsUnsigned(), 'cpu_id': cpu_id}
)
808 self
.create_thread(th_id
, th
.GetValueAsUnsigned())
809 if self
.connected_to_debugserver
:
810 self
.thread_cache
[th_id
]['core'] = cpu_id
811 self
.thread_cache
[th_id
]['queue'] = "cpu-%d" % int(cpu_id
)
812 nth
= self
.thread_cache
[th_id
]
813 self
.threads
.append(nth
)
814 self
.thread_cache
[nth
['tid']] = nth
815 processor_list_val
= processor_list_val
.GetChildMemberWithName('processor_list')
816 except KeyboardInterrupt, ke
:
817 print "OS Plugin Interrupted during thread loading process. \nWARNING:Thread registers and backtraces may not be accurate."
820 if hasattr(self
.process
, 'CreateOSPluginThread'):
823 # FIXME remove legacy code
825 thread_q_head
= self
._target
.FindGlobalVariables('threads', 1).GetValueAtIndex(0)
826 thread_type
= self
._target
.FindFirstType('thread')
827 thread_ptr_type
= thread_type
.GetPointerType()
828 for th
in IterateQueue(thread_q_head
, thread_ptr_type
, 'threads'):
829 th_id
= th
.GetChildMemberWithName('thread_id').GetValueAsUnsigned()
830 self
.create_thread(th_id
, th
.GetValueAsUnsigned())
831 nth
= self
.thread_cache
[th_id
]
832 for cputhread
in self
.processors
:
833 if cputhread
['active_thread'] == nth
['ptr']:
834 nth
['core'] = cputhread
['cpu_id']
835 self
.threads
.append( nth
)
836 except KeyboardInterrupt, ke
:
837 print "OS Plugin Interrupted during thread loading process. \nWARNING:Thread registers and backtraces may not be accurate."
842 def get_register_info(self
):
843 if self
.registers
== None:
844 print "Register Information not found "
845 return self
.register_set
.register_info
847 def get_register_data(self
, tid
):
850 regs
= self
.register_set
851 if self
.current_session_id
!= GetUniqueSessionID(self
.process
):
852 self
.thread_cache
= {}
853 self
.current_session_id
= GetUniqueSessionID(self
.process
)
854 if tid
in self
.thread_cache
.keys():
856 #Check if the thread is a fake one. Then create and return registers directly
857 if self
.thread_cache
[tid
]['name'].find('switchtoregs') == 0:
858 savedstateobj
= self
.version
.CreateValueFromExpression(None, '(uintptr_t *) ' + str(self
.thread_cache
[tid
]['ptr']))
859 regs
.ReadRegisterDataFromKDPSavedState(savedstateobj
, self
.version
)
860 return regs
.GetPackedRegisterState()
862 thobj
= self
.version
.CreateValueFromExpression(self
.thread_cache
[tid
]['name'], '(struct thread *)' + str(self
.thread_cache
[tid
]['ptr']))
865 print "FATAL ERROR: Could not find thread with id %d" % tid
866 regs
.ResetRegisterValues()
867 return regs
.GetPackedRegisterState()
869 if self
.kdp_thread
and self
.kdp_thread
.GetValueAsUnsigned() == thobj
.GetValueAsUnsigned():
870 regs
.ReadRegisterDataFromKDPSavedState(self
.kdp_state
, self
.version
)
871 return regs
.GetPackedRegisterState()
872 if int(PluginValue(thobj
).GetChildMemberWithName('kernel_stack').GetValueAsUnsigned()) != 0 :
873 if self
.target_arch
== archX86_64
:
874 # we do have a stack so lets get register information
875 saved_state_addr
= PluginValue(thobj
).GetChildMemberWithName('kernel_stack').GetValueAsUnsigned() + self
.kernel_stack_size
- self
.kernel_context_size
876 regs
.ReadRegisterDataFromKernelStack(saved_state_addr
, self
.version
)
877 return regs
.GetPackedRegisterState()
878 elif self
.target_arch
in archARMv7_family
and int(PluginValue(thobj
).GetChildMemberWithName('machine').GetChildMemberWithName('kstackptr').GetValueAsUnsigned()) != 0:
879 #we have stack on the machine.kstackptr.
880 saved_state_addr
= PluginValue(thobj
).GetChildMemberWithName('machine').GetChildMemberWithName('kstackptr').GetValueAsUnsigned()
881 regs
.ReadRegisterDataFromKernelStack(saved_state_addr
, self
.version
)
882 return regs
.GetPackedRegisterState()
883 elif self
.target_arch
== archARMv8
and int(PluginValue(thobj
).GetChildMemberWithName('machine').GetChildMemberWithName('kstackptr').GetValueAsUnsigned()) != 0:
884 saved_state_addr
= PluginValue(thobj
).GetChildMemberWithName('machine').GetChildMemberWithName('kstackptr').GetValueAsUnsigned()
885 arm_ctx
= PluginValue(self
.version
.CreateValueFromExpression(None, '(struct arm_context *) ' + str(saved_state_addr
)))
886 ss_64_addr
= arm_ctx
.GetChildMemberWithName('ss').GetChildMemberWithName('uss').GetChildMemberWithName('ss_64').GetLoadAddress()
887 regs
.ReadRegisterDataFromKernelStack(ss_64_addr
, self
.version
)
888 return regs
.GetPackedRegisterState()
889 elif self
.target_arch
== archX86_64
or self
.target_arch
in archARMv7_family
or self
.target_arch
== archARMv8
:
890 regs
.ReadRegisterDataFromContinuation( PluginValue(thobj
).GetChildMemberWithName('continuation').GetValueAsUnsigned())
891 return regs
.GetPackedRegisterState()
892 #incase we failed very miserably
893 except KeyboardInterrupt, ke
:
894 print "OS Plugin Interrupted during thread register load. \nWARNING:Thread registers and backtraces may not be accurate. for tid = %d" % tid
895 regs
.ResetRegisterValues()
896 print "FATAL ERROR: Failed to get register state for thread id 0x%x " % tid
898 return regs
.GetPackedRegisterState()