]>
git.saurik.com Git - apple/xnu.git/blob - tools/lldbmacros/kdp.py
   5 def GetKDPPacketHeaderInt(request
=0, is_reply
=False, seq
=0, length
=0, key
=0): 
   6     """ create a 64 bit number that could be saved as pkt_hdr_t 
   8             request:int   - 7 bit kdp_req_t request type 
   9             is_reply:bool - False => request, True => reply  
  10             seq: int      - 8  sequence number within session  
  11             length: int   - 16 bit length of entire pkt including hdr  
  12             key: int      - session key  
  14             int - 64 bit number to be saved in memory 
  19     retval 
= (seq 
<< 8) | retval
 
  20     retval 
= (length 
<< 16) | retval
 
  21     #retval = (retval << 32) | key 
  22     retval 
= (key 
<< 32) | retval
 
  26 def KDPDumpInfo(subcmd
, file_name
="", dest_ip
="", router_ip
="", port
=0): 
  27     """ Setup the state for DUMP INFO commands for sending coredump etc 
  29     if "kdp" != GetConnectionProtocol(): 
  30         print "Target is not connected over kdp. Nothing to do here." 
  32     input_address 
= unsigned(addressof(kern
.globals.manual_pkt
.input)) 
  33     len_address 
= unsigned(addressof(kern
.globals.manual_pkt
.len)) 
  34     data_address 
= unsigned(addressof(kern
.globals.manual_pkt
.data
)) 
  35     if not WriteInt32ToMemoryAddress(0, input_address
): 
  38     kdp_pkt_size 
= GetType('kdp_dumpinfo_req_t').GetByteSize() 
  39     if not WriteInt32ToMemoryAddress(kdp_pkt_size
, len_address
): 
  42     data_addr 
= int(addressof(kern
.globals.manual_pkt
)) 
  43     pkt 
= kern
.GetValueFromAddress(data_addr
, 'kdp_dumpinfo_req_t *') 
  44     if len(file_name
) > 49: 
  45         file_name 
= file_name
[:49] 
  47         dest_ip 
= dest_ip
[:15] 
  48     if len(router_ip
) > 15: 
  49         router_ip 
= router_ip
[:15] 
  51     header_value 
