]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/kern/kern_cdata.h
xnu-6153.61.1.tar.gz
[apple/xnu.git] / osfmk / kern / kern_cdata.h
index ac02b62d7c2bf5ffac08578a34425caad3d7d048..398e8a122459bae1de4174cb84eeedb8a3370476 100644 (file)
 #ifndef _KERN_CDATA_H_
 #define _KERN_CDATA_H_
 
-#include <stdint.h>
+#include <kern/kcdata.h>
 #include <mach/mach_types.h>
 
-#define KCDATA_DESC_MAXLEN          32      /* including NULL byte at end */
-
-struct kcdata_item {
-       uint32_t type;
-       uint32_t size; /* len(data)  */
-       uint64_t flags;
-#ifndef KERNEL
-       char data[];  /* must be at the end */
-#endif
-};
-
-typedef struct kcdata_item * kcdata_item_t;
-
-enum KCDATA_SUBTYPE_TYPES { KC_ST_CHAR = 1, KC_ST_INT8, KC_ST_UINT8, KC_ST_INT16, KC_ST_UINT16, KC_ST_INT32, KC_ST_UINT32, KC_ST_INT64, KC_ST_UINT64 };
-typedef enum KCDATA_SUBTYPE_TYPES kctype_subtype_t;
-
-/*
- * A subtype description structure that defines
- * how a compound data is laid out in memory. This
- * provides on the fly definition of types and consumption
- * by the parser.
- */
-struct kcdata_subtype_descriptor {
-       uint8_t              kcs_flags;
-#define KCS_SUBTYPE_FLAGS_NONE    0x0
-#define KCS_SUBTYPE_FLAGS_ARRAY   0x1
-       uint8_t              kcs_elem_type;                 /* restricted to kctype_subtype_t */
-       uint16_t             kcs_elem_offset;               /* offset in struct where data is found */
-       uint32_t             kcs_elem_size;                 /* size of element (or) packed state for array type */
-       char                 kcs_name[KCDATA_DESC_MAXLEN];  /* max 31 bytes for name of field */
-};
-
-typedef struct kcdata_subtype_descriptor * kcdata_subtype_descriptor_t;
-
 /*
- * In case of array of basic c types in kctype_subtype_t,
- * size is packed in lower 16 bits and
- * count is packed in upper 16 bits of kcs_elem_size field.
- */
-#define KCS_SUBTYPE_PACK_SIZE(e_count,e_size)      (((e_count) & 0xffff) << 16 | ((e_size) & 0xffff))
-
-static inline uint32_t
-kcs_get_elem_size(kcdata_subtype_descriptor_t d)
-{
-       if (d->kcs_flags & KCS_SUBTYPE_FLAGS_ARRAY) {
-               /* size is composed as ((count &0xffff)<<16 | (elem_size & 0xffff)) */
-               return (uint32_t)((d->kcs_elem_size & 0xffff) * ((d->kcs_elem_size & 0xffff0000)>>16));
-       }
-       return d->kcs_elem_size;
-}
-
-static inline uint32_t
-kcs_get_elem_count(kcdata_subtype_descriptor_t d)
-{
-       if (d->kcs_flags & KCS_SUBTYPE_FLAGS_ARRAY)
-               return (d->kcs_elem_size >> 16) & 0xffff;
-       return 1;
-}
-
-static inline kern_return_t
-kcs_set_elem_size(kcdata_subtype_descriptor_t d, uint32_t size, uint32_t count)
-{
-       if (count > 1) {
-               /* means we are setting up an array */
-               if (size > 0xffff || count > 0xffff)
-                       return KERN_INVALID_ARGUMENT;
-               d->kcs_elem_size = ((count & 0xffff) << 16 | (size & 0xffff));
-       }
-       else
-       {
-               d->kcs_elem_size = size;
-       }
-       return KERN_SUCCESS;
-}
-
-struct kcdata_type_definition {
-       uint32_t kct_type_identifier;
-       uint32_t kct_num_elements;
-       char kct_name[KCDATA_DESC_MAXLEN];
-#ifndef KERNEL
-       struct kcdata_subtype_descriptor kct_elements[];
-#endif
-};
-
-/* chunk type definitions. 0 - 0x7ff are reserved  and defined here
- * NOTE: Please update libkdd/kcdata/kcdtypes.c if you make any changes
- * in STACKSHOT_KCTYPE_* types.
- */
-
-/*
- * Types with description value.
- * these will have KCDATA_DESC_MAXLEN-1 length string description
- * and rest of KCDATA_ITEM_SIZE() - KCDATA_DESC_MAXLEN bytes as data
- */
-#define KCDATA_TYPE_INVALID              0x0
-#define KCDATA_TYPE_STRING_DESC          0x1
-#define KCDATA_TYPE_UINT32_DESC          0x2
-#define KCDATA_TYPE_UINT64_DESC          0x3
-#define KCDATA_TYPE_INT32_DESC           0x4
-#define KCDATA_TYPE_INT64_DESC           0x5
-#define KCDATA_TYPE_BINDATA_DESC         0x6
-
-/*
- * Compound type definitions
- */
-#define KCDATA_TYPE_ARRAY                0x11       /* Array of data */
-#define KCDATA_TYPE_TYPEDEFINTION        0x12       /* Meta type that describes a type on the fly. */
-#define KCDATA_TYPE_CONTAINER_BEGIN      0x13       /* Container type which has corresponding CONTAINER_END header.
-                                                     * KCDATA_TYPE_CONTAINER_BEGIN has type in the data segment.
-                                                     * Both headers have (uint64_t) ID for matching up nested data.
-                                                     */
-#define KCDATA_TYPE_CONTAINER_END        0x14
-
-
-/*
- * Generic data types that are most commonly used
+ * Do not use these macros!
+ *
+ * Instead, you should use kcdata_iter_* functions defined in kcdata.h.  These
+ * macoros have no idea where the kcdata buffer ends, so they are all unsafe.
  */
