+ flags.append('reaped')
+ if (coal.notified):
+ flags.append('notified')
+ return "|".join(flags)
+
+def GetCoalitionTasks(queue, coal_type, thread_details=False):
+ sfi_strs = {
+ 0x0 : "SFI_CLASS_UNSPECIFIED",
+ 0x1 : "SFI_CLASS_DARWIN_BG",
+ 0x2 : "SFI_CLASS_APP_NAP",
+ 0x3 : "SFI_CLASS_MANAGED_FOCAL",
+ 0x4 : "SFI_CLASS_MANAGED_NONFOCAL",
+ 0x5 : "SFI_CLASS_DEFAULT_FOCAL",
+ 0x6 : "SFI_CLASS_DEFAULT_NONFOCAL",
+ 0x7 : "SFI_CLASS_KERNEL",
+ 0x8 : "SFI_CLASS_OPTED_OUT",
+ 0x9 : "SFI_CLASS_UTILITY",
+ 0xA : "SFI_CLASS_LEGACY_FOCAL",
+ 0xB : "SFI_CLASS_LEGACY_NONFOCAL",
+ 0xC : "SFI_CLASS_USER_INITIATED_FOCAL",
+ 0xD : "SFI_CLASS_USER_INITIATED_NONFOCAL",
+ 0xE : "SFI_CLASS_USER_INTERACTIVE_FOCAL",
+ 0xF : "SFI_CLASS_USER_INTERACTIVE_NONFOCAL",
+ 0x10 : "SFI_CLASS_MAINTENANCE",
+ }
+ tasks = []
+ field_name = 'task_coalition'
+ for task in IterateLinkageChain(queue, 'task *', field_name, coal_type * sizeof('queue_chain_t')):
+ task_str = "({0: <d},{1: #x}, {2: <s}, {3: <s})".format(GetProcPIDForTask(task),task,GetProcNameForTask(task),GetTaskRoleString(task.effective_policy.t_role))
+ if thread_details:
+ for thread in IterateQueue(task.threads, "thread_t", "task_threads"):
+ task_str += "\n\t\t\t|-> thread:" + hex(thread) + ", " + sfi_strs[int(thread.sfi_class)]
+ tasks.append(task_str)
+ return tasks
+
+def GetCoalitionTypeString(type):
+ """ Convert a coalition type field into a string
+ Currently supported types (from <mach/coalition.h>):
+ COALITION_TYPE_RESOURCE
+ COALITION_TYPE_JETSAM
+ """
+ if type == 0: # COALITION_TYPE_RESOURCE
+ return 'RESOURCE'
+ if type == 1:
+ return 'JETSAM'
+ return '<unknown>'
+
+def GetResourceCoalitionSummary(coal, verbose=False):
+ """ Summarize a resource coalition
+ """
+ out_string = "Resource Coalition:\n\t Ledger:\n"
+ thread_details = False
+ if config['verbosity'] > vSCRIPT:
+ thread_details = True
+ ledgerp = coal.r.ledger
+ if verbose and unsigned(ledgerp) != 0:
+ i = 0
+ while i != ledgerp.l_template.lt_cnt:
+ out_string += "\t\t"
+ out_string += GetLedgerEntrySummary(kern.globals.task_ledger_template, ledgerp.l_entries[i], i)
+ i = i + 1
+ out_string += "\t bytesread {0: <d}\n\t byteswritten {1: <d}\n\t gpu_time {2: <d}".format(coal.r.bytesread, coal.r.byteswritten, coal.r.gpu_time)
+ out_string += "\n\t total_tasks {0: <d}\n\t dead_tasks {1: <d}\n\t active_tasks {2: <d}".format(coal.r.task_count, coal.r.dead_task_count, coal.r.task_count - coal.r.dead_task_count)
+ out_string += "\n\t last_became_nonempty_time {0: <d}\n\t time_nonempty {1: <d}".format(coal.r.last_became_nonempty_time, coal.r.time_nonempty)
+ out_string += "\n\t Tasks:\n\t\t"
+ tasks = GetCoalitionTasks(addressof(coal.r.tasks), 0, thread_details)
+ out_string += "\n\t\t".join(tasks)
+ return out_string
+
+def GetJetsamCoalitionSummary(coal, verbose=False):
+ out_string = "Jetsam Coalition:"
+ thread_details = False
+ if config['verbosity'] > vSCRIPT:
+ thread_details = True
+ if unsigned(coal.j.leader) == 0:
+ out_string += "\n\t NO Leader!"
+ else:
+ out_string += "\n\t Leader:\n\t\t"
+ out_string += "({0: <d},{1: #x}, {2: <s}, {3: <s})".format(GetProcPIDForTask(coal.j.leader),coal.j.leader,GetProcNameForTask(coal.j.leader),GetTaskRoleString(coal.j.leader.effective_policy.t_role))
+ out_string += "\n\t Extensions:\n\t\t"
+ tasks = GetCoalitionTasks(addressof(coal.j.extensions), 1, thread_details)
+ out_string += "\n\t\t".join(tasks)
+ out_string += "\n\t XPC Services:\n\t\t"
+ tasks = GetCoalitionTasks(addressof(coal.j.services), 1, thread_details)
+ out_string += "\n\t\t".join(tasks)
+ out_string += "\n\t Other Tasks:\n\t\t"
+ tasks = GetCoalitionTasks(addressof(coal.j.other), 1, thread_details)
+ out_string += "\n\t\t".join(tasks)