text: #!/usr/bin/env python3
  # 
  # Cross Platform and Multi Architecture Advanced Binary Emulation Framework
  #
  
  import ctypes, struct
  
  from enum import IntEnum
  
  
  class POINTER64(ctypes.Structure):
      _fields_ = [("value", ctypes.c_uint64)]
  
  class list_entry(ctypes.Structure):
      _fields_ = (
          ("le_next", POINTER64),
          ("le_prev", POINTER64),
      )
  
  class list_head(ctypes.Structure):
      _fields_ = (
          ("lh_first", POINTER64),
      )
  
      def __init__(self, ql, base):
          self.ql = ql
          self.base = base
  
      def updateToMem(self):
          self.ql.mem.write(self.base, bytes(self))
  
      def loadFromMem(self):
          data = self.ql.mem.read(self.base, ctypes.sizeof(self))
          newObj = type(self).from_buffer(data)
          newObj.ql = self.ql
          newObj.base = self.base
          return newObj
  
  class tailq_head(ctypes.Structure):
      _fields_ = (
          ("tqh_first", POINTER64),
          ("tqh_last", POINTER64),
      )
  
  class slist_head(ctypes.Structure):
      _fields_ = (
          ("slh_first", POINTER64),
      )
  
  class tailq_entry(ctypes.Structure):
      _fields_ = (
          ("tqe_next", POINTER64),
          ("tqe_prev", POINTER64),
      )
  
  # struct IOExternalMethodArguments
  # {
  #     uint32_t      version;
  
  #     uint32_t      selector;
  
  #     mach_port_t           asyncWakePort;
  #     io_user_reference_t * asyncReference;
  #     uint32_t              asyncReferenceCount;
  
  #     const uint64_t *    scalarInput;
  #     uint32_t      scalarInputCount;
  
  #     const void *  structureInput;
  #     uint32_t      structureInputSize;
  
  #     IOMemoryDescriptor * structureInputDescriptor;
     
  #     uint64_t *        scalarOutput;
  #     uint32_t      scalarOutputCount;
  
  #     void *        structureOutput;
  #     uint32_t      structureOutputSize;
  
  #     IOMemoryDescriptor * structureOutputDescriptor;
  #     uint32_t       structureOutputDescriptorSize;
  
  #     uint32_t      __reservedA;
  
  #     OSObject **         structureVariableOutputData;
  
  #     uint32_t      __reserved[30];
  # };
  
  class IOExternalMethodArguments(ctypes.Structure):
      _pack_ = 8
      _fields_ = (
          ("_version", ctypes.c_uint32),
          ("_selector", ctypes.c_uint32),
          ("_asyncWakePort", ctypes.c_uint32),
          ("_asyncReference", POINTER64),
          ("_asyncReferenceCount", ctypes.c_uint32),
          ("_scalarInput", POINTER64),
          ("_scalarInputCount", ctypes.c_uint32),
          ("_structureInput", POINTER64),
          ("_structureInputSize", ctypes.c_uint32),
          ("_structureInputDescriptor", POINTER64),
          ("_scalarOutput", POINTER64),
          ("_scalarOutputCount", ctypes.c_uint32),
          ("_structureOutput", POINTER64),
          ("_structureOutputSize", ctypes.c_uint32),
          ("_structureOutputDescriptor", POINTER64),
          ("_structureOutputDescriptorSize", ctypes.c_uint32),
          ("___reservedA", ctypes.c_uint32),
          ("_structureVariableOutputData", POINTER64),
          ("___reserved", ctypes.c_uint32 * 30)
      )
      def __init__(self, ql, base):
          self.ql = ql
          self.base = base
  
      @property
      def scalarInput(self):
          data = self.ql.mem.read(self.base, ctypes.sizeof(self))
          obj = type(self).from_buffer(data)
          array = self.ql.mem.read(obj._scalarInput.value, obj._scalarInputCount)
          return [struct.unpack("<Q", array[i: i + 8]) for i in range(0, len(array), 8)]
  
      @property
      def structureInput(self):
          data = self.ql.mem.read(self.base, ctypes.sizeof(self))
          obj = type(self).from_buffer(data)
          return self.ql.mem.read(obj._structureInput.value, obj._structureInputSize)
  
      @property
      def scalarOutput(self):
          data = self.ql.mem.read(self.base, ctypes.sizeof(self))
          obj = type(self).from_buffer(data)
          array = self.ql.mem.read(obj._scalarOutput.value, obj._scalarOutputCount)
          return [struct.unpack("<Q", array[i: i + 8]) for i in range(0, len(array), 8)]
  
      @property
      def structureOutput(self):
          data = self.ql.mem.read(self.base, ctypes.sizeof(self))
          obj = type(self).from_buffer(data)
          return self.ql.mem.read(obj._structureOutput.value, obj._structureOutputSize)
  
      def updateToMem(self):
          self.ql.mem.write(self.base, bytes(self))
  
      def loadFromMem(self):
          data = self.ql.mem.read(self.base, ctypes.sizeof(self))
          newObj = type(self).from_buffer(data)
          newObj.ql = self.ql
          newObj.base = self.base
          return newObj
  
  # typedef IOReturn (*IOExternalMethodAction)(OSObject * target, void * reference, 
  #                         IOExternalMethodArguments * arguments);
  # struct IOExternalMethodDispatch
  # {
  #     IOExternalMethodAction function;
  #     uint32_t           checkScalarInputCount;
  #     uint32_t           checkStructureInputSize;
  #     uint32_t           checkScalarOutputCount;
  #     uint32_t           checkStructureOutputSize;
  # };
  
  class IOExternalMethodDispatch(ctypes.Structure):
      _pack_ = 8
      _fields_ = (
          ("function", POINTER64),
          ("checkScalarInputCount", ctypes.c_uint32),
          ("checkStructureInputSize", ctypes.c_uint32),
          ("checkScalarOutputCount", ctypes.c_uint32),
          ("checkStructureOutputSize", ctypes.c_uint32)
      )
      def __init__(self, ql, base):
          self.ql = ql
          self.base = base
  
      def updateToMem(self):
          self.ql.mem.write(self.base, bytes(self))
  
      def loadFromMem(self):
          data = self.ql.mem.read(self.base, ctypes.sizeof(self))
          newObj = type(self).from_buffer(data)
          newObj.ql = self.ql
          newObj.base = self.base
          return newObj
  
  # typedef struct kmod_info {
  #     struct kmod_info  * next;
  #     int32_t             info_version;           // version of this structure
  #     uint32_t            id;
  #     char                name[KMOD_MAX_NAME];
  #     char                version[KMOD_MAX_NAME];
  #     int32_t             reference_count;        // # linkage refs to this 
  #     kmod_reference_t  * reference_list;         // who this refs (links on)
  #     vm_address_t        address;                // starting address
  #     vm_size_t           size;                   // total size
  #     vm_size_t           hdr_size;               // unwired hdr size
  #     kmod_start_func_t * start;
  #     kmod_stop_func_t  * stop;
  # } kmod_info_t;
  
  class kmod_info_t(ctypes.Structure):
      _pack_ = 8
      _fields_ = (
          ("next", POINTER64),
          ("info_version", ctypes.c_int32),
          ("id", ctypes.c_uint32),
          ("name", ctypes.c_char * 64),
          ("version", ctypes.c_char * 64),
          ("reference_count", ctypes.c_int32),
          ("reference_list", POINTER64),
          ("address", POINTER64),
          ("size", ctypes.c_uint64),
          ("hdr_size", ctypes.c_uint64),
          ("start", POINTER64),
          ("stop", POINTER64)
      )
  
      def __init__(self, ql, base):
          self.ql = ql
          self.base = base
  
      def updateToMem(self):
          self.ql.mem.write(self.base, bytes(self))
  
      def loadFromMem(self):
          data = self.ql.mem.read(self.base, ctypes.sizeof(self))
          newObj = type(self).from_buffer(data)
          newObj.ql = self.ql
          newObj.base = self.base
          return newObj
  
  # struct queue_entry {
  #     struct queue_entry  *next;      /* next element */
  #     struct queue_entry  *prev;      /* previous element */
  # };
  
  class queue_entry(ctypes.Structure):
      _pack_ = 8
      _fields_ = (
          ("next", POINTER64),
          ("prev", POINTER64)
      )
  
  # typedef struct _OSMallocTag_ {
  #     queue_chain_t   OSMT_link;
  #     uint32_t        OSMT_refcnt;
  #     uint32_t        OSMT_state;
  #     uint32_t        OSMT_attr;
  #     char            OSMT_name[OSMT_MAX_NAME];
  # }
  
  class OSMallocTag(ctypes.Structure):
      _pack_ = 8
      _fields_ = (
          ("OSMT_link", queue_entry),
          ("OSMT_refcnt", ctypes.c_uint32),
          ("OSMT_state", ctypes.c_uint32),
          ("OSMT_attr", ctypes.c_uint32),
          ("OSMT_name", ctypes.c_char * 64)
      )
  
      def __init__(self, ql, base):
          self.ql = ql
          self.base = base
  
      def updateToMem(self):
          self.ql.mem.write(self.base, bytes(self))
  
      def loadFromMem(self):
          data = self.ql.mem.read(self.base, ctypes.sizeof(self))
          newObj = type(self).from_buffer(data)
          newObj.ql = self.ql
          newObj.base = self.base
          return newObj
  
  # typedef struct {
  #     uint64_t            lck_grp_spin_util_cnt;
  #     uint64_t            lck_grp_spin_held_cnt;
  #     uint64_t            lck_grp_spin_miss_cnt;
  #     uint64_t            lck_grp_spin_held_max;
  #     uint64_t            lck_grp_spin_held_cum;
  # } lck_grp_spin_stat_t;
  
  # typedef struct {
  #     uint64_t            lck_grp_mtx_util_cnt;
  #     /* On x86, this is used as the "direct wait" count */
  #     uint64_t            lck_grp_mtx_held_cnt;
  #     uint64_t            lck_grp_mtx_miss_cnt;
  #     uint64_t            lck_grp_mtx_wait_cnt;
  #     /* Rest currently unused */
  #     uint64_t            lck_grp_mtx_held_max;
  #     uint64_t            lck_grp_mtx_held_cum;
  #     uint64_t            lck_grp_mtx_wait_max;
  #     uint64_t            lck_grp_mtx_wait_cum;
  # } lck_grp_mtx_stat_t;
  
  # typedef struct {
  #     uint64_t            lck_grp_rw_util_cnt;
  #     uint64_t            lck_grp_rw_held_cnt;
  #     uint64_t            lck_grp_rw_miss_cnt;
  #     uint64_t            lck_grp_rw_wait_cnt;
  #     uint64_t            lck_grp_rw_held_max;
  #     uint64_t            lck_grp_rw_held_cum;
  #     uint64_t            lck_grp_rw_wait_max;
  #     uint64_t            lck_grp_rw_wait_cum;
  # } lck_grp_rw_stat_t;
  
  # typedef struct _lck_grp_stat_ {
  #     lck_grp_spin_stat_t lck_grp_spin_stat;
  #     lck_grp_mtx_stat_t  lck_grp_mtx_stat;
  #     lck_grp_rw_stat_t   lck_grp_rw_stat;
  # } lck_grp_stat_t;
  
  # typedef struct _lck_grp_ {
  #     queue_chain_t       lck_grp_link;
  #     uint32_t        lck_grp_refcnt;
  #     uint32_t        lck_grp_spincnt;
  #     uint32_t        lck_grp_mtxcnt;
  #     uint32_t        lck_grp_rwcnt;
  #     uint32_t        lck_grp_attr;
  #     char            lck_grp_name[LCK_GRP_MAX_NAME];
  #     lck_grp_stat_t      lck_grp_stat;
  # } lck_grp_t;
  
  class lck_grp_spin_stat_t(ctypes.Structure):
      _fields_ = (
          ("lck_grp_spin_util_cnt", ctypes.c_uint64),
          ("lck_grp_spin_held_cnt", ctypes.c_uint64),
          ("lck_grp_spin_miss_cnt", ctypes.c_uint64),
          ("lck_grp_spin_held_max", ctypes.c_uint64),
          ("lck_grp_spin_held_cum", ctypes.c_uint64),
      )
  
  class lck_grp_mtx_stat_t(ctypes.Structure):
      _fields_ = (
          ("lck_grp_mtx_util_cnt", ctypes.c_uint64),
          ("lck_grp_mtx_held_cnt", ctypes.c_uint64),
          ("lck_grp_mtx_miss_cnt", ctypes.c_uint64),
          ("lck_grp_mtx_wait_cnt", ctypes.c_uint64),
          ("lck_grp_mtx_held_max", ctypes.c_uint64),
          ("lck_grp_mtx_held_cum", ctypes.c_uint64),
          ("lck_grp_mtx_wait_max", ctypes.c_uint64),
          ("lck_grp_mtx_wait_cum", ctypes.c_uint64),
      )
  
  class lck_grp_rw_stat_t(ctypes.Structure):
      _fields_ = (
          ("lck_grp_rw_util_cnt", ctypes.c_uint64),
          ("lck_grp_rw_held_cnt", ctypes.c_uint64),
          ("lck_grp_rw_miss_cnt", ctypes.c_uint64),
          ("lck_grp_rw_wait_cnt", ctypes.c_uint64),
          ("lck_grp_rw_held_max", ctypes.c_uint64),
          ("lck_grp_rw_held_cum", ctypes.c_uint64),
          ("lck_grp_rw_wait_max", ctypes.c_uint64),
          ("lck_grp_rw_wait_cum", ctypes.c_uint64),
      )
  
  class lck_grp_stat_t(ctypes.Structure):
      _fields_ = (
          ("lck_grp_spin_stat", lck_grp_spin_stat_t),
          ("lck_grp_mtx_stat", lck_grp_mtx_stat_t),
          ("lck_grp_rw_stat", lck_grp_rw_stat_t),
      )
  
  class lck_grp_t(ctypes.Structure):
      _fields_ = (
          ("lck_grp_link", queue_entry),
          ("lck_grp_refcnt", ctypes.c_uint32),
          ("lck_grp_spincnt", ctypes.c_uint32),
          ("lck_grp_mtxcnt", ctypes.c_uint32),
          ("lck_grp_rwcnt", ctypes.c_uint32),
          ("lck_grp_attr", ctypes.c_uint32),
          ("lck_grp_name", ctypes.c_char * 64),
          ("lck_grp_stat", lck_grp_stat_t)
      )
  
      def __init__(self, ql, base):
          self.ql = ql
          self.base = base
  
      def updateToMem(self):
          self.ql.mem.write(self.base, bytes(self))
  
      def loadFromMem(self):
          data = self.ql.mem.read(self.base, ctypes.sizeof(self))
          newObj = type(self).from_buffer(data)
          newObj.ql = self.ql
          newObj.base = self.base
          return newObj
  
  # typedef struct _lck_grp_attr_ {
  #     uint32_t    grp_attr_val;
  # } lck_grp_attr_t;
  
  class lck_grp_attr_t(ctypes.Structure):
      _fields_ = (
          ("grp_attr_val", ctypes.c_uint32),
      )
  
      def __init__(self, ql, base):
          self.ql = ql
          self.base = base
  
      def updateToMem(self):
          self.ql.mem.write(self.base, bytes(self))
  
      def loadFromMem(self):
          data = self.ql.mem.read(self.base, ctypes.sizeof(self))
          newObj = type(self).from_buffer(data)
          newObj.ql = self.ql
          newObj.base = self.base
          return newObj
  
  # typedef struct _lck_attr_ {
  #     unsigned int    lck_attr_val;
  # } lck_attr_t;
  
  class lck_attr_t(ctypes.Structure):
      _fields_ = (
          ("lck_attr_val", ctypes.c_uint32),
      )
  
      def __init__(self, ql, base):
          self.ql = ql
          self.base = base
  
      def updateToMem(self):
          self.ql.mem.write(self.base, bytes(self))
  
      def loadFromMem(self):
          data = self.ql.mem.read(self.base, ctypes.sizeof(self))
          newObj = type(self).from_buffer(data)
          newObj.ql = self.ql
          newObj.base = self.base
          return newObj
  
  # typedef struct _lck_mtx_ {
  #     union {
  #         struct {
  #             volatile uintptr_t      lck_mtx_owner;
  #             union {
  #                 struct {
  #                     volatile uint32_t
  #                         lck_mtx_waiters:16,
  #                         lck_mtx_pri:8,
  #                         lck_mtx_ilocked:1,
  #                         lck_mtx_mlocked:1,
  #                         lck_mtx_promoted:1,
  #                         lck_mtx_spin:1,
  #                         lck_mtx_is_ext:1,
  #                         lck_mtx_pad3:3;
  #                 };
  #                     uint32_t    lck_mtx_state;
  #             };
  #             /* Pad field used as a canary, initialized to ~0 */
  #             uint32_t            lck_mtx_pad32;
  #         };
  #         struct {
  #             struct _lck_mtx_ext_        *lck_mtx_ptr;
  #             uint32_t            lck_mtx_tag;
  #             uint32_t            lck_mtx_pad32_2;
  #         };
  #     };
  # } lck_mtx_t;
  
  class lck_mtx_t(ctypes.Structure):
      class lck_mtx_tmp_union(ctypes.Union):
          class lck_mtx_tmp_union_struct_1(ctypes.Structure):
              class lck_mtx_tmp_union_struct_union(ctypes.Union):
                  class lck_mtx_tmp_union_struct_union_struct(ctypes.Structure):
                      _fields_ = [
                          ("lck_mtx_waiters", ctypes.c_uint32, 16),
                          ("lck_mtx_pri", ctypes.c_uint32, 8),
                          ("lck_mtx_ilocked", ctypes.c_uint32, 1),
                          ("lck_mtx_mlocked", ctypes.c_uint32, 1),
                          ("lck_mtx_promoted", ctypes.c_uint32, 1),
                          ("lck_mtx_spin", ctypes.c_uint32, 1),
                          ("lck_mtx_is_ext", ctypes.c_uint32, 1),
                          ("lck_mtx_pad3", ctypes.c_uint32, 3)
                      ]
                  _anonymous_ = ("tmp_struct", )
                  _fields_ = (
                      ("tmp_struct", lck_mtx_tmp_union_struct_union_struct),
                      ("lck_mtx_state", ctypes.c_uint32)
                  )
              _anonymous_ = ("tmp_union", )
              _fields_ = (
                  ("lck_mtx_owner", ctypes.c_uint64),
                  ("tmp_union", lck_mtx_tmp_union_struct_union),
                  ("lck_mtx_pad32", ctypes.c_uint32)
              )
  
          class lck_mtx_tmp_union_struct_2(ctypes.Structure):
              _fields_ = (
                  ("lck_mtx_ptr", POINTER64),
                  ("lck_mtx_tag", ctypes.c_uint32),
                  ("lck_mtx_pad32_2", ctypes.c_uint32)
              )
  
          _anonymous_ = ("tmp_struct_1", "tmp_struct_2", )
          _fields_ = (
              ("tmp_struct_1", lck_mtx_tmp_union_struct_1),
              ("tmp_struct_2", lck_mtx_tmp_union_struct_2),
          )
      _anonymous_ = ("tmp_union", )
      _fields_ = (
          ("tmp_union", lck_mtx_tmp_union),
      )
  
      def __init__(self, ql, base):
          self.ql = ql
          self.base = base
  
      def updateToMem(self):
          self.ql.mem.write(self.base, bytes(self))
  
      def loadFromMem(self):
          data = self.ql.mem.read(self.base, ctypes.sizeof(self))
          newObj = type(self).from_buffer(data)
          newObj.ql = self.ql
          newObj.base = self.base
          return newObj
  
  # typedef struct {
  #     unsigned int        type;
  #     unsigned int        pad4;
  #     vm_offset_t     pc;
  #     vm_offset_t     thread;
  # } lck_mtx_deb_t;
  
  class lck_mtx_deb_t(ctypes.Structure):
      _fields_ = (
          ("type", ctypes.c_uint32),
          ("pad4", ctypes.c_uint32),
          ("pc", ctypes.c_uint64),
          ("thread", ctypes.c_uint64)
      )
  
  # typedef struct _lck_mtx_ext_ {
  #     lck_mtx_t       lck_mtx;
  #     struct _lck_grp_    *lck_mtx_grp;
  #     unsigned int        lck_mtx_attr;
  #     unsigned int        lck_mtx_pad1;
  #     lck_mtx_deb_t       lck_mtx_deb;
  #     uint64_t        lck_mtx_stat;
  #     unsigned int        lck_mtx_pad2[2];
  # } lck_mtx_ext_t;
  
  class lck_mtx_ext_t(ctypes.Structure):
      _fields_ = (
          ("lck_mtx", lck_mtx_t),
          ("lck_mtx_grp", POINTER64),
          ("lck_mtx_attr", ctypes.c_uint32),
          ("lck_mtx_pad1", ctypes.c_uint32),
          ("lck_mtx_deb", lck_mtx_deb_t),
          ("lck_mtx_stat", ctypes.c_uint64),
          ("lck_mtx_pad2", ctypes.c_uint32 * 2)
      )
      def __init__(self, ql, base):
          self.ql = ql
          self.base = base
  
      def updateToMem(self):
          self.ql.mem.write(self.base, bytes(self))
  
      def loadFromMem(self):
          data = self.ql.mem.read(self.base, ctypes.sizeof(self))
          newObj = type(self).from_buffer(data)
          newObj.ql = self.ql
          newObj.base = self.base
          return newObj
  
  # struct kauth_listener {
  #     TAILQ_ENTRY(kauth_listener) kl_link;
  #     const char *                kl_identifier;
  #     kauth_scope_callback_t      kl_callback;
  #     void *                      kl_idata;
  # };
  
  class kauth_listener_t(ctypes.Structure):
      class kauth_listener_struct(ctypes.Structure):
          _fields_ = (
              ("tqe_next", POINTER64),
              ("tqe_prev", POINTER64),
          )
      _fields_ = (
          ("kl_link", kauth_listener_struct),
          ("kl_identifier", POINTER64),
          ("kl_callback", POINTER64),
          ("kl_idata", POINTER64)
      )
  
      def __init__(self, ql, base):
          self.ql = ql
          self.base = base
  
      def updateToMem(self):
          self.ql.mem.write(self.base, bytes(self))
  
      def loadFromMem(self):
          data = self.ql.mem.read(self.base, ctypes.sizeof(self))
          newObj = type(self).from_buffer(data)
          newObj.ql = self.ql
          newObj.base = self.base
          return newObj
  
  # struct kauth_local_listener {
  #     kauth_listener_t            kll_listenerp;
  #     kauth_scope_callback_t      kll_callback;
  #     void *                      kll_idata;
  # };
  
  class kauth_local_listener_t(ctypes.Structure):
      _fields_ = (
          ("kll_listenerp", kauth_listener_t),
          ("kll_callback", POINTER64),
          ("kll_idata", POINTER64),
      )
  
  # struct kauth_scope {
  #     TAILQ_ENTRY(kauth_scope)    ks_link;
  #     volatile struct kauth_local_listener  ks_listeners[KAUTH_SCOPE_MAX_LISTENERS];
  #     const char *                ks_identifier;
  #     kauth_scope_callback_t      ks_callback;
  #     void *                      ks_idata;
  #     u_int                       ks_flags;
  # };
  
  class kauth_scope(ctypes.Structure):
      class kauth_scope_struct(ctypes.Structure):
          _fields_ = (
              ("tqe_next", POINTER64),
              ("tqe_prev", POINTER64),
          )
      _fields_ = (
          ("ks_link", kauth_scope_struct),
          ("ks_listeners", kauth_local_listener_t * 15),
          ("ks_identifier", POINTER64),
          ("ks_callback", POINTER64),
          ("ks_idata", POINTER64),
          ("ks_flags", ctypes.c_uint32)
      )
      def __init__(self, ql, base):
          self.ql = ql
          self.base = base
  
      def updateToMem(self):
          self.ql.mem.write(self.base, bytes(self))
  
      def loadFromMem(self):
          data = self.ql.mem.read(self.base, ctypes.sizeof(self))
          newObj = type(self).from_buffer(data)
          newObj.ql = self.ql
          newObj.base = self.base
          return newObj
  
  # struct domain {
  #     int dom_family;     /* AF_xxx */
  #     uint32_t dom_flags;     /* domain flags (see below ) */
  #     uint32_t dom_refs;      /* # socreates outstanding */
  #     lck_mtx_t *dom_mtx;     /* domain global mutex */
  #     decl_lck_mtx_data(, dom_mtx_s);
  #     TAILQ_ENTRY(domain) dom_entry;  /* next domain in list */
  #     TAILQ_HEAD(, protosw) dom_protosw; /* protosw chain */
  #     void    (*dom_init)     /* initialize domain data structures */
  #             (struct domain *);
  #     int (*dom_externalize)  /* externalize access rights */
  #             (struct mbuf *);
  #     void    (*dom_dispose)      /* dispose of internalized rights */
  #             (struct mbuf *);
  #     int (*dom_rtattach)     /* initialize routing table */
  #             (void **, int);
  #     int dom_rtoffset;       /* an arg to rtattach, in bits */
  #     int dom_maxrtkey;       /* for routing layer */
  #     int dom_protohdrlen;    /* len of protocol header */
  #     const char *dom_name;
  #     struct domain_old *dom_old; /* domain pointer per net_add_domain */
  # };
  
  class domain_t(ctypes.Structure):
      class domain_struct(ctypes.Structure):
          _fields_ = (
              ("tqe_next", POINTER64),
              ("tqe_prev", POINTER64),
          )
  
      _fields_ = (
          ("dom_family", ctypes.c_int32),
          ("dom_flags", ctypes.c_uint32),
          ("dom_refs", ctypes.c_uint32),
          ("dom_mtx", POINTER64),
          ("dom_mtx_s", lck_mtx_t),
          ("dom_entry", domain_struct),
          ("dom_protosw", tailq_head),
          ("dom_init", POINTER64),
          ("dom_externalize", POINTER64),
          ("dom_dispose", POINTER64),
          ("dom_rtattach", POINTER64),
          ("dom_rtoffset", ctypes.c_int32),
          ("dom_maxrtkey", ctypes.c_int32),
          ("dom_protohdrlen", ctypes.c_int32),
          ("dom_name", POINTER64),
          ("dom_old", POINTER64)
      )
      def __init__(self, ql, base):
          self.ql = ql
          self.base = base
  
      def updateToMem(self):
          self.ql.mem.write(self.base, bytes(self))
  
      def loadFromMem(self):
          data = self.ql.mem.read(self.base, ctypes.sizeof(self))
          newObj = type(self).from_buffer(data)
          newObj.ql = self.ql
          newObj.base = self.base
          return newObj
  
      def dump(self):
          for field in self._fields_:
              print(field[0], getattr(self, field[0]))
  
  # struct kev_d_vectors {
  #     u_int32_t   data_length;    /* Length of the event data */
  #     void        *data_ptr;  /* Pointer to event data */
  # };
  
  # /*!
  #     @struct kev_msg
  #     @discussion This structure is used when posting a kernel event.
  #     @field vendor_code The vendor code assigned by kev_vendor_code_find.
  #     @field kev_class The event's class.
  #     @field kev_class The event's subclass.
  #     @field kev_class The event's code.
  #     @field dv An array of vectors describing additional data to be appended
  #         to the kernel event.
  #  */
  # struct kev_msg {
  #     u_int32_t vendor_code;      /* For non-Apple extensibility */
  #     u_int32_t kev_class;        /* Layer of event source */
  #     u_int32_t kev_subclass;     /* Component within layer */
  #     u_int32_t event_code;       /* The event code */
  #     struct kev_d_vectors dv[N_KEV_VECTORS]; /* Up to n data vectors */
  # };
  
  class kev_d_vectors(ctypes.Structure):
      _fields_ = (
          ("data_length", ctypes.c_uint32),
          ("data_ptr", POINTER64),
      )
  
  class kev_msg(ctypes.Structure):
      _fields_ = (
          ("vendor_code", ctypes.c_uint32),
          ("kev_class", ctypes.c_uint32),
          ("kev_subclass", ctypes.c_uint32),
          ("event_code", ctypes.c_uint32),
          ("dv", kev_d_vectors * 5)
      )
  
      def __init__(self, ql, base):
          self.ql = ql
          self.base = base
  
      def updateToMem(self):
          self.ql.mem.write(self.base, bytes(self))
  
      def loadFromMem(self):
          data = self.ql.mem.read(self.base, ctypes.sizeof(self))
          newObj = type(self).from_buffer(data)
          newObj.ql = self.ql
          newObj.base = self.base
          return newObj
  
      def dump(self):
          for field in self._fields_:
              print(field[0], getattr(self, field[0]))
  
  # struct nlist_64 {
  #     union {
  #         uint32_t  n_strx; /* index into the string table */
  #     } n_un;
  #     uint8_t n_type;        /* type flag, see below */
  #     uint8_t n_sect;        /* section number or NO_SECT */
  #     uint16_t n_desc;       /* see <mach-o/stab.h> */
  #     uint64_t n_value;      /* value of this symbol (or stab offset) */
  # };
  
  class nlist64_t(ctypes.Structure):
      _fields_ = (
          ("n_strx", ctypes.c_uint32),
          ("n_type", ctypes.c_uint8),
          ("n_sect", ctypes.c_uint8),
          ("n_desc", ctypes.c_uint16),
          ("n_value", ctypes.c_uint64),
      )
  
      def __init__(self, ql, base):
          self.ql = ql
          self.base = base
  
      def updateToMem(self):
          self.ql.mem.write(self.base, bytes(self))
  
      def loadFromMem(self):
          data = self.ql.mem.read(self.base, ctypes.sizeof(self))
          newObj = type(self).from_buffer(data)
          newObj.ql = self.ql
          newObj.base = self.base
          return newObj
  
      def __str__(self):
          return "\tn_strx = %d" % self.n_strx + "\n\tn_type = %d" % self.n_type + "\n\tn_sect = %d" % self.n_sect + "\n\tn_desc = %d" % self.n_desc + "\n\tn_value = 0x%x" % self.n_value
  
  # struct sysent {        /* system call table */
  #     sy_call_t    *sy_call;    /* implementing function */
  #     sy_munge_t    *sy_arg_munge32; /* system call arguments munger for 32-bit process */
  #     int32_t        sy_return_type; /* system call return types */
  #     int16_t        sy_narg;    /* number of args */
  #     uint16_t    sy_arg_bytes;    /* Total size of arguments in bytes for
  #                      * 32-bit system calls
  #                      */
  # };
  
  class sysent_t(ctypes.Structure):
      _fields_ = (
          ("sy_call", POINTER64),
          ("sy_arg_munge32", POINTER64),
          ("sy_return_type", ctypes.c_int32),
          ("sy_narg", ctypes.c_int16),
          ("sy_arg_bytes", ctypes.c_uint16),
      )
  
      def __init__(self, ql, base):
          self.ql = ql
          self.base = base
  
      def updateToMem(self):
          self.ql.mem.write(self.base, bytes(self))
  
      def loadFromMem(self):
          data = self.ql.mem.read(self.base, ctypes.sizeof(self))
          newObj = type(self).from_buffer(data)
          newObj.ql = self.ql
          newObj.base = self.base
          return newObj
  
  # struct proc {
  #     LIST_ENTRY(proc) p_list;        /* List of all processes. */
  
  #     pid_t        p_pid;            /* Process identifier. (static)*/
  #     void *         task;            /* corresponding task (static)*/
  #     struct    proc *    p_pptr;             /* Pointer to parent process.(LL) */
  #     pid_t        p_ppid;            /* process's parent pid number */
  #     pid_t        p_pgrpid;        /* process group id of the process (LL)*/
  #     uid_t        p_uid;
  #     gid_t        p_gid;
  #     uid_t        p_ruid;
  #     gid_t        p_rgid;
  #     uid_t        p_svuid;
  #     gid_t        p_svgid;
  #     uint64_t    p_uniqueid;        /* process unique ID - incremented on fork/spawn/vfork, remains same across exec. */
  #     uint64_t    p_puniqueid;        /* parent's unique ID - set on fork/spawn/vfork, doesn't change if reparented. */
  
  #     struct lck_mtx_t     p_mlock;        /* mutex lock for proc */
  
  #     char        p_stat;            /* S* process status. (PL)*/
  #     char        p_shutdownstate;
  #     char        p_kdebug;        /* P_KDEBUG eq (CC)*/
  #     char        p_btrace;        /* P_BTRACE eq (CC)*/
  
  #     LIST_ENTRY(proc) p_pglist;        /* List of processes in pgrp.(PGL) */
  #     LIST_ENTRY(proc) p_sibling;        /* List of sibling processes. (LL)*/
  #     LIST_HEAD(, proc) p_children;        /* Pointer to list of children. (LL)*/
  #     TAILQ_HEAD( , uthread) p_uthlist;     /* List of uthreads  (PL) */
  
  #     LIST_ENTRY(proc) p_hash;        /* Hash chain. (LL)*/
  #     TAILQ_HEAD( ,eventqelt) p_evlist;    /* (PL) */
  
  #     struct lck_mtx_t    p_fdmlock;        /* proc lock to protect fdesc */
  #     struct lck_mtx_t     p_ucred_mlock;        /* mutex lock to protect p_ucred */
  
  #     /* substructures: */
  #     kauth_cred_t    p_ucred;        /* Process owner's identity. (PUCL) */
  #     struct    filedesc *p_fd;            /* Ptr to open files structure. (PFDL) */
  #     struct    pstats *p_stats;        /* Accounting/statistics (PL). */
  #     struct    plimit *p_limit;        /* Process limits.(PL) */
  
  #     struct    sigacts *p_sigacts;        /* Signal actions, state (PL) */
  #      int        p_siglist;        /* signals captured back from threads */
  #     struct lck_spin_t    p_slock;        /* spin lock for itimer/profil protection */
  
  # #define    p_rlimit    p_limit->pl_rlimit
  
  #     struct    plimit *p_olimit;        /* old process limits  - not inherited by child  (PL) */
  #     unsigned int    p_flag;            /* P_* flags. (atomic bit ops) */
  #     unsigned int    p_lflag;        /* local flags  (PL) */
  #     unsigned int    p_listflag;        /* list flags (LL) */
  #     unsigned int    p_ladvflag;        /* local adv flags (atomic) */
  #     int        p_refcount;        /* number of outstanding users(LL) */
  #     int        p_childrencnt;        /* children holding ref on parent (LL) */
  #     int        p_parentref;        /* children lookup ref on parent (LL) */
  
  #     pid_t        p_oppid;         /* Save parent pid during ptrace. XXX */
  #     u_int        p_xstat;        /* Exit status for wait; also stop signal. */
  #     uint8_t p_xhighbits;        /* Stores the top byte of exit status to avoid truncation*/
  
  #     struct    itimerval p_realtimer;        /* Alarm timer. (PSL) */
  #     struct    timeval p_rtime;        /* Real time.(PSL)  */
  #     struct    itimerval p_vtimer_user;    /* Virtual timers.(PSL)  */
  #     struct    itimerval p_vtimer_prof;    /* (PSL) */
  
  #     struct    timeval    p_rlim_cpu;        /* Remaining rlim cpu value.(PSL) */
  #     int        p_debugger;        /*  NU 1: can exec set-bit programs if suser */
  #     boolean_t    sigwait;    /* indication to suspend (PL) */
  #     void    *sigwait_thread;    /* 'thread' holding sigwait(PL)  */
  #     void    *exit_thread;        /* Which thread is exiting(PL)  */
  #     int    p_vforkcnt;        /* number of outstanding vforks(PL)  */
  #         void *  p_vforkact;         /* activation running this vfork proc)(static)  */
  #     int    p_fpdrainwait;        /* (PFDL) */
  #     pid_t    p_contproc;    /* last PID to send us a SIGCONT (PL) */
  
  #     /* Following fields are info from SIGCHLD (PL) */
  #     pid_t    si_pid;            /* (PL) */
  #     u_int   si_status;        /* (PL) */
  #     u_int    si_code;        /* (PL) */
  #     uid_t    si_uid;            /* (PL) */
  
  #     void * vm_shm;            /* (SYSV SHM Lock) for sysV shared memory */
  
  #     user_addr_t            p_dtrace_argv;            /* (write once, read only after that) */
  #     user_addr_t            p_dtrace_envp;            /* (write once, read only after that) */
  #     lck_mtx_t            p_dtrace_sprlock;        /* sun proc lock emulation */
  #     int                p_dtrace_probes;        /* (PL) are there probes for this proc? */
  #     u_int                p_dtrace_count;            /* (sprlock) number of DTrace tracepoints */
  #         uint8_t                         p_dtrace_stop;                  /* indicates a DTrace-desired stop */
  #     struct dtrace_ptss_page*    p_dtrace_ptss_pages;        /* (sprlock) list of user ptss pages */
  #     struct dtrace_ptss_page_entry*    p_dtrace_ptss_free_list;    /* (atomic) list of individual ptss entries */
  #     struct dtrace_helpers*        p_dtrace_helpers;        /* (dtrace_lock) DTrace per-proc private */
  #     struct dof_ioctl_data*        p_dtrace_lazy_dofs;        /* (sprlock) unloaded dof_helper_t's */
  
  # /* XXXXXXXXXXXXX BCOPY'ed on fork XXXXXXXXXXXXXXXX */
  # /* The following fields are all copied upon creation in fork. */
  # #define    p_startcopy    p_argslen
  
  #     u_int    p_argslen;     /* Length of process arguments. */
  #     int      p_argc;            /* saved argc for sysctl_procargs() */
  #     user_addr_t user_stack;        /* where user stack was allocated */
  #     struct    vnode *p_textvp;    /* Vnode of executable. */
  #     off_t    p_textoff;        /* offset in executable vnode */
  
  #     sigset_t p_sigmask;        /* DEPRECATED */
  #     sigset_t p_sigignore;    /* Signals being ignored. (PL) */
  #     sigset_t p_sigcatch;    /* Signals being caught by user.(PL)  */
  
  #     u_char    p_priority;    /* (NU) Process priority. */
  #     u_char    p_resv0;    /* (NU) User-priority based on p_cpu and p_nice. */
  #     char    p_nice;        /* Process "nice" value.(PL) */
  #     u_char    p_resv1;    /* (NU) User-priority based on p_cpu and p_nice. */
  
  #     // types currently in sys/param.h
  #     command_t   p_comm;
  #     proc_name_t p_name;    /* can be changed by the process */
  
  
  #     struct     pgrp *p_pgrp;        /* Pointer to process group. (LL) */
  #     uint32_t    p_csflags;    /* flags for codesign (PL) */
  #     uint32_t    p_pcaction;    /* action  for process control on starvation */
  #     uint8_t p_uuid[16];        /* from LC_UUID load command */
  
  #     /*
  #      * CPU type and subtype of binary slice executed in
  #      * this process.  Protected by proc lock.
  #      */
  #     cpu_type_t    p_cputype;
  #     cpu_subtype_t    p_cpusubtype;
  
  # /* End area that is copied on creation. */
  # /* XXXXXXXXXXXXX End of BCOPY'ed on fork (AIOLOCK)XXXXXXXXXXXXXXXX */
  # #define    p_endcopy    p_aio_total_count
  #     int        p_aio_total_count;        /* all allocated AIO requests for this proc */
  #     int        p_aio_active_count;        /* all unfinished AIO requests for this proc */
  #     TAILQ_HEAD( , aio_workq_entry ) p_aio_activeq;     /* active async IO requests */
  #     TAILQ_HEAD( , aio_workq_entry ) p_aio_doneq;    /* completed async IO requests */
  
  #     SLIST_HEAD(klist, klist) p_klist;  /* knote list (PL ?)*/
  
  #     struct    rusage_superset *p_ru;    /* Exit information. (PL) */
  #     int        p_sigwaitcnt;
  #     thread_t     p_signalholder;
  #     thread_t     p_transholder;
  
  #     /* DEPRECATE following field  */
  #     u_short    p_acflag;    /* Accounting flags. */
  #     volatile u_short p_vfs_iopolicy;    /* VFS iopolicy flags. (atomic bit ops) */
  
  #     user_addr_t     p_threadstart;        /* pthread start fn */
  #     user_addr_t     p_wqthread;        /* pthread workqueue fn */
  #     int     p_pthsize;            /* pthread size */
  #     uint32_t    p_pth_tsd_offset;    /* offset from pthread_t to TSD for new threads */
  #     user_addr_t    p_stack_addr_hint;    /* stack allocation hint for wq threads */
  #     void *     p_wqptr;            /* workq ptr */
  
  #     struct  timeval p_start;            /* starting time */
  #     void *    p_rcall;
  #     int        p_ractive;
  #     int    p_idversion;        /* version of process identity */
  #     void *    p_pthhash;            /* pthread waitqueue hash */
  #     volatile uint64_t was_throttled __attribute__((aligned(8))); /* Counter for number of throttled I/Os */
  #     volatile uint64_t did_throttle __attribute__((aligned(8)));  /* Counter for number of I/Os this proc throttled */
  
  #     uint64_t    p_dispatchqueue_offset;
  #     uint64_t    p_dispatchqueue_serialno_offset;
  #     uint64_t    p_return_to_kernel_offset;
  #     uint64_t    p_mach_thread_self_offset;
  
  #     struct timeval    vm_pressure_last_notify_tstamp;
  
  #     /* Fields protected by proc list lock */
  #     TAILQ_ENTRY(proc) p_memstat_list;               /* priority bucket link */
  #     uint32_t          p_memstat_state;              /* state */
  #     int32_t           p_memstat_effectivepriority;  /* priority after transaction state accounted for */
  #     int32_t           p_memstat_requestedpriority;  /* active priority */
  #     uint32_t          p_memstat_dirty;              /* dirty state */
  #     uint64_t          p_memstat_userdata;           /* user state */
  #     uint64_t          p_memstat_idledeadline;       /* time at which process became clean */
  #     uint64_t          p_memstat_idle_start;         /* abstime process transitions into the idle band */
  #     uint64_t      p_memstat_idle_delta;         /* abstime delta spent in idle band */
  #     int32_t           p_memstat_memlimit;           /* cached memory limit, toggles between active and inactive limits */
  #     int32_t           p_memstat_memlimit_active;    /* memory limit enforced when process is in active jetsam state */
  #     int32_t           p_memstat_memlimit_inactive;    /* memory limit enforced when process is in inactive jetsam state */
  
  #     /* cached proc-specific data required for corpse inspection */
  #     pid_t             p_responsible_pid;    /* pid resonsible for this process */
  #     _Atomic uint32_t  p_user_faults; /* count the number of user faults generated */
  
  #     struct os_reason     *p_exit_reason;
  
  #     uint64_t    p_user_data;            /* general-purpose storage for userland-provided data */
  
  # };
  
  class timeval_t(ctypes.Structure):
      _fields_ = (
          ("tv_sec", ctypes.c_long),
          ("tv_usec", ctypes.c_int32),
      )
  
  class itimerval_t(ctypes.Structure):
      _fields_ = (
          ("it_interval", timeval_t),
          ("it_value", timeval_t),
      )
  
  class proc_t(ctypes.Structure):
      # struct lck_spin_t {
      #     unsigned long    opaque[10];
      # };
      class lck_spin_t(ctypes.Structure):
          _fields_ = (
              ("opaque", ctypes.c_ulong * 10),
          )
      _fields_ = (
          ("p_list", list_entry),
          ("p_pid", ctypes.c_int32),
          ("task", POINTER64),
          ("p_pptr", POINTER64),
          ("p_ppid", ctypes.c_int32),
          ("p_pgrpid", ctypes.c_int32),
          ("p_uid", ctypes.c_uint32),
          ("p_gid", ctypes.c_uint32),
          ("p_ruid", ctypes.c_uint32),
          ("p_rgid", ctypes.c_uint32),
          ("p_svuid", ctypes.c_uint32),
          ("p_svgid", ctypes.c_uint32),
          ("p_uniqueid", ctypes.c_uint64),
          ("p_puniqueid", ctypes.c_uint64),
          ("p_mlock", lck_mtx_t),
          ("p_stat", ctypes.c_char),
          ("p_shutdownstate", ctypes.c_char),
          ("p_kdebug", ctypes.c_char),
          ("p_btrace", ctypes.c_char),
          ("p_pglist", list_entry),
          ("p_sibling", list_entry),
          ("p_children", list_head),
          ("p_uthlist", tailq_head),
          ("p_hash", list_entry),
          ("p_evlist", tailq_head),
          ("p_fdmlock", lck_mtx_t),
          ("p_ucred_mlock", lck_mtx_t),
          ("p_ucred", POINTER64),
          ("p_fd", POINTER64),
          ("p_stats", POINTER64),
          ("p_limit", POINTER64),
          ("p_sigacts", POINTER64),
          ("p_siglist", ctypes.c_int),
          ("p_slock", lck_spin_t),
          ("p_olimit", POINTER64),
          ("p_flag", ctypes.c_uint),
          ("p_lflag", ctypes.c_uint),
          ("p_listflag", ctypes.c_uint),
          ("p_ladvflag", ctypes.c_uint),
          ("p_refcount", ctypes.c_int),
          ("p_childrencnt", ctypes.c_int),
          ("p_parentref", ctypes.c_int),
          ("p_oppid", ctypes.c_int32),
          ("p_xstat", ctypes.c_uint),
          ("p_xhighbits", ctypes.c_uint8),
          ("p_realtimer", itimerval_t),
          ("p_rtime", timeval_t),
          ("p_vtimer_user", itimerval_t),
          ("p_vtimer_prof", itimerval_t),
          ("p_rlim_cpu", timeval_t),
          ("p_debugger", ctypes.c_int),
          ("sigwait", ctypes.c_int),
          ("sigwait_thread", POINTER64),
          ("exit_thread", POINTER64),
          ("p_vforkcnt", ctypes.c_int),
          ("p_vforkact", POINTER64),
          ("p_fpdrainwait", ctypes.c_int),
          ("p_contproc", ctypes.c_int32),
          ("si_pid", ctypes.c_int32),
          ("si_status", ctypes.c_uint),
          ("si_code", ctypes.c_uint),
          ("si_uid", ctypes.c_uint32),
          ("vm_shm", POINTER64),
          ("p_dtrace_argv", ctypes.c_uint64),
          ("p_dtrace_envp", ctypes.c_uint64),
          ("p_dtrace_sprlock", lck_mtx_t),
          ("p_dtrace_probes", ctypes.c_int),
          ("p_dtrace_count", ctypes.c_uint),
          ("p_dtrace_stop", ctypes.c_uint8),
          ("p_dtrace_ptss_pages", POINTER64),
          ("p_dtrace_ptss_free_list", POINTER64),
          ("p_dtrace_helpers", POINTER64),
          ("p_dtrace_lazy_dofs", POINTER64),
          ("p_argslen", ctypes.c_uint),
          ("p_argc", ctypes.c_int),
          ("user_stack", ctypes.c_uint64),
          ("p_textvp", POINTER64),
          ("p_textoff", ctypes.c_int64),
          ("p_sigmask", ctypes.c_uint32),
          ("p_sigignore", ctypes.c_uint32),
          ("p_sigcatch", ctypes.c_uint32),
          ("p_priority", ctypes.c_ubyte),
          ("p_resv0", ctypes.c_ubyte),
          ("p_nice", ctypes.c_char),
          ("p_resv1", ctypes.c_ubyte),
          ("p_comm", ctypes.c_char * (16 + 1)),
          ("p_name", ctypes.c_char * (2*16 + 1)),
          ("p_pgrp", POINTER64),
          ("p_csflags", ctypes.c_uint32),
          ("p_pcaction", ctypes.c_uint32),
          ("p_uuid", ctypes.c_uint8 * 16),
          ("p_cputype", ctypes.c_int),
          ("p_cpusubtype", ctypes.c_int),
          ("p_aio_total_count", ctypes.c_int),
          ("p_aio_active_count", ctypes.c_int),
          ("p_aio_activeq", tailq_head),
          ("p_aio_doneq", tailq_head),
          ("p_klist", slist_head),
          ("p_ru", POINTER64),
          ("p_sigwaitcnt", ctypes.c_int),
          ("p_signalholder", POINTER64),
          ("p_transholder", POINTER64),
          ("p_acflag", ctypes.c_ushort),
          ("p_vfs_iopolicy", ctypes.c_ushort),
          ("p_threadstart", ctypes.c_uint64),
          ("p_wqthread", ctypes.c_uint64),
          ("p_pthsize", ctypes.c_int),
          ("p_pth_tsd_offset", ctypes.c_uint32),
          ("p_stack_addr_hint", ctypes.c_uint64),
          ("p_wqptr", POINTER64),
          ("p_start", timeval_t),
          ("p_rcall", POINTER64),
          ("p_ractive", ctypes.c_int),
          ("p_idversion", ctypes.c_int),
          ("p_pthhash", POINTER64),
          ("was_throttled", ctypes.c_uint64),
          ("did_throttle", ctypes.c_uint64),
          ("p_dispatchqueue_offset", ctypes.c_uint64),
          ("p_dispatchqueue_serialno_offset", ctypes.c_uint64),
          ("p_return_to_kernel_offset", ctypes.c_uint64),
          ("p_mach_thread_self_offset", ctypes.c_uint64),
          ("vm_pressure_last_notify_tstamp", timeval_t),
          ("p_memstat_list", tailq_entry),
          ("p_memstat_state", ctypes.c_uint32),
          ("p_memstat_effectivepriority", ctypes.c_int32),
          ("p_memstat_requestedpriority", ctypes.c_int32),
          ("p_memstat_dirty", ctypes.c_uint32),
          ("p_memstat_userdata", ctypes.c_uint64),
          ("p_memstat_idledeadline", ctypes.c_uint64),
          ("p_memstat_idle_start", ctypes.c_uint64),
          ("p_memstat_idle_delta", ctypes.c_uint64),
          ("p_memstat_memlimit", ctypes.c_int32),
          ("p_memstat_memlimit_active", ctypes.c_int32),
          ("p_memstat_memlimit_inactive", ctypes.c_int32),
          ("p_responsible_pid", ctypes.c_int32),
          ("p_user_faults", ctypes.c_uint32),
          ("p_exit_reason", POINTER64),
          ("p_user_data", ctypes.c_uint64),
      )
  
      def __init__(self, ql, base):
          self.ql = ql
          self.base = base
  
      def updateToMem(self):
          self.ql.mem.write(self.base, bytes(self))
  
      def loadFromMem(self):
          data = self.ql.mem.read(self.base, ctypes.sizeof(self))
          newObj = type(self).from_buffer(data)
          newObj.ql = self.ql
          newObj.base = self.base
          return newObj
  
  # _STRUCT_TIMESPEC
  # {
  #     __darwin_time_t tv_sec;
  #     long            tv_nsec;
  # };
  class timespec_t(ctypes.Structure):
      _fields_ = (
          ("tv_sec", ctypes.c_long),
          ("tv_nsec", ctypes.c_long),
      )
  
  # typedef struct __attribute__((packed)) {
  #     uint32_t length;
  
  #     /* common attributes */
  #     attribute_set_t attrset;
  #     attrreference_t name;
  #     dev_t st_dev;
  #     fsobj_type_t objtype;
  #     struct timespec st_birthtimespec;
  #     struct timespec st_mtimespec;
  #     struct timespec st_ctimespec;
  #     struct timespec st_atimespec;
  #     uid_t st_uid;
  #     gid_t st_gid;
  #     uint32_t accessmask;
  #     uint32_t st_flags;
  #     uint64_t st_ino;
  
  #     /* non-directory attributes */
  #     uint32_t st_nlink;
  #     off_t allocsize;
  #     uint32_t st_blksize;
  #     uint32_t st_rdev;
  #     off_t st_size;
  # } attrListAttributes;
  
  class attrListAttributes_t(ctypes.Structure):
      # typedef struct attribute_set {
      #     attrgroup_t commonattr;         /* common attribute group */
      #     attrgroup_t volattr;            /* Volume attribute group */
      #     attrgroup_t dirattr;            /* directory attribute group */
      #     attrgroup_t fileattr;           /* file attribute group */
      #     attrgroup_t forkattr;           /* fork attribute group */
      # } attribute_set_t;
      class attribute_set_t(ctypes.Structure):
          _fields_ = (
              ("commonattr", ctypes.c_uint32),
              ("volattr", ctypes.c_uint32),
              ("dirattr", ctypes.c_uint32),
              ("fileattr", ctypes.c_uint32),
              ("forkattr", ctypes.c_uint32),
          )
  
      # typedef struct attrreference {
      #     int32_t     attr_dataoffset;
      #     u_int32_t   attr_length;
      # } attrreference_t;
      class attrreference_t(ctypes.Structure):
          _fields_ = (
              ("attr_dataoffset", ctypes.c_int32),
              ("attr_length", ctypes.c_uint32),
          )
  
      _fields_ = (
          ("length", ctypes.c_uint32),
          ("attrset", attribute_set_t),
          ("name", attrreference_t),
          ("st_dev", ctypes.c_int32),
          ("objtype", ctypes.c_uint32),
          ("st_birthtimespec", timespec_t),
          ("st_mtimespec", timespec_t),
          ("st_ctimespec", timespec_t),
          ("st_atimespec", timespec_t),
          ("st_uid", ctypes.c_uint32),
          ("st_gid", ctypes.c_uint32),
          ("accessmask", ctypes.c_uint32),
          ("st_flags", ctypes.c_uint32),
          ("st_ino", ctypes.c_uint64),
          ("st_nlink", ctypes.c_uint32),
          ("allocsize", ctypes.c_int64),
          ("st_blksize", ctypes.c_uint32),
          ("st_rdev", ctypes.c_uint32),
          ("st_size", ctypes.c_uint32)
      )
  
  # struct attrlist {
  #     u_short bitmapcount;            /* number of attr. bit sets in list (should be 5) */
  #     u_int16_t reserved;         /* (to maintain 4-byte alignment) */
  #     attrgroup_t commonattr;         /* common attribute group */
  #     attrgroup_t volattr;            /* Volume attribute group */
  #     attrgroup_t dirattr;            /* directory attribute group */
  #     attrgroup_t fileattr;           /* file attribute group */
  #     attrgroup_t forkattr;           /* fork attribute group */
  # };
  
  class attrlist_t(ctypes.Structure):
      _fields_ = (
          ("bitmapcount", ctypes.c_ushort),
          ("reserved", ctypes.c_uint16),
          ("commonattr", ctypes.c_uint32),
          ("volattr", ctypes.c_uint32),
          ("dirattr", ctypes.c_uint32),
          ("fileattr", ctypes.c_uint32),
          ("forkattr", ctypes.c_uint32),
      )
  
      def __init__(self, ql, base):
          self.ql = ql
          self.base = base
  
      def updateToMem(self):
          self.ql.mem.write(self.base, bytes(self))
  
      def loadFromMem(self):
          data = self.ql.mem.read(self.base, ctypes.sizeof(self))
          newObj = type(self).from_buffer(data)
          newObj.ql = self.ql
          newObj.base = self.base
          return newObj
  
  # struct getattrlistbulk_args {
  #     char dirfd_l_[PADL_(int)]; int dirfd; char dirfd_r_[PADR_(int)];
  #     char alist_l_[PADL_(user_addr_t)]; user_addr_t alist; char alist_r_[PADR_(user_addr_t)];
  #     char attributeBuffer_l_[PADL_(user_addr_t)]; user_addr_t attributeBuffer; char attributeBuffer_r_[PADR_(user_addr_t)];
  #     char bufferSize_l_[PADL_(user_size_t)]; user_size_t bufferSize; char bufferSize_r_[PADR_(user_size_t)];
  #     char options_l_[PADL_(uint64_t)]; uint64_t options; char options_r_[PADR_(uint64_t)];
  # };
  
  class getattrlistbulk_args_t(ctypes.Structure):
      _fields_ = (
          ("dirfd", ctypes.c_int),
          ("dirfd_r_", ctypes.c_byte * 4),
          ("alist", ctypes.c_uint64),
          ("attributeBuffer", ctypes.c_uint64),
          ("bufferSize", ctypes.c_uint64),
          ("options", ctypes.c_uint64),
      )
  
      def __init__(self, ql, base):
          self.ql = ql
          self.base = base
  
      def updateToMem(self):
          self.ql.mem.write(self.base, bytes(self))
  
      def loadFromMem(self):
          data = self.ql.mem.read(self.base, ctypes.sizeof(self))
          newObj = type(self).from_buffer(data)
          newObj.ql = self.ql
          newObj.base = self.base
          return newObj
  
  # /* use kern_iovec for system space requests */
  # struct kern_iovec {
  #     u_int64_t   iov_base;   /* Base address. */
  #     u_int64_t   iov_len;    /* Length. */
  # };
  
  # /* use user_iovec for user space requests */
  # struct user_iovec {
  #     user_addr_t iov_base;   /* Base address. */
  #     user_size_t iov_len;    /* Length. */
  # };
  
  # union iovecs {
  #     struct kern_iovec   *kiovp;
  #     struct user_iovec   *uiovp;
  # };
  
  # /* WARNING - use accessor calls for uio_iov and uio_resid since these */
  # /* fields vary depending on the originating address space. */
  # struct uio {
  #     union iovecs    uio_iovs;       /* current iovec */
  #     int             uio_iovcnt;     /* active iovecs */
  #     off_t           uio_offset;
  #     enum uio_seg    uio_segflg;
  #     enum uio_rw     uio_rw;
  #     user_size_t uio_resid_64;
  #     int             uio_size;       /* size for use with kfree */
  #     int             uio_max_iovs;   /* max number of iovecs this uio_t can hold */
  #     u_int32_t       uio_flags;      
  # };
  
  class kern_iovec_t(ctypes.Structure):
      _fields_ = (
          ("iov_base", ctypes.c_uint64),
          ("iov_len", ctypes.c_uint64),
      )
  
  class user_iovec_t(ctypes.Structure):
      _fields_ = (
          ("iov_base", ctypes.c_uint64),
          ("iov_len", ctypes.c_uint64),
      )
  
      def __init__(self, ql, base):
          self.ql = ql
          self.base = base
  
      def updateToMem(self):
          self.ql.mem.write(self.base, bytes(self))
  
      def loadFromMem(self):
          data = self.ql.mem.read(self.base, ctypes.sizeof(self))
          newObj = type(self).from_buffer(data)
          newObj.ql = self.ql
          newObj.base = self.base
          return newObj
  
  class iovecs_t(ctypes.Union):
      _fields_ = (
          ("kiovp", POINTER64),
          ("uiovp", POINTER64),
      )
  
  class uio_t(ctypes.Structure):
      _fields_ = (
          ("uio_iovs", iovecs_t),
          ("uio_iovcnt", ctypes.c_int),
          ("uio_offset", ctypes.c_int64),
          ("uio_segflg", ctypes.c_int),
          ("uio_rw", ctypes.c_int),
          ("uio_resid_64", ctypes.c_uint64),
          ("uio_size", ctypes.c_int),
          ("uio_max_iovs", ctypes.c_int),
          ("uio_flags", ctypes.c_uint32),
      )
  
      def __init__(self, ql, base):
          self.ql = ql
          self.base = base
  
      def updateToMem(self):
          self.ql.mem.write(self.base, bytes(self))
  
      def loadFromMem(self):
          data = self.ql.mem.read(self.base, ctypes.sizeof(self))
          newObj = type(self).from_buffer(data)
          newObj.ql = self.ql
          newObj.base = self.base
          return newObj
  
  # struct vnode_attr {
  #     uint64_t    va_supported;
  #     uint64_t    va_active;
  #     int     va_vaflags;
      
  #     dev_t       va_rdev;    /* device id (device nodes only) */
  #     uint64_t    va_nlink;   /* number of references to this file */
  #     uint64_t    va_total_size;  /* size in bytes of all forks */
  #     uint64_t    va_total_alloc; /* disk space used by all forks */
  #     uint64_t    va_data_size;   /* size in bytes of the fork managed by current vnode */
  #     uint64_t    va_data_alloc;  /* disk space used by the fork managed by current vnode */
  #     uint32_t    va_iosize;  /* optimal I/O blocksize */
  
  #     uid_t       va_uid;     /* owner UID */
  #     gid_t       va_gid;     /* owner GID */
  #     mode_t      va_mode;    /* posix permissions */
  #     uint32_t    va_flags;   /* file flags */
  #     struct kauth_acl *va_acl;   /* access control list */
  
  #     struct timespec va_create_time; /* time of creation */
  #     struct timespec va_access_time; /* time of last access */
  #     struct timespec va_modify_time; /* time of last data modification */
  #     struct timespec va_change_time; /* time of last metadata change */
  #     struct timespec va_backup_time; /* time of last backup */
      
  #     uint64_t    va_fileid;  /* file unique ID in filesystem */
  #     uint64_t    va_linkid;  /* file link unique ID */
  #     uint64_t    va_parentid;    /* parent ID */
  #     uint32_t    va_fsid;    /* filesystem ID */
  #     uint64_t    va_filerev; /* file revision counter */ /* XXX */
  #     uint32_t    va_gen;     /* file generation count */ /* XXX - relationship of
  #                                     * these two? */
  #     uint32_t    va_encoding;    /* filename encoding script */
  
  #     enum vtype  va_type;    /* file type */
  #     char *      va_name;    /* Name for ATTR_CMN_NAME; MAXPATHLEN bytes */
  #     guid_t      va_uuuid;   /* file owner UUID */
  #     guid_t      va_guuid;   /* file group UUID */
      
  #     uint64_t    va_nchildren;     /* Number of items in a directory */
  #     uint64_t    va_dirlinkcount;  /* Real references to dir (i.e. excluding "." and ".." refs) */
  
  #     struct kauth_acl *va_base_acl;
  #     struct timespec va_addedtime;   /* timestamp when item was added to parent directory */
          
  #     uint32_t va_dataprotect_class;  /* class specified for this file if it didn't exist */
  #     uint32_t va_dataprotect_flags;  /* flags from NP open(2) to the filesystem */
  
  #     uint32_t va_document_id;
  
  #     uint32_t    va_devid;   /* devid of filesystem */
  #     uint32_t    va_objtype; /* type of object */
  #     uint32_t    va_objtag;  /* vnode tag of filesystem */
  #     uint32_t    va_user_access; /* access for user */
  #     uint8_t     va_finderinfo[32];  /* Finder Info */
  #     uint64_t    va_rsrc_length; /* Resource Fork length */
  #     uint64_t    va_rsrc_alloc;  /* Resource Fork allocation size */
  #     fsid_t      va_fsid64;  /* fsid, of the correct type  */
  
  #     uint32_t va_write_gencount;     /* counter that increments each time the file changes */
  
  #     uint64_t va_private_size; /* If the file were deleted, how many bytes would be freed immediately */
  # };
  
  class vnode_attr_t(ctypes.Structure):
      # typedef struct {
      # #define KAUTH_GUID_SIZE 16  /* 128-bit identifier */
      #     unsigned char g_guid[KAUTH_GUID_SIZE];
      # } guid_t;
      class guid_t(ctypes.Structure):
          _fields_ = (
              ("g_guid", ctypes.c_ubyte * 16),
          )
  
      # typedef struct fsid { int32_t val[2]; } fsid_t; /* file system id type */
      class fsid_t(ctypes.Structure):
          _fields_ = (
              ("val", ctypes.c_int32 * 2),
          )
  
      _fields_ = (
          ("va_supported", ctypes.c_uint64),
          ("va_active", ctypes.c_uint64),
          ("va_vaflags", ctypes.c_int),
  
          ("va_rdev", ctypes.c_int32),
          ("va_nlink", ctypes.c_uint64),
          ("va_total_size", ctypes.c_uint64),
          ("va_total_alloc", ctypes.c_uint64),
          ("va_data_size", ctypes.c_uint64),
          ("va_data_alloc", ctypes.c_uint64),
          ("va_iosize", ctypes.c_uint32),
  
          ("va_uid", ctypes.c_uint32),
          ("va_gid", ctypes.c_uint32),
          ("va_mode", ctypes.c_uint16),
          ("va_flags", ctypes.c_uint32),
          ("va_acl", POINTER64),
  
          ("va_create_time", timespec_t),
          ("va_access_time", timespec_t),
          ("va_modify_time", timespec_t),
          ("va_change_time", timespec_t),
          ("va_backup_time", timespec_t),
  
          ("va_fileid", ctypes.c_uint64),
          ("va_linkid", ctypes.c_uint64),
          ("va_parentid", ctypes.c_uint64),
          ("va_fsid", ctypes.c_uint32),
          ("va_filerev", ctypes.c_uint64),
          ("va_gen", ctypes.c_uint32),
  
          ("va_encoding", ctypes.c_uint32),
  
          ("va_type", ctypes.c_int),
          ("va_name", POINTER64),
          ("va_uuuid", guid_t),
          ("va_guuid", guid_t),
  
          ("va_nchildren", ctypes.c_uint64),
          ("va_dirlinkcount", ctypes.c_uint64),
  
          ("va_base_acl", POINTER64),
          ("va_addedtime", timespec_t),
  
          ("va_dataprotect_class", ctypes.c_uint32),
          ("va_dataprotect_flags", ctypes.c_uint32),
          ("va_document_id", ctypes.c_uint32),
  
          ("va_devid", ctypes.c_uint32),
          ("va_objtype", ctypes.c_uint32),
          ("va_objtag", ctypes.c_uint32),
          ("va_user_access", ctypes.c_uint32),
          ("va_finderinfo", ctypes.c_uint8 * 32),
          ("va_rsrc_length", ctypes.c_uint64),
          ("va_rsrc_alloc", ctypes.c_uint64),
          ("va_fsid64", fsid_t),
  
          ("va_write_gencount", ctypes.c_uint32),
  
          ("va_private_size", ctypes.c_uint64),
      )
  
      def __init__(self, ql, base):
          self.ql = ql
          self.base = base
  
      def updateToMem(self):
          self.ql.mem.write(self.base, bytes(self))
  
      def loadFromMem(self):
          data = self.ql.mem.read(self.base, ctypes.sizeof(self))
          newObj = type(self).from_buffer(data)
          newObj.ql = self.ql
          newObj.base = self.base
          return newObj