-#define KCDATA_TYPE_LIBRARY_LOADINFO     0x30       /* struct dyld_uuid_info_32 */
-#define KCDATA_TYPE_LIBRARY_LOADINFO64   0x31       /* struct dyld_uuid_info_64 */
-#define KCDATA_TYPE_TIMEBASE             0x32       /* struct mach_timebase_info */
-#define KCDATA_TYPE_MACH_ABSOLUTE_TIME   0x33       /* uint64_t */
-#define KCDATA_TYPE_TIMEVAL              0x34       /* struct timeval64 */
-#define KCDATA_TYPE_USECS_SINCE_EPOCH    0x35       /* time in usecs uint64_t */
-
-#define KCDATA_TYPE_BUFFER_END      0xF19158ED
-
-/* MAGIC numbers defined for each class of chunked data */
-#define KCDATA_BUFFER_BEGIN_CRASHINFO  0xDEADF157   /* owner: corpses/task_corpse.h */
-                                                   /* type-range: 0x800 - 0x8ff */
-#define KCDATA_BUFFER_BEGIN_STACKSHOT  0x59a25807   /* owner: sys/stackshot.h */
-                                                   /* type-range: 0x900 - 0x9ff */
-
-/* next type range number available 0x1000 */
-
-/* Common MACROS and library functions */
-/* make header = sizeof(type, flags, size) */
 #define KCDATA_ITEM_HEADER_SIZE         (sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint64_t))
