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