]> git.saurik.com Git - apple/xnu.git/blame - tools/lldbmacros/kdp.py
xnu-7195.101.1.tar.gz
[apple/xnu.git] / tools / lldbmacros / kdp.py
CommitLineData
39236c6e
A
1from xnu import *
2from utils import *
3import sys
4
bca245ac
A
5current_KDP_mode = "swhosted"
6
39236c6e
A
7def GetKDPPacketHeaderInt(request=0, is_reply=False, seq=0, length=0, key=0):
8 """ create a 64 bit number that could be saved as pkt_hdr_t
9 params:
10 request:int - 7 bit kdp_req_t request type
11 is_reply:bool - False => request, True => reply
12 seq: int - 8 sequence number within session
13 length: int - 16 bit length of entire pkt including hdr
14 key: int - session key
15 returns:
16 int - 64 bit number to be saved in memory
17 """
18 retval = request
19 if is_reply:
20 retval = 1<<7 |retval
21 retval = (seq << 8) | retval
22 retval = (length << 16) | retval
23 #retval = (retval << 32) | key
24 retval = (key << 32) | retval
25 return retval
26
27
28def KDPDumpInfo(subcmd, file_name="", dest_ip="", router_ip="", port=0):
29 """ Setup the state for DUMP INFO commands for sending coredump etc
30 """
31 if "kdp" != GetConnectionProtocol():
32 print "Target is not connected over kdp. Nothing to do here."
33 return False
34 input_address = unsigned(addressof(kern.globals.manual_pkt.input))
35 len_address = unsigned(addressof(kern.globals.manual_pkt.len))
36 data_address = unsigned(addressof(kern.globals.manual_pkt.data))
37 if not WriteInt32ToMemoryAddress(0, input_address):
38 return False
39
40 kdp_pkt_size = GetType('kdp_dumpinfo_req_t').GetByteSize()
41 if not WriteInt32ToMemoryAddress(kdp_pkt_size, len_address):
42 return False
43
44 data_addr = int(addressof(kern.globals.manual_pkt))
45 pkt = kern.GetValueFromAddress(data_addr, 'kdp_dumpinfo_req_t *')
46 if len(file_name) > 49:
47 file_name = file_name[:49]
48 if len(dest_ip) > 15:
49 dest_ip = dest_ip[:15]
50 if len(router_ip) > 15:
51 router_ip = router_ip[:15]
52
53 header_value =GetKDPPacketHeaderInt(request=GetEnumValue('kdp_req_t::KDP_DUMPINFO'), length=kdp_pkt_size)
54 # 0x1f is same as KDP_DUMPINFO
55 if ( WriteInt64ToMemoryAddress((header_value), int(addressof(pkt.hdr))) and
56 WriteInt32ToMemoryAddress(subcmd, int(addressof(pkt.type))) and
57 WriteStringToMemoryAddress(file_name, int(addressof(pkt.name))) and
58 WriteStringToMemoryAddress(dest_ip, int(addressof(pkt.destip))) and
59 WriteStringToMemoryAddress(router_ip, int(addressof(pkt.routerip)))
60 ):
61 #We have saved important data successfully
62 if port > 0:
63 if not WriteInt32ToMemoryAddress(port, int(addressof(pkt.port))):
64 return False
65 if WriteInt32ToMemoryAddress(1, input_address):
66 return True
67 return False
68
69@lldb_command('sendcore')
70def KDPSendCore(cmd_args=None):
71 """ Configure kernel to send a coredump to the specified IP
72 Syntax: sendcore <IP address> [filename]
73 Configure the kernel to transmit a kernel coredump to a server (kdumpd)
74 at the specified IP address. This is useful when the remote target has
75 not been previously configured to transmit coredumps, and you wish to
76 preserve kernel state for later examination. NOTE: You must issue a "continue"
77 command after using this macro to trigger the kernel coredump. The kernel
78 will resume waiting in the debugger after completion of the coredump. You
79 may disable coredumps by executing the "disablecore" macro. You can
80 optionally specify the filename to be used for the generated core file.
81
82 """
83 if cmd_args == None or len(cmd_args) < 1:
84 print KDPSendCore.__doc__
85 return False
86 ip_address = cmd_args[0]
87 filename=""
88 if len(cmd_args) >=2:
89 filename = cmd_args[1].strip()
90 retval = KDPDumpInfo(GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_CORE'), file_name=filename, dest_ip=ip_address)
91 if retval:
92 print "Remote system has been setup for coredump. Please detach/continue the system. "
93 return True
94 else:
95 print "Something went wrong. Failed to setup the coredump on the target."
96 return False
97
98
99@lldb_command('sendsyslog')
100def KDPSendSyslog(cmd_args=None):
101 """ Configure kernel to send a system log to the specified IP
102 Syntax: sendsyslog <IP address> [filename]
103 Configure the kernel to transmit a kernel system log to a server (kdumpd)
104 at the specified IP address. NOTE: You must issue a "continue"
105 command after using this macro to trigger the kernel system log. The kernel
106 will resume waiting in the debugger after completion. You can optionally
107 specify the name to be used for the generated system log.
108 """
109 if cmd_args == None or len(cmd_args) < 1:
110 print KDPSendSyslog.__doc__
111 return False
112 ip_address = cmd_args[0]
113 filename =""
114 if len(cmd_args) >=2:
115 filename = cmd_args[1].strip()
116 retval = KDPDumpInfo(GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_SYSTEMLOG'), file_name = filename, dest_ip = ip_address)
117 if retval:
118 print "Remote system has been setup to send system log. please detach/continue the system."
119 return True
120 else:
121 print "Something went wrong. Failed to setup the systemlog on the target."
122 return False
123
124@lldb_command('sendpaniclog')
125def KDPSendPaniclog(cmd_args=None):
126 """ Configure kernel to send a panic log to the specified IP
127 Syntax: sendpaniclog <IP address> [filename]
128 Configure the kernel to transmit a kernel paniclog to a server (kdumpd)
129 at the specified IP address. NOTE: You must issue a "continue"
130 command after using this macro to trigger the kernel panic log. The kernel
131 will resume waiting in the debugger after completion. You can optionally
132 specify the name to be used for the generated panic log.
133 """
134 if cmd_args == None or len(cmd_args) < 1:
135 print KDPSendPaniclog.__doc__
136 return False
137 ip_address = cmd_args[0]
138 filename =""
139 if len(cmd_args) >=2:
140 filename = cmd_args[1].strip()
141 retval = KDPDumpInfo(GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_PANICLOG'), file_name = filename, dest_ip = ip_address)
142 if retval:
143 print "Remote system has been setup to send panic log. please detach/continue the system."
144 return True
145 else:
146 print "Something went wrong. Failed to setup the paniclog on the target."
147 return False
148
149
150@lldb_command('disablecore')
151def KDPDisableCore(cmd_args=None):
152 """ Configure the kernel to disable coredump transmission
153 Reconfigures the kernel so that it no longer transmits kernel coredumps. This
154 complements the "sendcore" macro, but it may be used if the kernel has been
155 configured to transmit coredumps through boot-args as well.
156
157 """
158 retval = KDPDumpInfo(GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_DISABLE'))
159 if retval :
160 print "Disabled coredump functionality on remote system."
161 else:
162 print "Failed to disable coredump functionality."
163 return retval
164
165@lldb_command('resume_on')
166def KDPResumeON(cmd_args=None):
167 """ The target system will resume when detaching or exiting from lldb.
168 This is the default behavior.
169 """
170 subcmd = GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_SETINFO') | GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_RESUME')
171 retval = KDPDumpInfo(subcmd)
172 if retval :
173 print "Target system will resume on detaching from lldb."
174 else:
175 print "Failed to enable resume functionality."
176 return retval
177
178@lldb_command('resume_off')
5ba3f43e 179def KDPResumeOFF(cmd_args=None):
39236c6e
A
180 """ The target system will not resume when detaching or exiting from lldb.
181 """
182 subcmd = GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_SETINFO') | GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_NORESUME')
183 retval = KDPDumpInfo(subcmd)
184 if retval :
185 print "Target system will not resume on detaching from lldb."
186 else:
187 print "Failed to disable resume functionality."
188 return retval
189
190
191
192@lldb_command('getdumpinfo')
193def KDPGetDumpInfo(cmd_args=None):
194 """ Retrieve the current remote dump settings.
195 """
196 if not KDPDumpInfo(GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_GETINFO')):
197 print "Failed to get dump settings."
198 return False
199 dumpinfo = Cast(addressof(kern.globals.manual_pkt.data), 'kdp_dumpinfo_reply_t *')
200 target_dump_type = int(dumpinfo.type)
201 if target_dump_type & GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_REBOOT'):
202 print "System will reboot after kernel info gets dumped."
203 else:
204 print "System will not reboot after kernel info gets dumped."
205 if target_dump_type & GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_RESUME'):
206 print "System will allow a re-attach after KDP disconnect."
207 else:
208 print "System will not allow a re-attach after KDP disconnect."
209 target_dump_type = target_dump_type & GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_MASK')
210 if target_dump_type == GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_DISABLE'):
211 print "Kernel not setup for remote dumps."
212 else:
213 kern_dump_type = ''
214 if target_dump_type == GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_CORE'):
215 kern_dump_type = "Core File"
216 elif target_dump_type == GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_PANICLOG'):
217 kern_dump_type = "Panic Log"
218 elif target_dump_type == GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_SYSTEMLOG'):
219 kern_dump_type = "System Log"
220 print "Kernel dump type:" + kern_dump_type
221 fname = "(autogenerated)"
222 if int(dumpinfo.name[0]) != 0:
223 fname = str(dumpinfo.name)
224 print "Filename: " + fname
225 print "Network Info: {:s} [{:d}] , Router: {:s}".format(dumpinfo.destip, dumpinfo.port, dumpinfo.routerip)
226 # end of get dump info
227
228
229@lldb_command('kdp-reenter')
230def KDPReenter(cmd_args=None):
231 """ Schedules reentry into the debugger
232 after <seconds> seconds, and resumes the target.
233 usage: kdp-reenter <seconds>
234 """
235 if len(cmd_args) < 1:
236 print "Please provide valid time in seconds"
237 print KDPReenter.__doc__
238 return False
239
240 if "kdp" != GetConnectionProtocol():
241 print "Target is not connected over kdp. Nothing to do here."
242 return False
243
244 num_seconds = ArgumentStringToInt(cmd_args[0])
245 milliseconds_to_sleep = num_seconds * 1000
246 if WriteInt32ToMemoryAddress(milliseconds_to_sleep, addressof(kern.globals.kdp_reentry_deadline)):
247 lldb.debugger.HandleCommand('process continue')
248 return True
249 print "Failed to setup kdp-reentry."
250 return False
251
252@lldb_command('kdp-reboot')
253def KDPReboot(cmd_args=None):
254 """ Restart the remote target
255 """
256 if "kdp" != GetConnectionProtocol():
257 print "Target is not connected over kdp. Nothing to do here."
258 return False
259
260 print "Rebooting the remote machine."
261 lldb.debugger.HandleCommand('process plugin packet send --command 0x13')
262 lldb.debugger.HandleCommand('detach')
263 return True
264
265@lldb_command('setdumpinfo')
266def KDPSetDumpInfo(cmd_args=None):
267 """ Configure the current remote dump settings.
268 Specify "" if you want to use the defaults (filename) or previously configured
269 settings (ip/router). Specify 0 for the port if you wish to
270 use the previously configured/default setting for that.
271 Syntax: setdumpinfo <filename> <ip> <router> <port>
272 """
273 if not cmd_args:
274 print KDPSetDumpInfo.__doc__
275 return False
276 if len(cmd_args) < 4:
277 print "Not enough arguments."
278 print KDPSetDumpInfo.__doc__
279 return False
280 portnum = ArgumentStringToInt(cmd_args[3])
281 retval = KDPDumpInfo(GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_SETINFO'), cmd_args[0], cmd_args[1], cmd_args[2], portnum)
282 if retval:
283 print "Successfully saved the dumpinfo."
284 else:
285 print "Failed to save the dumpinfo."
286 return retval
287
bca245ac
A
288@lldb_command('kdpmode')
289def KDPMode(cmd_args=None):
290 """
291 Change KDP mode between software hosted and hardware probe.
292 When lldb is connected to a KDP server backed by a hardware debug tool
293 setting this to 'hwprobe' enables physical memory access.
294
295 swhosted: LLDB is connected to the target using a serial or socket connection.
296 hwprobe: LLDB is connected to the target using a hardware probe.
297
298 usage: kdpmode <mode>
299 mode: 'swhosted' or 'hwprobe'
300 """
301 global current_KDP_mode
302
303 if cmd_args == None or len(cmd_args) == 0:
304 return current_KDP_mode
305 if len(cmd_args) > 1 or cmd_args[0] not in {'swhosted', 'hwprobe'}:
306 print "Invalid Arguments", KDPMode.__doc__
307 else:
308 current_KDP_mode = cmd_args[0]
309 return
310