-#define KCDATA_ITEM_TYPE(item)          (((kcdata_item_t)(item))->type)
-#define KCDATA_ITEM_SIZE(item)          (((kcdata_item_t)(item))->size)
-#define KCDATA_ITEM_FLAGS(item)          (((kcdata_item_t)(item))->flags)
-
-#define KCDATA_ITEM_ARRAY_GET_EL_TYPE(item)   ((KCDATA_ITEM_FLAGS(item) >> 32) & UINT32_MAX)
-#define KCDATA_ITEM_ARRAY_GET_EL_COUNT(item)  (KCDATA_ITEM_FLAGS(item) & UINT32_MAX)
-#define KCDATA_ITEM_ARRAY_GET_EL_SIZE(item)   (KCDATA_ITEM_SIZE(item) / KCDATA_ITEM_ARRAY_GET_EL_COUNT(item))
-
-#define KCDATA_CONTAINER_ID(item)             ((uint64_t)KCDATA_ITEM_FLAGS(item))
-
-#define KCDATA_ITEM_NEXT_HEADER(item)   ((kcdata_item_t)((uint64_t)((uintptr_t)(item)) + KCDATA_ITEM_HEADER_SIZE + KCDATA_ITEM_SIZE(item)))
-
-#define KCDATA_ITEM_FOREACH(head) for (; KCDATA_ITEM_TYPE(head) != KCDATA_TYPE_BUFFER_END; (head) = KCDATA_ITEM_NEXT_HEADER(head))
-
-static inline kcdata_item_t
-KCDATA_ITEM_FIND_TYPE(kcdata_item_t head, uint32_t type)
-{
-       KCDATA_ITEM_FOREACH(head)
-       {
-               if (KCDATA_ITEM_TYPE(head) == type) {
-                       break;
-               }
-       }
-       return (KCDATA_ITEM_TYPE(head) == type) ? (kcdata_item_t)head : 0;
-}
-
-#ifndef KERNEL
-#define KCDATA_ITEM_DATA_PTR(item)      (&((kcdata_item_t)(item))->data)
-
-static inline uint32_t kcdata_get_container_type(kcdata_item_t buffer) {
-       if (KCDATA_ITEM_TYPE(buffer) == KCDATA_TYPE_CONTAINER_BEGIN)
-               return *(uint32_t *)KCDATA_ITEM_DATA_PTR(buffer);
-       return 0;
-}
-
-static inline void kcdata_get_data_with_desc(kcdata_item_t buffer, char **desc_ptr, void **data_ptr) {
-       if (desc_ptr)
-               *desc_ptr = (char *)KCDATA_ITEM_DATA_PTR(buffer);
-       if (data_ptr)
-               *data_ptr = (void *)((uintptr_t)KCDATA_ITEM_DATA_PTR(buffer) + KCDATA_DESC_MAXLEN);
-}
-#endif /* KERNEL */
+#define KCDATA_ITEM_ITER(item)          kcdata_iter_unsafe((void*)(item))
+#define KCDATA_ITEM_TYPE(item)          kcdata_iter_type(KCDATA_ITEM_ITER(item))
+#define KCDATA_ITEM_SIZE(item)          kcdata_iter_size(KCDATA_ITEM_ITER(item))
+#define KCDATA_ITEM_FLAGS(item)         kcdata_iter_flags(KCDATA_ITEM_ITER(item))
+#define KCDATA_ITEM_ARRAY_GET_EL_TYPE(item)    kcdata_iter_array_elem_type(KCDATA_ITEM_ITER(item))
+#define KCDATA_ITEM_ARRAY_GET_EL_COUNT(item)   kcdata_iter_array_elem_count(KCDATA_ITEM_ITER(item))
+#define KCDATA_ITEM_ARRAY_GET_EL_SIZE(item)    kcdata_iter_array_elem_size(KCDATA_ITEM_ITER(item))
+#define KCDATA_CONTAINER_ID(item)              kcdata_iter_container_id(KCDATA_ITEM_ITER(item))
+#define KCDATA_ITEM_NEXT_HEADER(itemx)   (kcdata_iter_next(KCDATA_ITEM_ITER(itemx)).item)
+#define KCDATA_ITEM_FOREACH(head)       for (; KCDATA_ITEM_TYPE(head) != KCDATA_TYPE_BUFFER_END; (head) = KCDATA_ITEM_NEXT_HEADER(head))
+#define KCDATA_ITEM_DATA_PTR(item)      kcdata_iter_payload(KCDATA_ITEM_ITER(item))
+#define KCDATA_ITEM_FIND_TYPE(itemx, type) (kcdata_iter_find_type(KCDATA_ITEM_ITER(itemx), type).item)
+#define kcdata_get_container_type(buffer) kcdata_iter_container_type(KCDATA_ITEM_ITER(buffer))
+#define kcdata_get_data_with_desc(buf, desc, data) kcdata_iter_get_data_with_desc(KCDATA_ITEM_ITER(buf),desc,data,NULL)
+/* Do not use these macros! */
+
+#ifdef KERNEL
 
 #ifdef XNU_KERNEL_PRIVATE
 
 /* Structure to save information about corpse data */
 struct kcdata_descriptor {
        uint32_t            kcd_length;
-       uint32_t            kcd_flags;
-#define KCFLAG_USE_MEMCOPY  0x0
-#define KCFLAG_USE_COPYOUT  0x1
-       mach_vm_address_t   kcd_addr_begin;
-       mach_vm_address_t   kcd_addr_end;
+       uint16_t kcd_flags;
+#define KCFLAG_USE_MEMCOPY 0x0
+#define KCFLAG_USE_COPYOUT 0x1
+#define KCFLAG_NO_AUTO_ENDBUFFER 0x2
+       uint16_t kcd_user_flags; /* reserved for subsystems using kcdata */
+       mach_vm_address_t kcd_addr_begin;
+       mach_vm_address_t kcd_addr_end;
 };
 
 typedef struct kcdata_descriptor * kcdata_descriptor_t;
 
 kcdata_descriptor_t kcdata_memory_alloc_init(mach_vm_address_t crash_data_p, unsigned data_type, unsigned size, unsigned flags);
