1""" Please make sure you read the README file COMPLETELY BEFORE reading anything below. 2 It is very critical that you read coding guidelines in Section E in README file. 3""" 4from xnu import * 5import sys, shlex 6from utils import * 7from process import * 8from atm import * 9from bank import * 10import xnudefines 11 12@header("{0: <20s} {1: <6s} {2: <6s} {3: <10s} {4: <15s}".format("task", "pid", '#acts', "tablesize", "command")) 13def GetTaskIPCSummary(task): 14 """ Display a task's ipc summary. 15 params: 16 task : core.value represeting a Task in kernel 17 returns 18 str - string of ipc info for the task 19 """ 20 out_string = '' 21 format_string = "{0: <#020x} {1: <6d} {2: <6d} {3: <10d} {4: <15s}" 22 pval = Cast(task.bsd_info, 'proc *') 23 table_size = int(task.itk_space.is_table_size) 24 proc_name = str(pval.p_comm) 25 out_string += format_string.format(task, pval.p_pid, task.thread_count, table_size, proc_name) 26 return out_string 27 28@header("{0: <20s} {1: <28s} {2: <12s} {3: <6s} {4: <4s} {5: <20s} {6: <4s}\n".format( 29 "port", "mqueue", "recvname", "flags", "refs", "recvname", "dest")) 30def GetPortSummary(port, show_kmsg_summary=True, prefix=""): 31 """ Display a port's summary 32 params: 33 port : core.value representing a port in the kernel 34 returns 35 str : string of ipc info for the given port 36 """ 37 out_string = "" 38 portp = Cast(port, 'struct ipc_port *') 39 destspacep = kern.GetValueFromAddress(0, 'struct ipc_space *') 40 spacep = portp.data.receiver 41 format_string = "{0: #019x} {1: #019x} {2: <8s} {3: #011x} {4: <5s} {5: #05x} {6: #019x} {7: <16s}\n" 42 if portp.ip_object.io_bits & 0x80000000: 43 out_string += prefix + format_string.format( 44 unsigned(portp), addressof(portp.ip_messages), ' '*8, 45 unsigned(portp.ip_messages.data.port.receiver_name), 46 "APort", portp.ip_object.io_references, 47 unsigned(portp.ip_messages.data.port.receiver_name), 48 GetPortDestProc(portp)) 49 else: 50 out_string += prefix + format_string.format( 51 unsigned(portp), addressof(portp.ip_messages), ' '*8, 52 unsigned(portp.ip_messages.data.port.receiver_name), 53 "DPort", portp.ip_object.io_references, unsigned(portp), 54 "inactive-port") 55 56 if show_kmsg_summary: 57 kmsgp = Cast(portp.ip_messages.data.port.messages.ikmq_base, 'ipc_kmsg_t') 58 out_string += prefix + GetKMsgSummary.header + prefix + GetKMsgSummary(kmsgp) 59 60 kmsgheadp = kmsgp 61 kmsgp = kmsgp.ikm_next 62 while (kmsgp) != (kmsgheadp): 63 out_string += prefix + GetKMsgSummary(kmsgp) 64 kmsgp = kmsgp.ikm_next 65 return out_string 66 67def GetPortDestProc(portp): 68 """ Display the name and pid of a given port's receiver 69 params: 70 portp : core.value representing a pointer to a port in the kernel 71 destspacep : core.value representing a pointer to an ipc_space 72 returns: 73 str : string containing receiver's name and pid 74 """ 75 spacep = portp.data.receiver 76 out_str = "Not found" 77 for tsk in kern.tasks: 78 if tsk.itk_space == spacep: 79 if tsk.bsd_info: 80 destprocp = Cast(tsk.bsd_info, 'struct proc *') 81 out_str = "{0:s}({1: <d})".format(destprocp.p_comm, destprocp.p_pid) 82 else: 83 out_str = "unknown" 84 break 85 86 return out_str 87 88@header("{0: <20s} {1: <28s} {2: <12s} {3: <6s} {4: <6s} {5: <19s} {6: <26s} {7: <26s}\n".format( 89 "dest-port", "kmsg", "msgid", "disp", "size", "reply-port", "source", "destination")) 90def GetKMsgSummary(kmsgp): 91 """ Display a summary for type ipc_kmsg_t 92 params: 93 kmsgp : core.value representing the given ipc_kmsg_t struct 94 returns: 95 str : string of summary info for the given ipc_kmsg_t instance 96 """ 97 kmsghp = kmsgp.ikm_header 98 kmsgh = dereference(kmsghp) 99 out_string = "" 100 out_string += "{0: <19s} {1: <#019x} {2: <8s} {3: <#011x} ".format( 101 ' '*19, unsigned(kmsgp), ' '*8, kmsgh.msgh_id) 102 103 if (kmsgh.msgh_bits & 0xff) == 17: 104 out_string += "{0: <2s}".format("rS") 105 else: 106 out_string += "{0: <2s}".format("rO") 107 108 if (kmsgh.msgh_bits & 0xff00) == (17 << 8): 109 out_string += "{0: <2s}".format("lS") 110 else: 111 if (kmsgh.msgh_bits & 0xff00) == (18 << 8): 112 out_string += "{0: <2s}".format("lO") 113 else: 114 out_string += "{0: <2s}".format("l-") 115 if kmsgh.msgh_bits & 0xf0000000: 116 out_string += "{0: <2s}".format("c") 117 else: 118 out_string += "{0: <2s}".format("s") 119 120 dest_proc_name = "" 121 if kmsgp.ikm_header.msgh_remote_port: 122 dest_proc_name = GetDestinationProcessFromPort(kmsgp.ikm_header.msgh_remote_port) 123 124 out_string += "{0: ^6d} {1: <#019x} {2: <26s} {3: <26s}\n".format( 125 unsigned(kmsgh.msgh_size), unsigned(kmsgh.msgh_local_port), 126 GetKMsgSrc(kmsgp), dest_proc_name) 127 return out_string 128 129def GetKMsgSrc(kmsgp): 130 """ Routine that prints a kmsg's source process and pid details 131 params: 132 kmsgp : core.value representing the given ipc_kmsg_t struct 133 returns: 134 str : string containing the name and pid of the kmsg's source proc 135 """ 136 kmsgsrchp = Cast(kmsgp, 'ipc_kmsg_t').ikm_header 137 kmsgpid = int(Cast(kern.GetValueFromAddress(unsigned(kmsgsrchp) + kmsgsrchp.msgh_size, 'uint *')[10], 'pid_t')) 138 139 return "{0:s} ({1:d})".format(GetProcNameForPid(kmsgpid), kmsgpid) 140 141@header("{0: <20s} {1: <28s} {2: <12s} {3: <6s} {4: <6s} {5: <20s} {6: <7s}\n".format( 142 "portset", "waitqueue", "recvname", "flags", "refs", "recvname", "process")) 143def GetPortSetSummary(pset): 144 """ Display summary for a given struct ipc_pset * 145 params: 146 pset : core.value representing a pset in the kernel 147 returns: 148 str : string of summary information for the given pset 149 """ 150 out_str = "" 151 if pset.ips_object.io_bits & 0x80000000: 152 out_str += "{0: #019x} {1: #019x} {2: <7s} {3: #011x} {4: <4s} {5: >6d} {6: #019x} ".format( 153 unsigned(pset), addressof(pset.ips_messages), ' '*7, 154 pset.ips_messages.data.pset.local_name, "ASet", 155 pset.ips_object.io_references, 156 pset.ips_messages.data.pset.local_name) 157 158 else: 159 out_str += "{0: #019x} {1: #019x} {2: <7s} {3: #011x} {4: <4s} {5: >6d} {6: #019x} ".format( 160 unsigned(pset), addressof(pset.ips_messages), ' '*7, 161 pset.ips_messages.data.pset.local_name, "DSet", 162 pset.ips_object.io_references, 163 pset.ips_messages.data.pset.local_name) 164 165 once = True 166 setlinksp = addressof(pset.ips_messages.data.pset.set_queue.wqs_setlinks) 167 wql = Cast(pset.ips_messages.data.pset.set_queue.wqs_setlinks.next, 'WaitQueueLink *') 168 portoff = getfieldoffset('struct ipc_port', 'ip_messages') 169 prefix_str = "{0:<21s}".format(' '*21) 170 while unsigned(wql) != unsigned(Cast(setlinksp, 'void *')): 171 portp = kern.GetValueFromAddress(unsigned(wql.wql_element.wqe_queue) - portoff, 'ipc_port *') 172 if once: 173 once = False 174 out_str += "{0:s}\n{1:s}{2:s}".format(GetPortDestProc(portp), prefix_str, GetPortSummary.header) 175 out_str += GetPortSummary(portp, False, prefix_str) 176 wql = Cast(wql.wql_setlinks.next, 'WaitQueueLink *') 177 return out_str 178 179# Macro: showipc 180 181@lldb_command('showipc') 182def ShowIPC(cmd_args=None): 183 """ Routine to print data for the given IPC space 184 Usage: showipc <address of ipc space> 185 """ 186 if not cmd_args: 187 print "No arguments passed" 188 print ShowIPC.__doc__ 189 return False 190 ipc = kern.GetValueFromAddress(cmd_args[0], 'ipc_space *') 191 if not ipc: 192 print "unknown arguments:", str(cmd_args) 193 return False 194 print GetIPCInformation.header 195 print GetIPCInformation(ipc, False, False) 196 197# EndMacro: showipc 198 199# Macro: showtaskipc 200 201@lldb_command('showtaskipc') 202def ShowTaskIPC(cmd_args=None): 203 """ Routine to print IPC summary of given task 204 Usage: showtaskipc <address of task> 205 """ 206 if not cmd_args: 207 print "No arguments passed" 208 print ShowTaskIPC.__doc__ 209 return False 210 tval = kern.GetValueFromAddress(cmd_args[0], 'task *') 211 if not tval: 212 print "unknown arguments:", str(cmd_args) 213 return False 214 print GetTaskSummary.header + " " + GetProcSummary.header 215 pval = Cast(tval.bsd_info, 'proc *') 216 print GetTaskSummary(tval) + " " + GetProcSummary(pval) 217 print GetTaskIPCSummary.header 218 print GetTaskIPCSummary(tval) 219 220# EndMacro: showtaskipc 221 222# Macro: showallipc 223 224@lldb_command('showallipc') 225def ShowAllIPC(cmd_args=None): 226 """ Routine to print IPC summary of all tasks 227 Usage: showallipc 228 """ 229 for t in kern.tasks: 230 print GetTaskSummary.header + " " + GetProcSummary.header 231 pval = Cast(t.bsd_info, 'proc *') 232 print GetTaskSummary(t) + " " + GetProcSummary(pval) 233 print GetIPCInformation.header 234 print GetIPCInformation(t.itk_space, False, False) + "\n\n" 235 236# EndMacro: showallipc 237 238@lldb_command('showipcsummary') 239def ShowIPCSummary(cmd_args=None): 240 """ Summarizes the IPC state of all tasks. 241 This is a convenient way to dump some basic clues about IPC messaging. You can use the output to determine 242 tasks that are candidates for further investigation. 243 """ 244 print GetTaskIPCSummary.header 245 for t in kern.tasks: 246 print GetTaskIPCSummary(t) 247 return 248 249def GetKObjectFromPort(portval): 250 """ Get Kobject description from the port. 251 params: portval - core.value representation of 'ipc_port *' object 252 returns: str - string of kobject information 253 """ 254 kobject_str = "{0: <#020x}".format(portval.kdata.kobject) 255 io_bits = unsigned(portval.ip_object.io_bits) 256 objtype_index = io_bits & 0xfff 257 if objtype_index < len(xnudefines.kobject_types) : 258 desc_str = "kobject({0:s})".format(xnudefines.kobject_types[objtype_index]) 259 if xnudefines.kobject_types[objtype_index] in ('TASK_RESUME', 'TASK'): 260 desc_str += " " + GetProcNameForTask(Cast(portval.kdata.kobject, 'task *')) 261 else: 262 desc_str = "kobject(UNKNOWN) {:d}".format(objtype_index) 263 return kobject_str + " " + desc_str 264 265@static_var('destcache', {}) 266def GetDestinationProcessFromPort(port): 267 """ 268 params: port - core.value representation of 'ipc_port *' object 269 returns: str - name of process 270 """ 271 out_str = '' 272 dest_space = port.data.receiver 273 found_dest = False 274 #update destcache if data is not found 275 if hex(dest_space) not in GetDestinationProcessFromPort.destcache: 276 for t in kern.tasks: 277 if hex(t.itk_space) == hex(dest_space): 278 pval = Cast(t.bsd_info, 'proc *') 279 GetDestinationProcessFromPort.destcache[hex(dest_space)] = (t, pval) 280 found_dest = True 281 break 282 #end of for loop 283 else: found_dest = True 284 285 if found_dest: 286 (ftask , fproc) = GetDestinationProcessFromPort.destcache[hex(dest_space)] 287 if fproc: 288 out_str = "{0:s}({1:d})".format(fproc.p_comm, fproc.p_pid ) 289 else: 290 out_str = "task {0: <#020x}".format(ftask) 291 return out_str 292 293 294 295@header("{0: <20s} {1: <20s}".format("destname", "destination") ) 296def GetPortDestinationSummary(port): 297 """ Get destination information for a port. 298 params: port - core.value representation of 'ipc_port *' object 299 returns: str - string of info about ports destination 300 """ 301 out_str = '' 302 format_string = "{0: <20s} {1: <20s}" 303 destname_str = '' 304 destination_str = '' 305 ipc_space_kernel = unsigned(kern.globals.ipc_space_kernel) 306 target_spaceval = port.data.receiver 307 if unsigned(target_spaceval) == ipc_space_kernel : 308 destname_str = GetKObjectFromPort(port) 309 else: 310 if int(port.ip_object.io_bits) & 0x80000000 : 311 destname_str = "{0: <#020x}".format(port.ip_messages.data.port.receiver_name) 312 destination_str = GetDestinationProcessFromPort(port) 313 else: 314 destname_str = "{0: <#020x}".format(port) 315 destination_str = "inactive-port" 316 317 out_str += format_string.format(destname_str, destination_str) 318 return out_str 319 320@lldb_type_summary(['ipc_entry_t']) 321@header("{0: <20s} {1: <20s} {2: <8s} {3: <8s} {4: <20s} {5: <20s}".format("object", "name","rite", "urefs", "destname", "destination")) 322def GetIPCEntrySummary(entry, ipc_name=''): 323 """ Get summary of a ipc entry. 324 params: 325 entry - core.value representing ipc_entry_t in the kernel 326 ipc_name - str of format '0x0123' for display in summary. 327 returns: 328 str - string of ipc entry related information 329 """ 330 out_str = '' 331 entry_ptr = int(hex(entry), 16) 332 format_string = "{0: <#020x} {1: <12s} {2: <8s} {3: <8d} {4: <20s} {5: <20s}" 333 right_str = '' 334 destname_str = '' 335 destination_str = '' 336 337 ie_object = entry.ie_object 338 ie_bits = int(entry.ie_bits) 339 urefs = int(ie_bits & 0xffff) 340 if ie_bits & 0x00100000 : 341 right_str = 'Dead' 342 elif ie_bits & 0x00080000: 343 right_str = 'Set' 344 else: 345 if ie_bits & 0x00010000 : 346 if ie_bits & 0x00020000 : 347 right_str = 'SR' 348 else: 349 right_str = 'S' 350 elif ie_bits & 0x00020000: 351 right_str = 'R' 352 elif ie_bits & 0x00040000 : 353 right_str = 'O' 354 portval = Cast(ie_object, 'ipc_port_t') 355 if int(entry.index.request) != 0: 356 requestsval = portval.ip_requests 357 sorightval = requestsval[int(entry.index.request)].notify.port 358 soright_ptr = unsigned(sorightval) 359 if soright_ptr != 0: 360 if soright_ptr & 0x1 : right_str +='s' 361 elif soright_ptr & 0x2 : right_str +='d' 362 else : right_str +='n' 363 if ie_bits & 0x00800000 : right_str +='c' 364 if portval.ip_nsrequest != 0: right_str +='x' 365 # now show the port destination part 366 destname_str = GetPortDestinationSummary(Cast(ie_object, 'ipc_port_t')) 367 368 out_str = format_string.format(ie_object, ipc_name, right_str, urefs, destname_str, destination_str) 369 return out_str 370 371@header("{0: >20s}".format("user bt") ) 372def GetPortUserStack(port, task): 373 """ Get UserStack information for the given port & task. 374 params: port - core.value representation of 'ipc_port *' object 375 task - value representing 'task *' object 376 returns: str - string information on port's userstack 377 """ 378 out_str = '' 379 ie_port_callstack = port.ip_callstack 380 ie_port_spares = port.ip_spares[0] 381 proc_val = Cast(task.bsd_info, 'proc *') 382 if ie_port_callstack[0]: 383 out_str += "{: <10x}".format(ie_port_callstack[0]) 384 count = 1 385 while count < 16 and ie_port_callstack[count]: 386 out_str += ": <10x".format(ie_port_callstack[count]) 387 count = count + 1 388 if ie_port_spares != proc_val.p_pid: 389 out_str += " ({:<10d})".format(ie_port_spares) 390 out_str += '\n' 391 return out_str 392 393@lldb_type_summary(['ipc_space *']) 394@header("{0: <20s} {1: <20s} {2: <20s} {3: <8s} {4: <10s} {5: <16s} {6: <10s} {7: <7s}".format('ipc_space', 'is_task', 'is_table', 'flags', 'ports', 'table_next', 'low_mod', 'high_mod')) 395def GetIPCInformation(space, show_entries=False, show_userstack=False): 396 """ Provide a summary of the ipc space 397 """ 398 out_str = '' 399 format_string = "{0: <#020x} {1: <#020x} {2: <#020x} {3: <8s} {4: <10d} {5: <#01x} {6: >10d} {7: >10d}" 400 is_tableval = space.is_table 401 ports = int(space.is_table_size) 402 flags ='' 403 is_bits = int(space.is_bits) 404 if (is_bits & 0x40000000) == 0: flags +='A' 405 else: flags += ' ' 406 if (is_bits & 0x20000000) != 0: flags +='G' 407 out_str += format_string.format(space, space.is_task, space.is_table, flags, space.is_table_size, space.is_table_next, space.is_low_mod, space.is_high_mod) 408 409 #should show the each individual entries if asked. 410 if show_entries == True: 411 out_str += "\n\t" + GetIPCEntrySummary.header + "\n" 412 num_entries = ports 413 index = 0 414 while index < num_entries: 415 entryval = GetObjectAtIndexFromArray(is_tableval, index) 416 entry_ie_bits = unsigned(entryval.ie_bits) 417 if (int(entry_ie_bits) & 0x001f0000 ) != 0: 418 entry_name = "{0: <#020x}".format( (index <<8 | entry_ie_bits >> 24) ) 419 out_str += "\t" + GetIPCEntrySummary(entryval, entry_name) + "\n" 420 if show_userstack == True: 421 entryport = Cast(entryval.ie_object, 'ipc_port *') 422 if entryval.ie_object and (int(entry_ie_bits) & 0x00070000) and entryport.ip_callstack[0]: 423 out_str += GetPortUserStack.header 424 out_str += GetPortUserStack(entryport, space.is_task) 425 index +=1 426 #done with showing entries 427 return out_str 428 429# Macro: showrights 430 431@lldb_command('showrights') 432def ShowRights(cmd_args=None): 433 """ Routine to print rights information for the given IPC space 434 Usage: showrights <address of ipc space> 435 """ 436 if not cmd_args: 437 print "No arguments passed" 438 print ShowRights.__doc__ 439 return False 440 ipc = kern.GetValueFromAddress(cmd_args[0], 'ipc_space *') 441 if not ipc: 442 print "unknown arguments:", str(cmd_args) 443 return False 444 print GetIPCInformation.header 445 print GetIPCInformation(ipc, True, False) 446 447# EndMacro: showrights 448 449@lldb_command('showtaskrights') 450def ShowTaskRights(cmd_args=None): 451 """ Routine to ipc rights information for a task 452 Usage: showtaskrights <task address> 453 """ 454 if cmd_args == None: 455 print "No arguments passed" 456 print ShowTaskStacksCmdHelper.__doc__ 457 return False 458 tval = kern.GetValueFromAddress(cmd_args[0], 'task *') 459 if not tval: 460 print "unknown arguments:", str(cmd_args) 461 return False 462 print GetTaskSummary.header + " " + GetProcSummary.header 463 pval = Cast(tval.bsd_info, 'proc *') 464 print GetTaskSummary(tval) + " " + GetProcSummary(pval) 465 print GetIPCInformation.header 466 print GetIPCInformation(tval.itk_space, True, False) 467 468# Macro: showataskrightsbt 469 470@lldb_command('showtaskrightsbt') 471def ShowTaskRightsBt(cmd_args=None): 472 """ Routine to ipc rights information with userstacks for a task 473 Usage: showtaskrightsbt <task address> 474 """ 475 if cmd_args == None: 476 print "No arguments passed" 477 print ShowTaskRightsBt.__doc__ 478 return False 479 tval = kern.GetValueFromAddress(cmd_args[0], 'task *') 480 if not tval: 481 print "unknown arguments:", str(cmd_args) 482 return False 483 print GetTaskSummary.header + " " + GetProcSummary.header 484 pval = Cast(tval.bsd_info, 'proc *') 485 print GetTaskSummary(tval) + " " + GetProcSummary(pval) 486 print GetIPCInformation.header 487 print GetIPCInformation(tval.itk_space, True, True) 488 489# EndMacro: showtaskrightsbt 490 491# Macro: showallrights 492 493@lldb_command('showallrights') 494def ShowAllRights(cmd_args=None): 495 """ Routine to print rights information for IPC space of all tasks 496 Usage: showallrights 497 """ 498 for t in kern.tasks: 499 print GetTaskSummary.header + " " + GetProcSummary.header 500 pval = Cast(t.bsd_info, 'proc *') 501 print GetTaskSummary(t) + " " + GetProcSummary(pval) 502 try: 503 print GetIPCInformation.header 504 print GetIPCInformation(t.itk_space, True, False) + "\n\n" 505 except (KeyboardInterrupt, SystemExit): 506 raise 507 except: 508 print "Failed to get IPC information. Do individual showtaskrights <task> to find the error. \n\n" 509 510# EndMacro: showallrights 511 512# Macro: showpipestats 513@lldb_command('showpipestats') 514def ShowPipeStats(cmd_args=None): 515 """ Display pipes usage information in the kernel 516 """ 517 print "Number of pipes: {: d}".format(kern.globals.amountpipes) 518 print "Memory used by pipes: {:s}".format(sizeof_fmt(int(kern.globals.amountpipekva))) 519 print "Max memory allowed for pipes: {:s}".format(sizeof_fmt(int(kern.globals.maxpipekva))) 520# EndMacro: showpipestats 521 522# Macro: showtaskbusyports 523@lldb_command('showtaskbusyports') 524def ShowTaskBusyPorts(cmd_args=None): 525 """ Routine to print information about receive rights belonging to this task that 526 have enqueued messages. This is oten a sign of a blocked or hung process 527 Usage: showtaskbusyports <task address> 528 """ 529 if not cmd_args: 530 print "No arguments passed. Please pass in the address of a task" 531 print ShowTaskBusyPorts.__doc__ 532 return 533 task = kern.GetValueFromAddress(cmd_args[0], 'task_t') 534 print GetTaskBusyPorts(task) 535 return 536 537def GetTaskBusyPorts(task): 538 """ Prints all busy ports for a given task. ie. all receive rights belonging 539 to this task that have enqueued messages. 540 params: 541 task : core.value representing a task in kernel 542 returns: 543 str : String containing information about the given task's busy ports 544 """ 545 isp = task.itk_space 546 i = 0 547 out_string = "" 548 while i < isp.is_table_size: 549 iep = addressof(isp.is_table[i]) 550 if iep.ie_bits & 0x00020000: 551 port = Cast(iep.ie_object, 'ipc_port_t') 552 if port.ip_messages.data.port.msgcount > 0: 553 out_string += GetPortSummary.header + GetPortSummary(port) 554 i = i + 1 555 return out_string 556# EndMacro: showtaskbusyports 557 558# Macro: showallbusyports 559@lldb_command('showallbusyports') 560def ShowAllBusyPorts(cmd_args=None): 561 """ Routine to print information about all receive rights on the system that 562 have enqueued messages. 563 """ 564 task_queue_head = kern.globals.tasks 565 566 for tsk in kern.tasks: 567 print GetTaskBusyPorts(tsk) 568 return 569# EndMacro: showallbusyports 570 571# Macro: showmqueue: 572@lldb_command('showmqueue') 573def ShowMQueue(cmd_args=None): 574 """ Routine that lists details about a given mqueue 575 Syntax: (lldb) showmqueue 0xaddr 576 """ 577 if not cmd_args: 578 print "Please specify the address of the ipc_mqueue whose details you want to print" 579 print ShowMQueue.__doc__ 580 return 581 mqueue = kern.GetValueFromAddress(cmd_args[0], 'struct ipc_mqueue *') 582 wq_type = mqueue.data.pset.set_queue.wqs_wait_queue.wq_type 583 if int(wq_type) == 3: 584 psetoff = getfieldoffset('struct ipc_pset', 'ips_messages') 585 pset = unsigned(ArgumentStringToInt(cmd_args[0])) - unsigned(psetoff) 586 print GetPortSetSummary.header + GetPortSetSummary(kern.GetValueFromAddress(pset, 'struct ipc_pset *')) 587 if int(wq_type) == 2: 588 portoff = getfieldoffset('struct ipc_port', 'ip_messages') 589 port = unsigned(ArgumentStringToInt(cmd_args[0])) - unsigned(portoff) 590 print GetPortSummary.header + GetPortSummary(kern.GetValueFromAddress(port, 'struct ipc_port *')) 591# EndMacro: showmqueue 592 593# Macro: showkmsg: 594@lldb_command('showkmsg') 595def ShowKMSG(cmd_args=[]): 596 """ Show detail information about a <ipc_kmsg_t> structure 597 Usage: (lldb) showkmsg <ipc_kmsg_t> 598 """ 599 if not cmd_args: 600 raise ArgumentError('Invalid arguments') 601 kmsg = kern.GetValueFromAddress(cmd_args[0], 'ipc_kmsg_t') 602 print GetKMsgSummary.header 603 print GetKMsgSummary(kmsg) 604 605# EndMacro: showkmsg 606 607# Macro: showpset 608@lldb_command('showpset') 609def ShowPSet(cmd_args=None): 610 """ Routine that prints details for a given ipc_pset * 611 Syntax: (lldb) showpset 0xaddr 612 """ 613 if not cmd_args: 614 print "Please specify the address of the pset whose details you want to print" 615 print ShowPSet.__doc__ 616 return 617 618 print GetPortSetSummary.header + GetPortSetSummary(kern.GetValueFromAddress(cmd_args[0], 'ipc_pset *')) 619# EndMacro: showpset 620 621# IPC importance inheritance related macros. 622 623@lldb_command('showalliits') 624def ShowAllIITs(cmd_args=[], cmd_options={}): 625 """ Development only macro. Show list of all iits allocated in the system. """ 626 try: 627 iit_queue = kern.globals.global_iit_alloc_queue 628 except ValueError: 629 print "This debug macro is only available in development or debug kernels" 630 return 631 632 print GetIPCImportantTaskSummary.header 633 for iit in IterateQueue(iit_queue, 'struct ipc_importance_task *', 'iit_allocation'): 634 print GetIPCImportantTaskSummary(iit) 635 return 636 637@header("{: <18s} {: <3s} {: <18s} {: <20s} {: <18s} {: <8s}".format("ipc_imp_inherit", "don", "to_task", "proc_name", "from_elem", "depth")) 638@lldb_type_summary(['ipc_importance_inherit *', 'ipc_importance_inherit_t']) 639def GetIPCImportanceInheritSummary(iii): 640 """ describes iii object of type ipc_importance_inherit_t * """ 641 out_str = "" 642 fmt = "{o: <#018x} {don: <3s} {o.iii_to_task.iit_task: <#018x} {task_name: <20s} {o.iii_from_elem: <#018x} {o.iii_depth: <#08x}" 643 donating_str = "" 644 if unsigned(iii.iii_donating): 645 donating_str = "DON" 646 taskname = GetProcNameForTask(iii.iii_to_task.iit_task) 647 if hasattr(iii.iii_to_task, 'iit_bsd_pid'): 648 taskname = "({:d}) {:s}".format(iii.iii_to_task.iit_bsd_pid, iii.iii_to_task.iit_procname) 649 out_str += fmt.format(o=iii, task_name = taskname, don=donating_str) 650 return out_str 651 652@static_var('recursion_count', 0) 653@header("{: <18s} {: <4s} {: <8s} {: <8s} {: <18s} {: <18s}".format("iie", "type", "refs", "made", "#kmsgs", "#inherits")) 654@lldb_type_summary(['ipc_importance_elem *']) 655def GetIPCImportanceElemSummary(iie): 656 """ describes an ipc_importance_elem * object """ 657 658 if GetIPCImportanceElemSummary.recursion_count > 500: 659 GetIPCImportanceElemSummary.recursion_count = 0 660 return "Recursion of 500 reached" 661 662 out_str = '' 663 fmt = "{: <#018x} {: <4s} {: <8d} {: <8d} {: <#018x} {: <#018x}" 664 type_str = 'TASK' 665 if unsigned(iie.iie_bits) & 0x80000000: 666 type_str = "INH" 667 refs = unsigned(iie.iie_bits) & 0x7fffffff 668 made_refs = unsigned(iie.iie_made) 669 kmsg_count = sum(1 for i in IterateQueue(iie.iie_kmsgs, 'struct ipc_kmsg *', 'ikm_inheritance')) 670 inherit_count = sum(1 for i in IterateQueue(iie.iie_inherits, 'struct ipc_importance_inherit *', 'iii_inheritance')) 671 out_str += fmt.format(iie, type_str, refs, made_refs, kmsg_count, inherit_count) 672 if config['verbosity'] > vHUMAN: 673 if kmsg_count > 0: 674 out_str += "\n\t"+ GetKMsgSummary.header 675 for k in IterateQueue(iie.iie_kmsgs, 'struct ipc_kmsg *', 'ikm_inheritance'): 676 out_str += "\t" + "{: <#018x}".format(k.ikm_header.msgh_remote_port) + ' ' + GetKMsgSummary(k).lstrip() 677 out_str += "\n" 678 if inherit_count > 0: 679 out_str += "\n\t" + GetIPCImportanceInheritSummary.header + "\n" 680 for i in IterateQueue(iie.iie_inherits, 'struct ipc_importance_inherit *', 'iii_inheritance'): 681 out_str += "\t" + GetIPCImportanceInheritSummary(i) + "\n" 682 out_str += "\n" 683 if type_str == "INH": 684 iii = Cast(iie, 'struct ipc_importance_inherit *') 685 out_str += "Inherit from: " + GetIPCImportanceElemSummary(iii.iii_from_elem) 686 687 return out_str 688 689@header("{: <18s} {: <18s} {: <20s}".format("iit", "task", "name")) 690@lldb_type_summary(['ipc_importance_task *']) 691def GetIPCImportantTaskSummary(iit): 692 """ iit is a ipc_importance_task value object. 693 """ 694 fmt = "{: <#018x} {: <#018x} {: <20s}" 695 out_str='' 696 pname = GetProcNameForTask(iit.iit_task) 697 if hasattr(iit, 'iit_bsd_pid'): 698 pname = "({:d}) {:s}".format(iit.iit_bsd_pid, iit.iit_procname) 699 out_str += fmt.format(iit, iit.iit_task, pname) 700 return out_str 701 702@lldb_command('showallimportancetasks') 703def ShowIPCImportanceTasks(cmd_args=[], cmd_options={}): 704 """ display a list of all tasks with ipc importance information. 705 Usage: (lldb) showallimportancetasks 706 Tip: add "-v" to see detailed information on each kmsg or inherit elems 707 """ 708 print ' ' + GetIPCImportantTaskSummary.header + ' ' + GetIPCImportanceElemSummary.header 709 for t in kern.tasks: 710 s = "" 711 if unsigned(t.task_imp_base): 712 s += ' ' + GetIPCImportantTaskSummary(t.task_imp_base) 713 s += ' ' + GetIPCImportanceElemSummary(addressof(t.task_imp_base.iit_elem)) 714 print s 715 716@lldb_command('showipcimportance', '') 717def ShowIPCImportance(cmd_args=[], cmd_options={}): 718 """ Describe an importance from <ipc_importance_elem_t> argument. 719 Usage: (lldb) showimportance <ipc_importance_elem_t> 720 """ 721 if not cmd_args: 722 raise ArgumentError("Please provide valid argument") 723 724 elem = kern.GetValueFromAddress(cmd_args[0], 'ipc_importance_elem_t') 725 print GetIPCImportanceElemSummary.header 726 print GetIPCImportanceElemSummary(elem) 727 728@header("{: <18s} {: <10s} {: <18s} {: <18s} {: <8s} {: <5s} {: <5s} {: <5s}".format("ivac", "refs", "port", "tbl", "tblsize", "index", "Grow", "freelist")) 729@lldb_type_summary(['ipc_voucher_attr_control *', 'ipc_voucher_attr_control_t']) 730def GetIPCVoucherAttrControlSummary(ivac): 731 """ describes a voucher attribute control settings """ 732 out_str = "" 733 fmt = "{c: <#018x} {c.ivac_refs: <10d} {c.ivac_port: <#018x} {c.ivac_table: <#018x} {c.ivac_table_size: <8d} {c.ivac_key_index: <5d} {growing: <5s} {c.ivac_freelist: <5d}" 734 growing_str = "" 735 736 if unsigned(ivac) == 0: 737 return "{: <#018x}".format(ivac) 738 739 if unsigned(ivac.ivac_is_growing): 740 growing_str = "Y" 741 out_str += fmt.format(c=ivac, growing = growing_str) 742 return out_str 743 744@lldb_command('showivac','') 745def ShowIPCVoucherAttributeControl(cmd_args=[], cmd_options={}): 746 """ Show summary of voucher attribute contols. 747 Usage: (lldb) showivac <ipc_voucher_attr_control_t> 748 """ 749 if not cmd_args: 750 raise ArgumentError("Please provide correct arguments.") 751 ivac = kern.GetValueFromAddress(cmd_args[0], 'ipc_voucher_attr_control_t') 752 print GetIPCVoucherAttrControlSummary.header 753 print GetIPCVoucherAttrControlSummary(ivac) 754 if config['verbosity'] > vHUMAN: 755 cur_entry_index = 0 756 last_entry_index = unsigned(ivac.ivac_table_size) 757 print "index " + GetIPCVoucherAttributeEntrySummary.header 758 while cur_entry_index < last_entry_index: 759 print "{: <5d} ".format(cur_entry_index) + GetIPCVoucherAttributeEntrySummary(addressof(ivac.ivac_table[cur_entry_index])) 760 cur_entry_index += 1 761 762 763 764 765@header("{: <18s} {: <30s} {: <30s} {: <30s} {: <30s} {: <30s}".format("ivam", "get_value_fn", "extract_fn", "release_value_fn", "command_fn", "release_fn")) 766@lldb_type_summary(['ipc_voucher_attr_manager *', 'ipc_voucher_attr_manager_t']) 767def GetIPCVoucherAttrManagerSummary(ivam): 768 """ describes a voucher attribute manager settings """ 769 out_str = "" 770 fmt = "{: <#018x} {: <30s} {: <30s} {: <30s} {: <30s} {: <30s}" 771 772 if unsigned(ivam) == 0 : 773 return "{: <#018x}".format(ivam) 774 775 get_value_fn = kern.Symbolicate(unsigned(ivam.ivam_get_value)) 776 extract_fn = kern.Symbolicate(unsigned(ivam.ivam_extract_content)) 777 release_value_fn = kern.Symbolicate(unsigned(ivam.ivam_release_value)) 778 command_fn = kern.Symbolicate(unsigned(ivam.ivam_command)) 779 release_fn = kern.Symbolicate(unsigned(ivam.ivam_release)) 780 out_str += fmt.format(ivam, get_value_fn, extract_fn, release_value_fn, command_fn, release_fn) 781 return out_str 782 783 784 785@header("{: <18s} {: <10s} {:s} {:s}".format("ivgte", "key", GetIPCVoucherAttrControlSummary.header.strip(), GetIPCVoucherAttrManagerSummary.header.strip())) 786@lldb_type_summary(['ipc_voucher_global_table_element *', 'ipc_voucher_global_table_element_t']) 787def GetIPCVoucherGlobalTableElementSummary(ivgte): 788 """ describes a ipc_voucher_global_table_element object """ 789 out_str = "" 790 fmt = "{g: <#018x} {g.ivgte_key: <10d} {ctrl_s:s} {mgr_s:s}" 791 out_str += fmt.format(g=ivgte, ctrl_s=GetIPCVoucherAttrControlSummary(ivgte.ivgte_control), mgr_s=GetIPCVoucherAttrManagerSummary(ivgte.ivgte_manager)) 792 return out_str 793 794@lldb_command('showglobalvouchertable', '') 795def ShowGlobalVoucherTable(cmd_args=[], cmd_options={}): 796 """ show detailed information of all voucher attribute managers registered with vouchers system 797 Usage: (lldb) showglobalvouchertable 798 """ 799 entry_size = sizeof(kern.globals.iv_global_table[0]) 800 elems = sizeof(kern.globals.iv_global_table) / entry_size 801 print GetIPCVoucherGlobalTableElementSummary.header 802 for i in range(elems): 803 elt = addressof(kern.globals.iv_global_table[i]) 804 print GetIPCVoucherGlobalTableElementSummary(elt) 805 806# Type summaries for Bag of Bits. 807 808@lldb_type_summary(['user_data_value_element', 'user_data_element_t']) 809@header("{0: <20s} {1: <16s} {2: <20s} {3: <20s} {4: <16s} {5: <20s}".format("user_data_ve", "maderefs", "checksum", "hash value", "size", "data")) 810def GetBagofBitsElementSummary(data_element): 811 """ Summarizes the Bag of Bits element 812 params: data_element = value of the object of type user_data_value_element_t 813 returns: String with summary of the type. 814 """ 815 format_str = "{0: <#020x} {1: <16d} {2: <#020x} {3: <#020x} {4: <16d}" 816 out_string = format_str.format(data_element, unsigned(data_element.e_made), data_element.e_sum, data_element.e_hash, unsigned(data_element.e_size)) 817 out_string += " 0x" 818 819 for i in range(0, (unsigned(data_element.e_size) - 1)): 820 out_string += "{:02x}".format(int(data_element.e_data[i])) 821 return out_string 822 823def GetIPCHandleSummary(handle_ptr): 824 """ converts a handle value inside a voucher attribute table to ipc element and returns appropriate summary. 825 params: handle_ptr - uint64 number stored in handle of voucher. 826 returns: str - string summary of the element held in internal structure 827 """ 828 elem = kern.GetValueFromAddress(handle_ptr, 'ipc_importance_elem_t') 829 if elem.iie_bits & 0x80000000 : 830 iie = Cast(elem, 'struct ipc_importance_inherit *') 831 return GetIPCImportanceInheritSummary(iie) 832 else: 833 iit = Cast(elem, 'struct ipc_importance_task *') 834 return GetIPCImportantTaskSummary(iit) 835 836def GetATMHandleSummary(handle_ptr): 837 """ Convert a handle value to atm value and returns corresponding summary of its fields. 838 params: handle_ptr - uint64 number stored in handle of voucher 839 returns: str - summary of atm value 840 """ 841 elem = kern.GetValueFromAddress(handle_ptr, 'atm_value *') 842 return GetATMValueSummary(elem) 843 844def GetBankHandleSummary(handle_ptr): 845 """ converts a handle value inside a voucher attribute table to bank element and returns appropriate summary. 846 params: handle_ptr - uint64 number stored in handle of voucher. 847 returns: str - summary of bank element 848 """ 849 elem = kern.GetValueFromAddress(handle_ptr, 'bank_element_t') 850 if elem.be_type & 1 : 851 ba = Cast(elem, 'struct bank_account *') 852 return GetBankAccountSummary(ba) 853 else: 854 bt = Cast(elem, 'struct bank_task *') 855 return GetBankTaskSummary(bt) 856 857def GetBagofBitsHandleSummary(handle_ptr): 858 """ Convert a handle value to bag of bits value and returns corresponding summary of its fields. 859 params: handle_ptr - uint64 number stored in handle of voucher 860 returns: str - summary of bag of bits element 861 """ 862 elem = kern.GetValueFromAddress(handle_ptr, 'user_data_element_t') 863 return GetBagofBitsElementSummary(elem) 864 865@static_var('attr_managers',{1: GetATMHandleSummary, 2: GetIPCHandleSummary, 3: GetBankHandleSummary, 7: GetBagofBitsHandleSummary}) 866def GetHandleSummaryForKey(handle_ptr, key_num): 867 """ Get a summary of handle pointer from the voucher attribute manager. 868 For example key 1 -> ATM and it puts atm_value_t in the handle. So summary of it would be atm value and refs etc. 869 key 2 -> ipc and it puts either ipc_importance_inherit_t or ipc_important_task_t. 870 key 3 -> Bank and it puts either bank_task_t or bank_account_t. 871 key 7 -> Bag of Bits and it puts user_data_element_t in handle. So summary of it would be Bag of Bits content and refs etc. 872 """ 873 key_num = int(key_num) 874 if key_num not in GetHandleSummaryForKey.attr_managers: 875 return "Unknown key %d" % key_num 876 return GetHandleSummaryForKey.attr_managers[key_num](handle_ptr) 877 878 879@header("{: <18s} {: <18s} {: <10s} {: <4s} {: <18s} {: <18s}".format("ivace", "value_handle", "#refs", "rel?", "maderefs", "next_layer")) 880@lldb_type_summary(['ivac_entry *', 'ivac_entry_t']) 881def GetIPCVoucherAttributeEntrySummary(ivace, manager_key_num = 0): 882 """ Get summary for voucher attribute entry. 883 """ 884 out_str = "" 885 fmt = "{e: <#018x} {e.ivace_value: <#018x} {e.ivace_refs: <10d} {release: <4s} {made_refs: <18s} {next_layer: <18s}" 886 release_str = "" 887 free_str = "" 888 made_refs = "" 889 next_layer = "" 890 891 if unsigned(ivace.ivace_releasing): 892 release_str = "Y" 893 if unsigned(ivace.ivace_free): 894 free_str = 'F' 895 if unsigned(ivace.ivace_layered): 896 next_layer = "{: <#018x}".format(ivace.ivace_u.ivaceu_layer) 897 else: 898 made_refs = "{: <18d}".format(ivace.ivace_u.ivaceu_made) 899 900 out_str += fmt.format(e=ivace, release=release_str, made_refs=made_refs, next_layer=next_layer) 901 if config['verbosity'] > vHUMAN and manager_key_num > 0: 902 out_str += " " + GetHandleSummaryForKey(unsigned(ivace.ivace_value), manager_key_num) 903 if config['verbosity'] > vHUMAN : 904 out_str += ' {: <2s} {: <4d} {: <4d}'.format(free_str, ivace.ivace_next, ivace.ivace_index) 905 return out_str 906 907@lldb_command('showivacfreelist','') 908def ShowIVACFreeList(cmd_args=[], cmd_options={}): 909 """ Walk the free list and print every entry in the list. 910 usage: (lldb) showivacfreelist <ipc_voucher_attr_control_t> 911 """ 912 if not cmd_args: 913 raise ArgumentError('Please provide <ipc_voucher_attr_control_t>') 914 ivac = kern.GetValueFromAddress(cmd_args[0], 'ipc_voucher_attr_control_t') 915 print GetIPCVoucherAttrControlSummary.header 916 print GetIPCVoucherAttrControlSummary(ivac) 917 if unsigned(ivac.ivac_freelist) == 0: 918 print "ivac table is full" 919 return 920 print "index " + GetIPCVoucherAttributeEntrySummary.header 921 next_free = unsigned(ivac.ivac_freelist) 922 while next_free != 0: 923 print "{: <5d} ".format(next_free) + GetIPCVoucherAttributeEntrySummary(addressof(ivac.ivac_table[next_free])) 924 next_free = unsigned(ivac.ivac_table[next_free].ivace_next) 925 926 927 928@header('{: <18s} {: <8s} {: <18s} {: <18s} {: <18s} {: <18s} {: <18s}'.format("ipc_voucher", "refs", "checksum", "hash", "tbl_size", "table", "voucher_port")) 929@lldb_type_summary(['ipc_voucher *', 'ipc_voucher_t']) 930def GetIPCVoucherSummary(voucher, show_entries=False): 931 """ describe a voucher from its ipc_voucher * object """ 932 out_str = "" 933 fmt = "{v: <#018x} {v.iv_refs: <8d} {v.iv_sum: <#018x} {v.iv_hash: <#018x} {v.iv_table_size: <#018x} {v.iv_table: <#018x} {v.iv_port: <#018x}" 934 out_str += fmt.format(v = voucher) 935 entries_str = '' 936 if show_entries or config['verbosity'] > vHUMAN: 937 elems = unsigned(voucher.iv_table_size) 938 entries_header_str = "\n\t" + "{: <5s} {: <3s} {: <16s} {: <30s}".format("index", "key", "value_index", "manager") + " " + GetIPCVoucherAttributeEntrySummary.header 939 fmt = "{: <5d} {: <3d} {: <16d} {: <30s}" 940 for i in range(elems): 941 voucher_entry_index = unsigned(voucher.iv_inline_table[i]) 942 if voucher_entry_index: 943 s = fmt.format(i, GetVoucherManagerKeyForIndex(i), voucher_entry_index, GetVoucherAttributeManagerNameForIndex(i)) 944 e = GetVoucherValueHandleFromVoucherForIndex(voucher, i) 945 if e is not None: 946 s += " " + GetIPCVoucherAttributeEntrySummary(addressof(e), GetVoucherManagerKeyForIndex(i) ) 947 if entries_header_str : 948 entries_str = entries_header_str 949 entries_header_str = '' 950 entries_str += "\n\t" + s 951 if not entries_header_str: 952 entries_str += "\n\t" 953 out_str += entries_str 954 return out_str 955 956def GetVoucherManagerKeyForIndex(idx): 957 """ Returns key number for index based on global table. Will raise index error if value is incorrect 958 """ 959 return unsigned(kern.globals.iv_global_table[idx].ivgte_key) 960 961def GetVoucherAttributeManagerForKey(k): 962 """ Walks through the iv_global_table and finds the attribute manager name 963 params: k - int key number of the manager 964 return: cvalue - the attribute manager object. 965 None - if not found 966 """ 967 retval = None 968 entry_size = sizeof(kern.globals.iv_global_table[0]) 969 elems = sizeof(kern.globals.iv_global_table) / entry_size 970 for i in range(elems): 971 elt = addressof(kern.globals.iv_global_table[i]) 972 if k == unsigned(elt.ivgte_key): 973 retval = elt.ivgte_manager 974 break 975 return retval 976 977def GetVoucherAttributeControllerForKey(k): 978 """ Walks through the iv_global_table and finds the attribute controller 979 params: k - int key number of the manager 980 return: cvalue - the attribute controller object. 981 None - if not found 982 """ 983 retval = None 984 entry_size = sizeof(kern.globals.iv_global_table[0]) 985 elems = sizeof(kern.globals.iv_global_table) / entry_size 986 for i in range(elems): 987 elt = addressof(kern.globals.iv_global_table[i]) 988 if k == unsigned(elt.ivgte_key): 989 retval = elt.ivgte_control 990 break 991 return retval 992 993 994def GetVoucherAttributeManagerName(ivam): 995 """ find the name of the ivam object 996 param: ivam - cvalue object of type ipc_voucher_attr_manager_t 997 returns: str - name of the manager 998 """ 999 return kern.Symbolicate(unsigned(ivam)) 1000 1001def GetVoucherAttributeManagerNameForIndex(idx): 1002 """ get voucher attribute manager name for index 1003 return: str - name of the attribute manager object 1004 """ 1005 return GetVoucherAttributeManagerName(GetVoucherAttributeManagerForKey(GetVoucherManagerKeyForIndex(idx))) 1006 1007def GetVoucherValueHandleFromVoucherForIndex(voucher, idx): 1008 """ traverse the voucher attrs and get value_handle in the voucher attr controls table 1009 params: 1010 voucher - cvalue object of type ipc_voucher_t 1011 idx - int index in the entries for which you wish to get actual handle for 1012 returns: cvalue object of type ivac_entry_t 1013 None if no handle found. 1014 """ 1015 manager_key = GetVoucherManagerKeyForIndex(idx) 1016 voucher_num_elems = unsigned(voucher.iv_table_size) 1017 if idx >= voucher_num_elems: 1018 debuglog("idx %d is out of range max: %d" % (idx, voucher_num_elems)) 1019 return None 1020 voucher_entry_value = unsigned(voucher.iv_inline_table[idx]) 1021 debuglog("manager_key %d" % manager_key) 1022 ivac = GetVoucherAttributeControllerForKey(manager_key) 1023 if ivac is None or unsigned(ivac) == 0: 1024 debuglog("No voucher attribute controller for idx %d" % idx) 1025 return None 1026 1027 ivac = kern.GetValueFromAddress(unsigned(ivac), 'ipc_voucher_attr_control_t') # ??? No idea why lldb does not addressof directly 1028 ivace_table = ivac.ivac_table 1029 if voucher_entry_value >= unsigned(ivac.ivac_table_size): 1030 print "Failed to get ivace for value %d in table of size %d" % (voucher_entry_value, unsigned(ivac.ivac_table_size)) 1031 return None 1032 return ivace_table[voucher_entry_value] 1033 1034 1035 1036@lldb_command('showallvouchers') 1037def ShowAllVouchers(cmd_args=[], cmd_options={}): 1038 """ Display a list of all vouchers in the global voucher hash table 1039 Usage: (lldb) showallvouchers 1040 """ 1041 iv_hash_table = kern.globals.ivht_bucket 1042 num_buckets = sizeof(kern.globals.ivht_bucket) / sizeof(kern.globals.ivht_bucket[0]) 1043 print GetIPCVoucherSummary.header 1044 for i in range(num_buckets): 1045 for v in IterateQueue(iv_hash_table[i], 'ipc_voucher_t', 'iv_hash_link'): 1046 print GetIPCVoucherSummary(v) 1047 1048@lldb_command('showvoucher', '') 1049def ShowVoucher(cmd_args=[], cmd_options={}): 1050 """ Describe a voucher from <ipc_voucher_t> argument. 1051 Usage: (lldb) showvoucher <ipc_voucher_t> 1052 """ 1053 if not cmd_args: 1054 raise ArgumentError("Please provide valid argument") 1055 1056 voucher = kern.GetValueFromAddress(cmd_args[0], 'ipc_voucher_t') 1057 print GetIPCVoucherSummary.header 1058 print GetIPCVoucherSummary(voucher, show_entries=True) 1059 1060 1061