=GetKDPPacketHeaderInt(request
=GetEnumValue('kdp_req_t::KDP_DUMPINFO'), length
=kdp_pkt_size
) 
  52     # 0x1f is same as KDP_DUMPINFO 
  53     if ( WriteInt64ToMemoryAddress((header_value
), int(addressof(pkt
.hdr
))) and 
  54          WriteInt32ToMemoryAddress(subcmd
, int(addressof(pkt
.type))) and 
  55          WriteStringToMemoryAddress(file_name
, int(addressof(pkt
.name
))) and 
  56          WriteStringToMemoryAddress(dest_ip
, int(addressof(pkt
.destip
))) and 
  57          WriteStringToMemoryAddress(router_ip
, int(addressof(pkt
.routerip
))) 
  59          #We have saved important data successfully 
  61             if not WriteInt32ToMemoryAddress(port
, int(addressof(pkt
.port
))): 
  63         if WriteInt32ToMemoryAddress(1, input_address
): 
  67 @lldb_command('sendcore') 
  68 def KDPSendCore(cmd_args
=None): 
  69     """  Configure kernel to send a coredump to the specified IP 
  70     Syntax: sendcore <IP address> [filename] 
  71     Configure the kernel to transmit a kernel coredump to a server (kdumpd)  
  72     at the specified IP address. This is useful when the remote target has 
  73     not been previously configured to transmit coredumps, and you wish to 
  74     preserve kernel state for later examination. NOTE: You must issue a "continue" 
  75     command after using this macro to trigger the kernel coredump. The kernel 
  76     will resume waiting in the debugger after completion of the coredump. You 
  77     may disable coredumps by executing the "disablecore" macro. You can  
  78     optionally specify the filename to be used for the generated core file. 
  81     if cmd_args 
== None or len(cmd_args
) < 1: 
  82         print KDPSendCore
.__doc
__ 
  84     ip_address 
= cmd_args
[0] 
  87         filename 
= cmd_args
[1].strip() 
  88     retval 
= KDPDumpInfo(GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_CORE'), file_name
=filename
, dest_ip
=ip_address
) 
  90         print "Remote system has been setup for coredump. Please detach/continue the system. " 
  93         print "Something went wrong. Failed to setup the coredump on the target." 
  97 @lldb_command('sendsyslog') 
  98 def KDPSendSyslog(cmd_args
=None): 
  99     """ Configure kernel to send a system log to the specified IP 
 100         Syntax: sendsyslog <IP address> [filename] 
 101         Configure the kernel to transmit a kernel system log to a server (kdumpd)  
 102         at the specified IP address. NOTE: You must issue a "continue" 
 103         command after using this macro to trigger the kernel system log. The kernel 
 104         will resume waiting in the debugger after completion. You can optionally 
 105         specify the name to be used for the generated system log. 
 107     if cmd_args 
== None or len(cmd_args
) < 1: 
 108         print KDPSendSyslog
.__doc
__ 
 110     ip_address 
= cmd_args
[0] 
 112     if len(cmd_args
) >=2: 
 113         filename 
= cmd_args
[1].strip() 
 114     retval 
= KDPDumpInfo(GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_SYSTEMLOG'), file_name 
= filename
, dest_ip 
= ip_address
) 
 116         print "Remote system has been setup to send system log. please detach/continue the system." 
 119         print "Something went wrong. Failed to setup the systemlog on the target." 
 122 @lldb_command('sendpaniclog') 
 123 def KDPSendPaniclog(cmd_args
=None): 
 124     """ Configure kernel to send a panic log to the specified IP 
 125         Syntax: sendpaniclog <IP address> [filename] 
 126         Configure the kernel to transmit a kernel paniclog to a server (kdumpd)  
 127         at the specified IP address. NOTE: You must issue a "continue" 
 128         command after using this macro to trigger the kernel panic log. The kernel 
 129         will resume waiting in the debugger after completion. You can optionally 
 130         specify the name to be used for the generated panic log. 
 132     if cmd_args 
== None or len(cmd_args
) < 1: 
 133         print KDPSendPaniclog
.__doc
__ 
 135     ip_address 
= cmd_args
[0] 
 137     if len(cmd_args
) >=2: 
 138         filename 
= cmd_args
[1].strip() 
 139     retval 
= KDPDumpInfo(GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_PANICLOG'), file_name 
= filename
, dest_ip 
= ip_address
) 
 141         print "Remote system has been setup to send panic log. please detach/continue the system." 
 144         print "Something went wrong. Failed to setup the paniclog on the target." 
 148 @lldb_command('disablecore') 
 149 def KDPDisableCore(cmd_args
=None): 
 150     """ Configure the kernel to disable coredump transmission 
 151         Reconfigures the kernel so that it no longer transmits kernel coredumps. This 
 152         complements the "sendcore" macro, but it may be used if the kernel has been 
 153         configured to transmit coredumps through boot-args as well. 
 156     retval 
= KDPDumpInfo(GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_DISABLE')) 
 158         print "Disabled coredump functionality on remote system." 
 160         print "Failed to disable coredump functionality." 
 163 @lldb_command('resume_on') 
 164 def KDPResumeON(cmd_args
=None): 
 165     """ The target system will resume when detaching  or exiting from lldb.  
 166         This is the default behavior. 
 168     subcmd 
= GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_SETINFO') | 
GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_RESUME')  
 169     retval 
= KDPDumpInfo(subcmd
) 
 171         print "Target system will resume on detaching from lldb." 
 173         print "Failed to enable resume functionality." 
 176 @lldb_command('resume_off') 
 177 def KDPResumeON(cmd_args
=None): 
 178     """ The target system will not resume when detaching  or exiting from lldb.  
 180     subcmd 
= GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_SETINFO') | 
GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_NORESUME')  
 181     retval 
= KDPDumpInfo(subcmd
) 
 183         print "Target system will not resume on detaching from lldb." 
 185         print "Failed to disable resume functionality." 
 190 @lldb_command('getdumpinfo') 
 191 def KDPGetDumpInfo(cmd_args
=None): 
 192     """ Retrieve the current remote dump settings. 
 194     if not KDPDumpInfo(GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_GETINFO')): 
 195         print "Failed to get dump settings." 
 197     dumpinfo 
= Cast(addressof(kern
.globals.manual_pkt
.data
), 'kdp_dumpinfo_reply_t *') 
 198     target_dump_type 
= int(dumpinfo
.type) 
 199     if target_dump_type 
& GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_REBOOT'): 
 200         print "System will reboot after kernel info gets dumped." 
 202         print "System will not reboot after kernel info gets dumped." 
 203     if target_dump_type 
& GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_RESUME'): 
 204         print "System will allow a re-attach after KDP disconnect." 
 206         print "System will not allow a re-attach after KDP disconnect." 
 207     target_dump_type 
= target_dump_type 
& GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_MASK') 
 208     if target_dump_type 
== GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_DISABLE'): 
 209         print "Kernel not setup for remote dumps." 
 212         if target_dump_type 
== GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_CORE'): 
 213             kern_dump_type 
= "Core File" 
 214         elif target_dump_type 
== GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_PANICLOG'): 
 215             kern_dump_type 
= "Panic Log" 
 216         elif target_dump_type 
== GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_SYSTEMLOG'): 
 217             kern_dump_type 
= "System Log" 
 218         print "Kernel dump type:" + kern_dump_type
 
 219         fname 
= "(autogenerated)" 
 220         if int(dumpinfo
.name
[0]) != 0: 
 221             fname 
= str(dumpinfo
.name
) 
 222         print "Filename: " + fname
 
 223         print "Network Info: {:s} [{:d}] , Router: {:s}".format(dumpinfo
.destip
, dumpinfo
.port
, dumpinfo
.routerip
) 
 224     # end of get dump info 
 227 @lldb_command('kdp-reenter') 
 228 def KDPReenter(cmd_args
=None): 
 229     """ Schedules reentry into the debugger  
 230         after <seconds> seconds, and resumes the target. 
 231         usage: kdp-reenter <seconds> 
 233     if len(cmd_args
) < 1: 
 234         print "Please provide valid time in seconds" 
 235         print KDPReenter
.__doc
__ 
 238     if "kdp" != GetConnectionProtocol(): 
 239         print "Target is not connected over kdp. Nothing to do here." 
 242     num_seconds 
= ArgumentStringToInt(cmd_args
[0]) 
 243     milliseconds_to_sleep 
= num_seconds 
* 1000 
 244     if WriteInt32ToMemoryAddress(milliseconds_to_sleep
, addressof(kern
.globals.kdp_reentry_deadline
)): 
 245         lldb
.debugger
.HandleCommand('process continue') 
 247     print "Failed to setup kdp-reentry." 
 250 @lldb_command('kdp-reboot') 
 251 def KDPReboot(cmd_args
=None): 
 252     """ Restart the remote target 
 254     if "kdp" != GetConnectionProtocol(): 
 255         print "Target is not connected over kdp. Nothing to do here." 
 258     print "Rebooting the remote machine." 
 259     lldb
.debugger
.HandleCommand('process plugin packet send --command 0x13') 
 260     lldb
.debugger
.HandleCommand('detach') 
 263 @lldb_command('setdumpinfo') 
 264 def KDPSetDumpInfo(cmd_args
=None): 
 265     """ Configure the current remote dump settings.  
 266         Specify "" if you want to use the defaults (filename) or previously configured 
 267         settings (ip/router). Specify 0 for the port if you wish to  
 268         use the previously configured/default setting for that. 
 269         Syntax: setdumpinfo <filename> <ip> <router> <port> 
 272         print KDPSetDumpInfo
.__doc
__ 
 274     if len(cmd_args
) < 4: 
 275         print "Not enough arguments." 
 276         print KDPSetDumpInfo
.__doc
__ 
 278     portnum 
= ArgumentStringToInt(cmd_args
[3]) 
 279     retval 
= KDPDumpInfo(GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_SETINFO'), cmd_args
[0], cmd_args
[1], cmd_args
[2], portnum
) 
 281         print "Successfully saved the dumpinfo." 
 283         print "Failed to save the dumpinfo."