]> git.saurik.com Git - apple/xnu.git/blame_incremental - tools/lldbmacros/core/operating_system.py
xnu-7195.101.1.tar.gz
[apple/xnu.git] / tools / lldbmacros / core / operating_system.py
... / ...
CommitLineData
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
5import lldb
6import struct
7osplugin_target_obj = None
8
9class 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))
17 return None
18
19class Armv8_RegisterSet(object):
20 """ register info set for armv8 64 bit architecture"""
21 register_info = { 'sets' : ['GPR'],
22 'registers': [
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},
59 ]
60 }
61
62 def __init__(self):
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):
66 self.x0 = 0
67 self.x1 = 0
68 self.x2 = 0
69 self.x3 = 0
70 self.x4 = 0
71 self.x5 = 0
72 self.x6 = 0
73 self.x7 = 0
74 self.x8 = 0
75 self.x9 = 0
76 self.x10 = 0
77 self.x11 = 0
78 self.x12 = 0
79 self.x13 = 0
80 self.x14 = 0
81 self.x15 = 0
82 self.x16 = 0
83 self.x17 = 0
84 self.x18 = 0
85 self.x19 = 0
86 self.x20 = 0
87 self.x21 = 0
88 self.x22 = 0
89 self.x23 = 0
90 self.x24 = 0
91 self.x25 = 0
92 self.x26 = 0
93 self.x27 = 0
94 self.x28 = 0
95 self.fp = 0
96 self.lr = 0
97 self.sp = 0
98 self.pc = 0
99 self.far = 0
100 self.cpsr = 0
101 self.esr = 0
102
103 def __str__(self):
104 return """ pc = """
105
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)
112
113 def ReadRegisterDataFromKDPSavedState(self, kdp_state, kernel_version):
114 """ Setup register values from KDP saved information.
115 """
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()
156 return self
157
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()
181 return self
182
183 def ReadRegisterDataFromContinuation(self, continuation_ptr):
184 self.ResetRegisterValues()
185 self.pc = continuation_ptr
186 return self
187
188 @classmethod
189 def GetRegisterInfo(cls, regnum):
190 if regnum < 0 or regnum > len(cls.register_info['registers']):
191 return ''
192
193 reginfo = cls.register_info['registers'][regnum]
194 retval = ''
195 for i in reginfo.keys():
196 v_str = str(reginfo[i])
197 if i == 'set':
198 v_str = 'General Purpose Registers'
199 retval += "%s:%s;" % (str(i), v_str)
200 return retval
201
202
203
204class Armv7_RegisterSet(object):
205 """ register info set for armv7 32 bit architecture """
206 register_info = { 'sets' : ['GPR'],
207 'registers': [
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}
227 ]
228 }
229
230 def __init__(self):
231 self.switch_context_address = osplugin_target_obj.FindSymbols('load_reg')[0].GetSymbol().GetStartAddress().GetLoadAddress(osplugin_target_obj) + 8
232 self.ResetRegisterValues()
233
234 @classmethod
235 def GetRegisterInfo(cls, regnum):
236 if regnum < 0 or regnum > len(cls.register_info['registers']):
237 return ''
238
239 reginfo = cls.register_info['registers'][regnum]
240 retval = ''
241 for i in reginfo.keys():
242 v_str = str(reginfo[i])
243 if i == 'set':
244 v_str = 'General Purpose Registers'
245 retval += "%s:%s;" % (str(i), v_str)
246 return retval
247
248 def ResetRegisterValues(self):
249 self.r0 = 0
250 self.r1 = 0
251 self.r2 = 0
252 self.r3 = 0
253 self.r4 = 0
254 self.r5 = 0
255 self.r6 = 0
256 self.r7 = 0
257 self.r8 = 0
258 self.r9 = 0
259 self.r10 = 0
260 self.r11 = 0
261 self.r12 = 0
262 self.sp = 0
263 self.lr = 0
264 self.pc = 0
265 self.cpsr = 0
266 self.fsr = 0
267 self.far = 0
268
269 def __str__(self):
270 return """
271 r0 = {o.r0: <#010x}
272 r1 = {o.r1: <#010x}
273 r2 = {o.r2: <#010x}
274 r3 = {o.r3: <#010x}
275 r4 = {o.r4: <#010x}
276 r5 = {o.r5: <#010x}
277 r6 = {o.r6: <#010x}
278 r7 = {o.r7: <#010x}
279 r8 = {o.r8: <#010x}
280 r9 = {o.r9: <#010x}
281 r10 = {o.r10: <#010x}
282 r11 = {o.r11: <#010x}
283 r12 = {o.r12: <#010x}
284 sp = {o.sp: <#010x}
285 lr = {o.lr: <#010x}
286 pc = {o.pc: <#010x}
287 cpsr = {o.cpsr: <#010x}
288 fsr = {o.fsr : <#010x}
289 far = {o.far : <#010x}
290 """.format(o=self)
291
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)
298
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()
323 return self
324
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()
350 return self
351
352 def ReadRegisterDataFromContinuation(self, continuation_ptr):
353 self.ResetRegisterValues()
354 self.pc = continuation_ptr
355 return self
356
357
358class I386_RegisterSet(object):
359 """ register info set for i386 architecture
360 """
361 register_info = { 'sets' : ['GPR'],
362 'registers': [
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},
379 ]
380 }
381
382 def __init__(self):
383 self.ResetRegisterValues()
384
385 @classmethod
386 def GetRegisterInfo(cls, regnum):
387 if regnum < 0 or regnum > len(cls.register_info['registers']):
388 return ''
389
390 reginfo = cls.register_info['registers'][regnum]
391 retval = ''
392 for i in reginfo.keys():
393 v_str = str(reginfo[i])
394 if i == 'set':
395 v_str = 'General Purpose Registers'
396 retval += "%s:%s;" % (str(i), v_str)
397 return retval
398
399 def ResetRegisterValues(self):
400 """ set all registers to zero """
401 self.eax = 0
402 self.ebx = 0
403 self.ecx = 0
404 self.edx = 0
405 self.edi = 0
406 self.esi = 0
407 self.ebp = 0
408 self.esp = 0
409 self.ss = 0
410 self.eflags = 0
411 self.eip = 0
412 self.cs = 0
413 self.ds = 0
414 self.es = 0
415 self.fs = 0
416 self.gs = 0
417
418 def __str__(self):
419 return """
420 eax = {o.eax: #010x}
421 ebx = {o.ebx: #010x}
422 ecx = {o.ecx: #010x}
423 edx = {o.edx: #010x}
424 edi = {o.edi: #010x}
425 esi = {o.esi: #010x}
426 ebp = {o.ebp: #010x}
427 esp = {o.esp: #010x}
428 ss = {o.ss: #010x}
429 eflags = {o.eflags: #010x}
430 eip = {o.eip: #010x}
431 cs = {o.cs: #010x}
432 ds = {o.ds: #010x}
433 es = {o.es: #010x}
434 fs = {o.fs: #010x}
435 gs = {o.gs: #010x}
436 """.format(o=self)
437
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
445 )
446
447 def ReadRegisterDataFromKDPSavedState(self, kdp_state, kernel_version):
448 """ to be implemented"""
449 return None
450
451 def ReadRegisterDataFromKernelStack(self, kstack_saved_state_addr, kernel_version):
452 """ to be implemented """
453 return None
454
455 def ReadRegisterDataFromContinuation(self, continuation_ptr):
456 self.ResetRegisterValues()
457 self.eip = continuation_ptr
458 return self
459
460
461class X86_64RegisterSet(object):
462 """ register info set for x86_64 architecture """
463 register_info = { 'sets' : ['GPR'],
464 'registers': [
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 },
486 ]
487 }
488 def __init__(self):
489 self.ResetRegisterValues()
490
491 @classmethod
492 def GetRegisterInfo(cls, regnum):
493 if regnum < 0 or regnum > len(cls.register_info['registers']):
494 return ''
495
496 reginfo = cls.register_info['registers'][regnum]
497 retval = ''
498 for i in reginfo.keys():
499 v_str = str(reginfo[i])
500 if i == 'set':
501 v_str = 'General Purpose Registers'
502 retval += "%s:%s;" % (str(i), v_str)
503 return retval
504
505
506 def ResetRegisterValues(self):
507 """ set all the registers to zero. """
508 self.rax = 0
509 self.rbx = 0
510 self.rcx = 0
511 self.rdx = 0
512 self.rdi = 0
513 self.rsi = 0
514 self.rbp = 0
515 self.rsp = 0
516 self.r8 = 0
517 self.r9 = 0
518 self.r10 = 0
519 self.r11 = 0
520 self.r12 = 0
521 self.r13 = 0
522 self.r14 = 0
523 self.r15 = 0
524 self.rip = 0
525 self.rflags = 0
526 self.cs = 0
527 self.fs = 0
528 self.gs = 0
529
530 def __str__(self):
531 return """
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}
540 r8 = {o.r8: <#018x}
541 r9 = {o.r9: <#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}
550 cs = {o.cs: <#018x}
551 fs = {o.fs: <#018x}
552 gs = {o.gs: <#018x}
553 """.format(o=self)
554
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)
561
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()
585 return self
586
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()
600 return self
601
602 def ReadRegisterDataFromContinuation(self, continuation_ptr):
603 self.ResetRegisterValues()
604 self.rip = continuation_ptr
605 return self
606
607
608
609
610def 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
612 params:
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.
616 returns:
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
619 """
620 queue_head_addr = 0x0
621 if queue_head.TypeIsPointerType():
622 queue_head_addr = queue_head.GetValueAsUnsigned()
623 else:
624 queue_head_addr = queue_head.GetAddress().GetLoadAddress(osplugin_target_obj)
625 cur_elt = queue_head.GetChildMemberWithName('next')
626 while True:
627 if not cur_elt.IsValid() or cur_elt.GetValueAsUnsigned() == 0 or cur_elt.GetValueAsUnsigned() == queue_head_addr:
628 break
629 elt = cur_elt.Cast(element_ptr_type)
630 yield elt
631 cur_elt = elt.GetChildMemberWithName(element_field_name).GetChildMemberWithName('next')
632
633def GetUniqueSessionID(process_obj):
634 """ Create a unique session identifier.
635 params:
636 process_obj: lldb.SBProcess object refering to connected process.
637 returns:
638 int - a unique number identified by processid and stopid.
639 """
640 session_key_str = ""
641 if hasattr(process_obj, "GetUniqueID"):
642 session_key_str += str(process_obj.GetUniqueID()) + ":"
643 else:
644 session_key_str += "0:"
645
646 if hasattr(process_obj, "GetStopID"):
647 session_key_str += str(process_obj.GetStopID())
648 else:
649 session_key_str +="1"
650
651 return hash(session_key_str)
652
653
654(archX86_64, archARMv7, archI386, archARMv8) = ("x86_64", "armv7", "i386", "arm64")
655
656class OperatingSystemPlugIn(object):
657 """Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class"""
658
659 def __init__(self, process):
660 '''Initialization needs a valid.SBProcess object'''
661 self.process = None
662 self.registers = None
663 self.threads = 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
679 # state of threads.
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
706 # kdp Memory Memory
707 # gdb Server Server
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."
715 else:
716 print "Instantiating threads completely from saved state in memory."
717
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,
725 'ptr' : context,
726 'name' : 'switchtoregs' + hex(context),
727 'queue' : 'None',
728 'state' : 'stopped',
729 'stop_reason' : 'none'
730 }
731 self.thread_cache[tid] = thread_obj
732 return thread_obj
733
734 th_ptr = context
735 th = self.version.CreateValueFromExpression(str(th_ptr),'(struct thread *)' + str(th_ptr))
736 thread_id = th.GetChildMemberWithName('thread_id').GetValueAsUnsigned()
737 if tid != thread_id:
738 print "FATAL ERROR: Creating thread from memory 0x%x with tid in mem=%d when requested tid = %d " % (context, thread_id, tid)
739 return None
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'),
744 'state' : 'stopped',
745 'stop_reason' : 'none'
746 }
747 if self.current_session_id != GetUniqueSessionID(self.process):
748 self.thread_cache = {}
749 self.current_session_id = GetUniqueSessionID(self.process)
750
751 self.thread_cache[tid] = thread_obj
752 return thread_obj
753
754
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]]
769 return retval
770 else:
771 print "FATAL FAILURE: Unable to find kdp_thread state for this connection."
772 return []
773
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.
776 if num_threads <=0 :
777 return []
778
779 self.current_session_id = GetUniqueSessionID(self.process)
780 self.threads = []
781 self.thread_cache = {}
782 self.processors = []
783 try:
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."
800 return self.threads
801
802 if hasattr(self.process, 'CreateOSPluginThread'):
803 return self.threads
804
805 # FIXME remove legacy code
806 try:
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."
820 return self.threads
821 # end legacy code
822 return self.threads
823
824 def get_register_info(self):
825 if self.registers == None:
826 print "Register Information not found "
827 return self.register_set.register_info
828
829 def get_register_data(self, tid):
830 thobj = None
831 try:
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():
837
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()
843
844 thobj = self.version.CreateValueFromExpression(self.thread_cache[tid]['name'], '(struct thread *)' + str(self.thread_cache[tid]['ptr']))
845
846 if thobj == None :
847 print "FATAL ERROR: Could not find thread with id %d" % tid
848 regs.ResetRegisterValues()
849 return regs.GetPackedRegisterState()
850
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
879 print thobj
880 return regs.GetPackedRegisterState()