]> git.saurik.com Git - apple/xnu.git/blame - tools/lldbmacros/core/operating_system.py
xnu-6153.101.6.tar.gz
[apple/xnu.git] / tools / lldbmacros / core / operating_system.py
CommitLineData
39236c6e
A
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):
fe8ab488
A
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': [
3e170ce0
A
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'},
fe8ab488
A
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'},
3e170ce0
A
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},
fe8ab488
A
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 """
3e170ce0 116 saved_state = kernel_version.CreateValueFromExpression(None, '(struct arm_saved_state64 *) ' + str(kdp_state.GetValueAsUnsigned()))
fe8ab488
A
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, '(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()
200 return self
201
202 def ReadRegisterDataFromContinuation(self, continuation_ptr):
203 self.ResetRegisterValues()
204 self.pc = continuation_ptr
205 return self
206
207 @classmethod
208 def GetRegisterInfo(cls, regnum):
209 if regnum < 0 or regnum > len(cls.register_info['registers']):
210 return ''
211
212 reginfo = cls.register_info['registers'][regnum]
213 retval = ''
214 for i in reginfo.keys():
215 v_str = str(reginfo[i])
216 if i == 'set':
217 v_str = 'General Purpose Registers'
218 retval += "%s:%s;" % (str(i), v_str)
219 return retval
220
39236c6e
A
221
222
223class Armv7_RegisterSet(object):
fe8ab488
A
224 """ register info set for armv7 32 bit architecture """
225 register_info = { 'sets' : ['GPR'],
226 'registers': [
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},
3e170ce0
A
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}
fe8ab488
A
246 ]
247 }
248
249 def __init__(self):
250 self.switch_context_address = osplugin_target_obj.FindSymbols('load_reg')[0].GetSymbol().GetStartAddress().GetLoadAddress(osplugin_target_obj) + 8
251 self.ResetRegisterValues()
252
253 @classmethod
254 def GetRegisterInfo(cls, regnum):
255 if regnum < 0 or regnum > len(cls.register_info['registers']):
256 return ''
257
258 reginfo = cls.register_info['registers'][regnum]
259 retval = ''
260 for i in reginfo.keys():
261 v_str = str(reginfo[i])
262 if i == 'set':
263 v_str = 'General Purpose Registers'
264 retval += "%s:%s;" % (str(i), v_str)
265 return retval
266
267 def ResetRegisterValues(self):
268 self.r0 = 0
269 self.r1 = 0
270 self.r2 = 0
271 self.r3 = 0
272 self.r4 = 0
273 self.r5 = 0
274 self.r6 = 0
275 self.r7 = 0
276 self.r8 = 0
277 self.r9 = 0
278 self.r10 = 0
279 self.r11 = 0
280 self.r12 = 0
281 self.sp = 0
282 self.lr = 0
283 self.pc = 0
284 self.cpsr = 0
285 self.fsr = 0
286 self.far = 0
287
288 def __str__(self):
289 return """
290 r0 = {o.r0: <#010x}
291 r1 = {o.r1: <#010x}
292 r2 = {o.r2: <#010x}
293 r3 = {o.r3: <#010x}
294 r4 = {o.r4: <#010x}
295 r5 = {o.r5: <#010x}
296 r6 = {o.r6: <#010x}
297 r7 = {o.r7: <#010x}
298 r8 = {o.r8: <#010x}
299 r9 = {o.r9: <#010x}
300 r10 = {o.r10: <#010x}
301 r11 = {o.r11: <#010x}
302 r12 = {o.r12: <#010x}
303 sp = {o.sp: <#010x}
304 lr = {o.lr: <#010x}
305 pc = {o.pc: <#010x}
306 cpsr = {o.cpsr: <#010x}
307 fsr = {o.fsr : <#010x}
308 far = {o.far : <#010x}
309 """.format(o=self)
310
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)
317
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()
342 return self
343
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()
369 return self
370
371 def ReadRegisterDataFromContinuation(self, continuation_ptr):
372 self.ResetRegisterValues()
373 self.pc = continuation_ptr
374 return self
39236c6e
A
375
376
377class I386_RegisterSet(object):
fe8ab488
A
378 """ register info set for i386 architecture
379 """
380 register_info = { 'sets' : ['GPR'],
381 'registers': [
382 { 'name': 'eax' , 'bitsize': 32, 'offset' : 0, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 0, 'dwarf': 0},
3e170ce0
A
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},
fe8ab488
A
398 ]
399 }
400
401 def __init__(self):
402 self.ResetRegisterValues()
403
404 @classmethod
405 def GetRegisterInfo(cls, regnum):
406 if regnum < 0 or regnum > len(cls.register_info['registers']):
407 return ''
408
409 reginfo = cls.register_info['registers'][regnum]
410 retval = ''
411 for i in reginfo.keys():
412 v_str = str(reginfo[i])
413 if i == 'set':
414 v_str = 'General Purpose Registers'
415 retval += "%s:%s;" % (str(i), v_str)
416 return retval
417
418 def ResetRegisterValues(self):
419 """ set all registers to zero """
420 self.eax = 0
421 self.ebx = 0
422 self.ecx = 0
423 self.edx = 0
424 self.edi = 0
425 self.esi = 0
426 self.ebp = 0
427 self.esp = 0
428 self.ss = 0
429 self.eflags = 0
430 self.eip = 0
431 self.cs = 0
432 self.ds = 0
433 self.es = 0
434 self.fs = 0
435 self.gs = 0
436
437 def __str__(self):
438 return """
439 eax = {o.eax: #010x}
440 ebx = {o.ebx: #010x}
441 ecx = {o.ecx: #010x}
442 edx = {o.edx: #010x}
443 edi = {o.edi: #010x}
444 esi = {o.esi: #010x}
445 ebp = {o.ebp: #010x}
446 esp = {o.esp: #010x}
447 ss = {o.ss: #010x}
448 eflags = {o.eflags: #010x}
449 eip = {o.eip: #010x}
450 cs = {o.cs: #010x}
451 ds = {o.ds: #010x}
452 es = {o.es: #010x}
453 fs = {o.fs: #010x}
454 gs = {o.gs: #010x}
455 """.format(o=self)
456
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
464 )
465
466 def ReadRegisterDataFromKDPSavedState(self, kdp_state, kernel_version):
467 """ to be implemented"""
468 return None
469
470 def ReadRegisterDataFromKernelStack(self, kstack_saved_state_addr, kernel_version):
471 """ to be implemented """
472 return None
473
474 def ReadRegisterDataFromContinuation(self, continuation_ptr):
475 self.ResetRegisterValues()
476 self.eip = continuation_ptr
477 return self
478
479
39236c6e 480class X86_64RegisterSet(object):
fe8ab488
A
481 """ register info set for x86_64 architecture """
482 register_info = { 'sets' : ['GPR'],
483 'registers': [
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 },
505 ]
506 }
507 def __init__(self):
508 self.ResetRegisterValues()
509
510 @classmethod
511 def GetRegisterInfo(cls, regnum):
512 if regnum < 0 or regnum > len(cls.register_info['registers']):
513 return ''
514
515 reginfo = cls.register_info['registers'][regnum]
516 retval = ''
517 for i in reginfo.keys():
518 v_str = str(reginfo[i])
519 if i == 'set':
520 v_str = 'General Purpose Registers'
521 retval += "%s:%s;" % (str(i), v_str)
522 return retval
523
524
525 def ResetRegisterValues(self):
526 """ set all the registers to zero. """
527 self.rax = 0
528 self.rbx = 0
529 self.rcx = 0
530 self.rdx = 0
531 self.rdi = 0
532 self.rsi = 0
533 self.rbp = 0
534 self.rsp = 0
535 self.r8 = 0
536 self.r9 = 0
537 self.r10 = 0
538 self.r11 = 0
539 self.r12 = 0
540 self.r13 = 0
541 self.r14 = 0
542 self.r15 = 0
543 self.rip = 0
544 self.rflags = 0
545 self.cs = 0
546 self.fs = 0
547 self.gs = 0
548
549 def __str__(self):
550 return """
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}
559 r8 = {o.r8: <#018x}
560 r9 = {o.r9: <#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}
569 cs = {o.cs: <#018x}
570 fs = {o.fs: <#018x}
571 gs = {o.gs: <#018x}
572 """.format(o=self)
573
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)
580
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()
604 return self
605
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()
619 return self
620
621 def ReadRegisterDataFromContinuation(self, continuation_ptr):
622 self.ResetRegisterValues()
623 self.rip = continuation_ptr
624 return self
39236c6e
A
625
626
627
628
629def IterateQueue(queue_head, element_ptr_type, element_field_name):
fe8ab488 630 """ iterate over a queue in kernel of type queue_head_t. refer to osfmk/kern/queue.h
39236c6e
A
631 params:
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.
635 returns:
636 A generator does not return. It is used for iterating.
fe8ab488 637 SBValue : an object thats of type (element_type) queue_head->next. Always a pointer object
39236c6e
A
638 """
639 queue_head_addr = 0x0
640 if queue_head.TypeIsPointerType():
641 queue_head_addr = queue_head.GetValueAsUnsigned()
642 else:
643 queue_head_addr = queue_head.GetAddress().GetLoadAddress(osplugin_target_obj)
644 cur_elt = queue_head.GetChildMemberWithName('next')
645 while True:
39236c6e
A
646 if not cur_elt.IsValid() or cur_elt.GetValueAsUnsigned() == 0 or cur_elt.GetValueAsUnsigned() == queue_head_addr:
647 break
648 elt = cur_elt.Cast(element_ptr_type)
649 yield elt
650 cur_elt = elt.GetChildMemberWithName(element_field_name).GetChildMemberWithName('next')
651
652def GetUniqueSessionID(process_obj):
fe8ab488
A
653 """ Create a unique session identifier.
654 params:
655 process_obj: lldb.SBProcess object refering to connected process.
656 returns:
657 int - a unique number identified by processid and stopid.
658 """
659 session_key_str = ""
660 if hasattr(process_obj, "GetUniqueID"):
661 session_key_str += str(process_obj.GetUniqueID()) + ":"
662 else:
663 session_key_str += "0:"
39236c6e 664
fe8ab488
A
665 if hasattr(process_obj, "GetStopID"):
666 session_key_str += str(process_obj.GetStopID())
667 else:
668 session_key_str +="1"
39236c6e 669
fe8ab488 670 return hash(session_key_str)
39236c6e
A
671
672
5ba3f43e 673(archX86_64, archARMv7, archI386, archARMv8) = ("x86_64", "armv7", "i386", "arm64")
39236c6e
A
674
675class OperatingSystemPlugIn(object):
676 """Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class"""
fe8ab488 677
39236c6e
A
678 def __init__(self, process):
679 '''Initialization needs a valid.SBProcess object'''
680 self.process = None
681 self.registers = None
682 self.threads = 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)
3e170ce0
A
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()
39236c6e
A
694 self.kernel_context_size = 0
695 self.connected_over_kdp = False
fe8ab488
A
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
698 # state of threads.
699 self.connected_to_debugserver = True
39236c6e
A
700 plugin_string = self.process.GetPluginName().lower()
701 if plugin_string.find("kdp") >=0:
702 self.connected_over_kdp = True
fe8ab488 703 self.connected_to_debugserver = False
39236c6e
A
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 :
fe8ab488
A
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()
5ba3f43e
A
715 self.kernel_thread_state_size = self._target.FindFirstType('struct thread_kernel_state').GetByteSize()
716 elif arch.startswith(archARMv7) :
fe8ab488
A
717 self.target_arch = arch
718 print "Target arch: " + self.target_arch
719 self.register_set = Armv7_RegisterSet()
5ba3f43e 720 elif arch.startswith(archARMv8):
fe8ab488
A
721 self.target_arch = arch
722 print "Target arch: " + self.target_arch
723 self.register_set = Armv8_RegisterSet()
724 # connection intel arm
725 # kdp Memory Memory
726 # gdb Server Server
727 # coredump Memory Server
728 if not self.connected_over_kdp :
729 if plugin_string.find('core') >= 0 and self.target_arch == archX86_64:
730 self.connected_to_debugserver = False
39236c6e 731 self.registers = self.register_set.register_info
fe8ab488
A
732 if self.connected_to_debugserver:
733 print "Connected to live debugserver or arm core. Will associate on-core threads to registers reported by server."
734 else:
735 print "Instantiating threads completely from saved state in memory."
736
39236c6e 737 def create_thread(self, tid, context):
5ba3f43e 738 # tid == deadbeef means its a custom thread which kernel does not know of.
3e170ce0
A
739 if tid == 0xdeadbeef :
740 # tid manipulation should be the same as in "switchtoregs" code in lldbmacros/process.py .
741 tid = 0xdead0000 | (context & ~0xffff0000)
742 tid = tid & 0xdeadffff
743 thread_obj = { 'tid' : tid,
744 'ptr' : context,
745 'name' : 'switchtoregs' + hex(context),
746 'queue' : 'None',
747 'state' : 'stopped',
748 'stop_reason' : 'none'
749 }
750 self.thread_cache[tid] = thread_obj
751 return thread_obj
752
39236c6e
A
753 th_ptr = context
754 th = self.version.CreateValueFromExpression(str(th_ptr),'(struct thread *)' + str(th_ptr))
755 thread_id = th.GetChildMemberWithName('thread_id').GetValueAsUnsigned()
756 if tid != thread_id:
fe8ab488
A
757 print "FATAL ERROR: Creating thread from memory 0x%x with tid in mem=%d when requested tid = %d " % (context, thread_id, tid)
758 return None
39236c6e
A
759 thread_obj = { 'tid' : thread_id,
760 'ptr' : th.GetValueAsUnsigned(),
761 'name' : hex(th.GetValueAsUnsigned()).rstrip('L'),
762 'queue' : hex(th.GetChildMemberWithName('wait_queue').GetValueAsUnsigned()).rstrip('L'),
763 'state' : 'stopped',
764 'stop_reason' : 'none'
765 }
766 if self.current_session_id != GetUniqueSessionID(self.process):
fe8ab488
A
767 self.thread_cache = {}
768 self.current_session_id = GetUniqueSessionID(self.process)
39236c6e
A
769
770 self.thread_cache[tid] = thread_obj
771 return thread_obj
772
773
774 def get_thread_info(self):
775 self.kdp_thread = None
776 self.kdp_state = None
777 if self.connected_over_kdp :
778 kdp = self._target.FindGlobalVariables('kdp',1).GetValueAtIndex(0)
779 kdp_state = kdp.GetChildMemberWithName('saved_state')
780 kdp_thread = kdp.GetChildMemberWithName('kdp_thread')
781 if kdp_thread and kdp_thread.GetValueAsUnsigned() != 0:
fe8ab488
A
782 self.kdp_thread = kdp_thread
783 self.kdp_state = kdp_state
784 kdp_thid = kdp_thread.GetChildMemberWithName('thread_id').GetValueAsUnsigned()
785 self.create_thread(kdp_thid, kdp_thread.GetValueAsUnsigned())
786 self.thread_cache[kdp_thid]['core']=0
787 retval = [self.thread_cache[kdp_thid]]
788 return retval
39236c6e 789 else:
fe8ab488
A
790 print "FATAL FAILURE: Unable to find kdp_thread state for this connection."
791 return []
39236c6e
A
792
793 num_threads = self._target.FindGlobalVariables('threads_count',1).GetValueAtIndex(0).GetValueAsUnsigned()
794 #In case we are caught before threads are initialized. Fallback to threads known by astris/gdb server.
795 if num_threads <=0 :
796 return []
fe8ab488 797
39236c6e
A
798 self.current_session_id = GetUniqueSessionID(self.process)
799 self.threads = []
800 self.thread_cache = {}
801 self.processors = []
802 try:
fe8ab488
A
803 processor_list_val = PluginValue(self._target.FindGlobalVariables('processor_list',1).GetValueAtIndex(0))
804 while processor_list_val.IsValid() and processor_list_val.GetValueAsUnsigned() !=0 :
805 th = processor_list_val.GetChildMemberWithName('active_thread')
806 th_id = th.GetChildMemberWithName('thread_id').GetValueAsUnsigned()
807 cpu_id = processor_list_val.GetChildMemberWithName('cpu_id').GetValueAsUnsigned()
808 self.processors.append({'active_thread': th.GetValueAsUnsigned(), 'cpu_id': cpu_id})
809 self.create_thread(th_id, th.GetValueAsUnsigned())
810 if self.connected_to_debugserver:
811 self.thread_cache[th_id]['core'] = cpu_id
812 self.thread_cache[th_id]['queue'] = "cpu-%d" % int(cpu_id)
813 nth = self.thread_cache[th_id]
814 self.threads.append(nth)
815 self.thread_cache[nth['tid']] = nth
816 processor_list_val = processor_list_val.GetChildMemberWithName('processor_list')
39236c6e 817 except KeyboardInterrupt, ke:
fe8ab488
A
818 print "OS Plugin Interrupted during thread loading process. \nWARNING:Thread registers and backtraces may not be accurate."
819 return self.threads
820
39236c6e 821 if hasattr(self.process, 'CreateOSPluginThread'):
fe8ab488 822 return self.threads
39236c6e 823
fe8ab488 824 # FIXME remove legacy code
39236c6e 825 try:
3e170ce0 826 thread_q_head = self._target.FindGlobalVariables('threads', 1).GetValueAtIndex(0)
fe8ab488
A
827 thread_type = self._target.FindFirstType('thread')
828 thread_ptr_type = thread_type.GetPointerType()
829 for th in IterateQueue(thread_q_head, thread_ptr_type, 'threads'):
830 th_id = th.GetChildMemberWithName('thread_id').GetValueAsUnsigned()
831 self.create_thread(th_id, th.GetValueAsUnsigned())
832 nth = self.thread_cache[th_id]
833 for cputhread in self.processors:
834 if cputhread['active_thread'] == nth['ptr']:
835 nth['core'] = cputhread['cpu_id']
836 self.threads.append( nth )
39236c6e 837 except KeyboardInterrupt, ke:
fe8ab488
A
838 print "OS Plugin Interrupted during thread loading process. \nWARNING:Thread registers and backtraces may not be accurate."
839 return self.threads
840 # end legacy code
39236c6e 841 return self.threads
fe8ab488 842
39236c6e
A
843 def get_register_info(self):
844 if self.registers == None:
fe8ab488 845 print "Register Information not found "
39236c6e 846 return self.register_set.register_info
fe8ab488 847
39236c6e 848 def get_register_data(self, tid):
39236c6e
A
849 thobj = None
850 try:
3e170ce0 851 regs = self.register_set
fe8ab488
A
852 if self.current_session_id != GetUniqueSessionID(self.process):
853 self.thread_cache = {}
854 self.current_session_id = GetUniqueSessionID(self.process)
fe8ab488 855 if tid in self.thread_cache.keys():
3e170ce0
A
856
857 #Check if the thread is a fake one. Then create and return registers directly
858 if self.thread_cache[tid]['name'].find('switchtoregs') == 0:
859 savedstateobj = self.version.CreateValueFromExpression(None, '(uintptr_t *) ' + str(self.thread_cache[tid]['ptr']))
860 regs.ReadRegisterDataFromKDPSavedState(savedstateobj, self.version)
861 return regs.GetPackedRegisterState()
862
fe8ab488 863 thobj = self.version.CreateValueFromExpression(self.thread_cache[tid]['name'], '(struct thread *)' + str(self.thread_cache[tid]['ptr']))
3e170ce0 864
fe8ab488
A
865 if thobj == None :
866 print "FATAL ERROR: Could not find thread with id %d" % tid
867 regs.ResetRegisterValues()
868 return regs.GetPackedRegisterState()
869
870 if self.kdp_thread and self.kdp_thread.GetValueAsUnsigned() == thobj.GetValueAsUnsigned():
871 regs.ReadRegisterDataFromKDPSavedState(self.kdp_state, self.version)
872 return regs.GetPackedRegisterState()
873 if int(PluginValue(thobj).GetChildMemberWithName('kernel_stack').GetValueAsUnsigned()) != 0 :
874 if self.target_arch == archX86_64 :
875 # we do have a stack so lets get register information
5ba3f43e 876 saved_state_addr = PluginValue(thobj).GetChildMemberWithName('kernel_stack').GetValueAsUnsigned() + self.kernel_stack_size - self.kernel_thread_state_size
fe8ab488
A
877 regs.ReadRegisterDataFromKernelStack(saved_state_addr, self.version)
878 return regs.GetPackedRegisterState()
5ba3f43e 879 elif self.target_arch.startswith(archARMv7) and int(PluginValue(thobj).GetChildMemberWithName('machine').GetChildMemberWithName('kstackptr').GetValueAsUnsigned()) != 0:
fe8ab488
A
880 #we have stack on the machine.kstackptr.
881 saved_state_addr = PluginValue(thobj).GetChildMemberWithName('machine').GetChildMemberWithName('kstackptr').GetValueAsUnsigned()
882 regs.ReadRegisterDataFromKernelStack(saved_state_addr, self.version)
883 return regs.GetPackedRegisterState()
5ba3f43e 884 elif self.target_arch.startswith(archARMv8) and int(PluginValue(thobj).GetChildMemberWithName('machine').GetChildMemberWithName('kstackptr').GetValueAsUnsigned()) != 0:
fe8ab488
A
885 saved_state_addr = PluginValue(thobj).GetChildMemberWithName('machine').GetChildMemberWithName('kstackptr').GetValueAsUnsigned()
886 arm_ctx = PluginValue(self.version.CreateValueFromExpression(None, '(struct arm_context *) ' + str(saved_state_addr)))
887 ss_64_addr = arm_ctx.GetChildMemberWithName('ss').GetChildMemberWithName('uss').GetChildMemberWithName('ss_64').GetLoadAddress()
888 regs.ReadRegisterDataFromKernelStack(ss_64_addr, self.version)
889 return regs.GetPackedRegisterState()
5ba3f43e 890 elif self.target_arch == archX86_64 or self.target_arch.startswith(archARMv7) or self.target_arch.startswith(archARMv8):
fe8ab488
A
891 regs.ReadRegisterDataFromContinuation( PluginValue(thobj).GetChildMemberWithName('continuation').GetValueAsUnsigned())
892 return regs.GetPackedRegisterState()
893 #incase we failed very miserably
39236c6e 894 except KeyboardInterrupt, ke:
fe8ab488 895 print "OS Plugin Interrupted during thread register load. \nWARNING:Thread registers and backtraces may not be accurate. for tid = %d" % tid
39236c6e
A
896 regs.ResetRegisterValues()
897 print "FATAL ERROR: Failed to get register state for thread id 0x%x " % tid
898 print thobj
899 return regs.GetPackedRegisterState()