/ duct-tape / xnu / osfmk / kern / kern_cdata.h
kern_cdata.h
  1  /*
  2   * Copyright (c) 2015 Apple Inc. All rights reserved.
  3   *
  4   * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  5   *
  6   * This file contains Original Code and/or Modifications of Original Code
  7   * as defined in and that are subject to the Apple Public Source License
  8   * Version 2.0 (the 'License'). You may not use this file except in
  9   * compliance with the License. The rights granted to you under the License
 10   * may not be used to create, or enable the creation or redistribution of,
 11   * unlawful or unlicensed copies of an Apple operating system, or to
 12   * circumvent, violate, or enable the circumvention or violation of, any
 13   * terms of an Apple operating system software license agreement.
 14   *
 15   * Please obtain a copy of the License at
 16   * http://www.opensource.apple.com/apsl/ and read it before using this file.
 17   *
 18   * The Original Code and all software distributed under the License are
 19   * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 20   * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 21   * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 22   * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 23   * Please see the License for the specific language governing rights and
 24   * limitations under the License.
 25   *
 26   * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
 27   */
 28  
 29  #ifndef _KERN_CDATA_H_
 30  #define _KERN_CDATA_H_
 31  
 32  #include <kern/kcdata.h>
 33  #include <mach/mach_types.h>
 34  #ifdef XNU_KERNEL_PRIVATE
 35  #include <libkern/zlib.h>
 36  #endif
 37  
 38  /*
 39   * Do not use these macros!
 40   *
 41   * Instead, you should use kcdata_iter_* functions defined in kcdata.h.  These
 42   * macoros have no idea where the kcdata buffer ends, so they are all unsafe.
 43   */
 44  #define KCDATA_ITEM_HEADER_SIZE         (sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint64_t))
 45  #define KCDATA_ITEM_ITER(item)          kcdata_iter_unsafe((void*)(item))
 46  #define KCDATA_ITEM_TYPE(item)          kcdata_iter_type(KCDATA_ITEM_ITER(item))
 47  #define KCDATA_ITEM_SIZE(item)          kcdata_iter_size(KCDATA_ITEM_ITER(item))
 48  #define KCDATA_ITEM_FLAGS(item)         kcdata_iter_flags(KCDATA_ITEM_ITER(item))
 49  #define KCDATA_ITEM_ARRAY_GET_EL_TYPE(item)    kcdata_iter_array_elem_type(KCDATA_ITEM_ITER(item))
 50  #define KCDATA_ITEM_ARRAY_GET_EL_COUNT(item)   kcdata_iter_array_elem_count(KCDATA_ITEM_ITER(item))
 51  #define KCDATA_ITEM_ARRAY_GET_EL_SIZE(item)    kcdata_iter_array_elem_size(KCDATA_ITEM_ITER(item))
 52  #define KCDATA_CONTAINER_ID(item)              kcdata_iter_container_id(KCDATA_ITEM_ITER(item))
 53  #define KCDATA_ITEM_NEXT_HEADER(itemx)   (kcdata_iter_next(KCDATA_ITEM_ITER(itemx)).item)
 54  #define KCDATA_ITEM_FOREACH(head)       for (; KCDATA_ITEM_TYPE(head) != KCDATA_TYPE_BUFFER_END; (head) = KCDATA_ITEM_NEXT_HEADER(head))
 55  #define KCDATA_ITEM_DATA_PTR(item)      kcdata_iter_payload(KCDATA_ITEM_ITER(item))
 56  #define KCDATA_ITEM_FIND_TYPE(itemx, type) (kcdata_iter_find_type(KCDATA_ITEM_ITER(itemx), type).item)
 57  #define kcdata_get_container_type(buffer) kcdata_iter_container_type(KCDATA_ITEM_ITER(buffer))
 58  #define kcdata_get_data_with_desc(buf, desc, data) kcdata_iter_get_data_with_desc(KCDATA_ITEM_ITER(buf),desc,data,NULL)
 59  /* Do not use these macros! */
 60  
 61  __options_decl(kcd_compression_type_t, uint64_t, {
 62  	KCDCT_NONE = 0x00,
 63  	KCDCT_ZLIB = 0x01,
 64  });
 65  
 66  #ifdef KERNEL
 67  #ifdef XNU_KERNEL_PRIVATE
 68  
 69  __options_decl(kcd_cd_flag_t, uint64_t, {
 70  	KCD_CD_FLAG_IN_MARK  = 0x01,
 71  	KCD_CD_FLAG_FINALIZE = 0x02,
 72  });
 73  
 74  /* Structure to save zstream and other compression metadata */
 75  struct kcdata_compress_descriptor {
 76  	z_stream kcd_cd_zs;
 77  	void *kcd_cd_base;
 78  	uint64_t kcd_cd_offset;
 79  	size_t kcd_cd_maxoffset;
 80  	uint64_t kcd_cd_mark_begin;
 81  	kcd_cd_flag_t kcd_cd_flags;
 82  	kcd_compression_type_t kcd_cd_compression_type;
 83  	void (*kcd_cd_memcpy_f)(void *, const void *, size_t);
 84  	mach_vm_address_t kcd_cd_totalout_addr;
 85  	mach_vm_address_t kcd_cd_totalin_addr;
 86  };
 87  
 88  /*
 89   * Various, compression algorithm agnostic flags for controlling writes to the
 90   * output buffer.
 91   */
 92  enum kcdata_compression_flush {
 93  	/*
 94  	 * Hint that no flush is needed because more data is expected. Doesn't
 95  	 * guarantee that no data will be written to the output buffer, since the
 96  	 * underlying algorithm may decide that it's running out of space and may
 97  	 * flush to the output buffer.
 98  	 */
 99  	KCDCF_NO_FLUSH,
100  	/*
101  	 * Hint to flush all internal buffers to the output buffers.
102  	 */
103  	KCDCF_SYNC_FLUSH,
104  	/*
105  	 * Hint that this is going to be the last call to the compression function,
106  	 * so flush all output buffers and mark state as finished.
107  	 */
108  	KCDCF_FINISH,
109  };
110  
111  /* Structure to save information about kcdata */
112  struct kcdata_descriptor {
113  	uint32_t            kcd_length;
114  	uint16_t kcd_flags;
115  #define KCFLAG_USE_MEMCOPY 0x0
116  #define KCFLAG_USE_COPYOUT 0x1
117  #define KCFLAG_NO_AUTO_ENDBUFFER 0x2
118  #define KCFLAG_USE_COMPRESSION 0x4
119  	uint16_t kcd_user_flags; /* reserved for subsystems using kcdata */
120  	mach_vm_address_t kcd_addr_begin;
121  	mach_vm_address_t kcd_addr_end;
122  	struct kcdata_compress_descriptor kcd_comp_d;
123  };
124  
125  typedef struct kcdata_descriptor * kcdata_descriptor_t;
126  
127  kcdata_descriptor_t kcdata_memory_alloc_init(mach_vm_address_t crash_data_p, unsigned data_type, unsigned size, unsigned flags);
128  kern_return_t kcdata_memory_static_init(
129  	kcdata_descriptor_t data, mach_vm_address_t buffer_addr_p, unsigned data_type, unsigned size, unsigned flags);
130  kern_return_t kcdata_memory_destroy(kcdata_descriptor_t data);
131  kern_return_t
132  kcdata_add_container_marker(kcdata_descriptor_t data, uint32_t header_type, uint32_t container_type, uint64_t identifier);
133  kern_return_t kcdata_add_type_definition(kcdata_descriptor_t data,
134      uint32_t type_id,
135      char * type_name,
136      struct kcdata_subtype_descriptor * elements_array_addr,
137      uint32_t elements_count);
138  
139  kern_return_t kcdata_add_uint64_with_description(kcdata_descriptor_t crashinfo, uint64_t data, const char * description);
140  kern_return_t kcdata_add_uint32_with_description(kcdata_descriptor_t crashinfo, uint32_t data, const char * description);
141  
142  kern_return_t kcdata_undo_add_container_begin(kcdata_descriptor_t data);
143  
144  kern_return_t kcdata_write_buffer_end(kcdata_descriptor_t data);
145  void *kcdata_memory_get_begin_addr(kcdata_descriptor_t data);
146  kern_return_t kcdata_init_compress(kcdata_descriptor_t, int hdr_tag, void (*memcpy_f)(void *, const void *, size_t), uint64_t type);
147  kern_return_t kcdata_push_data(kcdata_descriptor_t data, uint32_t type, uint32_t size, const void *input_data);
148  kern_return_t kcdata_push_array(kcdata_descriptor_t data, uint32_t type_of_element, uint32_t size_of_element, uint32_t count, const void *input_data);
149  kern_return_t kcdata_compress_memory_addr(kcdata_descriptor_t data, void *ptr);
150  kern_return_t kcdata_finish_compression(kcdata_descriptor_t data);
151  void kcdata_compression_window_open(kcdata_descriptor_t data);
152  kern_return_t kcdata_compression_window_close(kcdata_descriptor_t data);
153  void kcd_finalize_compression(kcdata_descriptor_t data);
154  
155  #else /* XNU_KERNEL_PRIVATE */
156  
157  typedef void * kcdata_descriptor_t;
158  
159  #endif /* XNU_KERNEL_PRIVATE */
160  
161  uint32_t kcdata_estimate_required_buffer_size(uint32_t num_items, uint32_t payload_size);
162  uint64_t kcdata_memory_get_used_bytes(kcdata_descriptor_t kcd);
163  uint64_t kcdata_memory_get_uncompressed_bytes(kcdata_descriptor_t kcd);
164  kern_return_t kcdata_memcpy(kcdata_descriptor_t data, mach_vm_address_t dst_addr, const void * src_addr, uint32_t size);
165  kern_return_t kcdata_bzero(kcdata_descriptor_t data, mach_vm_address_t dst_addr, uint32_t size);
166  kern_return_t kcdata_get_memory_addr(kcdata_descriptor_t data, uint32_t type, uint32_t size, mach_vm_address_t * user_addr);
167  kern_return_t kcdata_get_memory_addr_for_array(
168  	kcdata_descriptor_t data, uint32_t type_of_element, uint32_t size_of_element, uint32_t count, mach_vm_address_t * user_addr);
169  
170  #endif /* KERNEL */
171  #endif /* _KERN_CDATA_H_ */