+def IterateLinkageChain(queue_head, element_type, field_name, field_ofst=0):
+ """ Iterate over a Linkage Chain queue in kernel of type queue_head_t. (osfmk/kern/queue.h method 1)
+ This is equivalent to the qe_foreach_element() macro
+ params:
+ queue_head - value : Value object for queue_head.
+ element_type - lldb.SBType : pointer type of the element which contains the queue_chain_t. Typically its structs like thread, task etc..
+ - str : OR a string describing the type. ex. 'task *'
+ field_name - str : Name of the field (in element) which holds a queue_chain_t
+ field_ofst - int : offset from the 'field_name' (in element) which holds a queue_chain_t
+ This is mostly useful if a particular element contains an array of queue_chain_t
+ returns:
+ A generator does not return. It is used for iterating.
+ value : An object thats of type (element_type). Always a pointer object
+ example usage:
+ coalq = kern.GetGlobalVariable('coalitions_q')
+ for coal in IterateLinkageChain(coalq, 'struct coalition *', 'coalitions'):
+ print GetCoalitionInfo(coal)
+ """
+ global kern
+ if type(element_type) == str:
+ element_type = gettype(element_type)
+
+ if unsigned(queue_head) == 0:
+ return
+
+ if element_type.IsPointerType():
+ elem_ofst = getfieldoffset(element_type.GetPointeeType(), field_name) + field_ofst
+ else:
+ elem_ofst = getfieldoffset(element_type, field_name) + field_ofst
+
+ link = queue_head.next
+ while (unsigned(link) != unsigned(queue_head)):
+ addr = unsigned(link) - elem_ofst;
+ # I can't use the GetValueFromAddress function of the kernel class
+ # because I have no instance of that class!
+ obj = value(link.GetSBValue().CreateValueFromExpression(None,'(void *)'+str(addr)))
+ obj = cast(obj, element_type)
+ yield obj
+ link = link.next
+
+
+def IterateQueue(queue_head, element_ptr_type, element_field_name, backwards=False, unpack_ptr_fn=None):
+ """ Iterate over an Element Chain queue in kernel of type queue_head_t. (osfmk/kern/queue.h method 2)