-kern_return_t kcdata_memory_static_init(kcdata_descriptor_t data, mach_vm_address_t buffer_addr_p, unsigned data_type, unsigned size, unsigned flags);
+kern_return_t kcdata_memory_static_init(
+       kcdata_descriptor_t data, mach_vm_address_t buffer_addr_p, unsigned data_type, unsigned size, unsigned flags);
 kern_return_t kcdata_memory_destroy(kcdata_descriptor_t data);
-uint64_t kcdata_memory_get_used_bytes(kcdata_descriptor_t kcd);
-kern_return_t kcdata_memcpy(kcdata_descriptor_t data, mach_vm_address_t dst_addr, void *src_addr, uint32_t size);
+kern_return_t
+kcdata_add_container_marker(kcdata_descriptor_t data, uint32_t header_type, uint32_t container_type, uint64_t identifier);
+kern_return_t kcdata_add_type_definition(kcdata_descriptor_t data,
+    uint32_t type_id,
+    char * type_name,
+    struct kcdata_subtype_descriptor * elements_array_addr,
+    uint32_t elements_count);
+
+kern_return_t kcdata_add_uint64_with_description(kcdata_descriptor_t crashinfo, uint64_t data, const char * description);
+kern_return_t kcdata_add_uint32_with_description(kcdata_descriptor_t crashinfo, uint32_t data, const char * description);
 
-kern_return_t kcdata_get_memory_addr(kcdata_descriptor_t data, uint32_t type, uint32_t size, mach_vm_address_t *user_addr);
-kern_return_t kcdata_get_memory_addr_for_array(kcdata_descriptor_t data, uint32_t type_of_element, uint32_t size_of_element, uint32_t count, mach_vm_address_t *user_addr);
-kern_return_t kcdata_add_container_marker(kcdata_descriptor_t data, uint32_t header_type, uint32_t container_type, uint64_t identifier);
-kern_return_t kcdata_add_type_definition(kcdata_descriptor_t data, uint32_t type_id, char *type_name, struct kcdata_subtype_descriptor *elements_array_addr, uint32_t elements_count);
+kern_return_t kcdata_undo_add_container_begin(kcdata_descriptor_t data);
 
+kern_return_t kcdata_write_buffer_end(kcdata_descriptor_t data);
+void *kcdata_memory_get_begin_addr(kcdata_descriptor_t data);
 
-kern_return_t kcdata_add_uint64_with_description(kcdata_descriptor_t crashinfo, uint64_t data, const char *description);
-kern_return_t kcdata_add_uint32_with_description(kcdata_descriptor_t crashinfo, uint32_t data, const char *description);
+#else /* XNU_KERNEL_PRIVATE */
+
+typedef void * kcdata_descriptor_t;
 
 #endif /* XNU_KERNEL_PRIVATE */
 
+uint32_t kcdata_estimate_required_buffer_size(uint32_t num_items, uint32_t payload_size);
+uint64_t kcdata_memory_get_used_bytes(kcdata_descriptor_t kcd);
+kern_return_t kcdata_memcpy(kcdata_descriptor_t data, mach_vm_address_t dst_addr, const void * src_addr, uint32_t size);
+kern_return_t kcdata_bzero(kcdata_descriptor_t data, mach_vm_address_t dst_addr, uint32_t size);
+kern_return_t kcdata_get_memory_addr(kcdata_descriptor_t data, uint32_t type, uint32_t size, mach_vm_address_t * user_addr);
+kern_return_t kcdata_get_memory_addr_for_array(
+       kcdata_descriptor_t data, uint32_t type_of_element, uint32_t size_of_element, uint32_t count, mach_vm_address_t * user_addr);
+
+#endif /* KERNEL */
 #endif /* _KERN_CDATA_H_ */