1 /* 2 * Copyright (c) 2021 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 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 26 */ 27 #ifndef _KCOV_KSANCOV_DATA_H_ 28 #define _KCOV_KSANCOV_DATA_H_ 29 30 #if KERNEL_PRIVATE 31 32 #if CONFIG_KSANCOV 33 34 /* 35 * On arm64 the VM_MIN_KERNEL_ADDRESS is too far from %pc to fit into 32-bit value. As a result 36 * ksancov reports invalid %pcs. To make at least kernel %pc values corect a different base has 37 * to be used for arm. 38 */ 39 #if defined(__x86_64__) || defined(__i386__) 40 #define KSANCOV_PC_OFFSET VM_MIN_KERNEL_ADDRESS 41 #elif defined(__arm__) || defined(__arm64__) 42 #define KSANCOV_PC_OFFSET VM_KERNEL_LINK_ADDRESS 43 #else 44 #error "Unsupported platform" 45 #endif 46 47 48 /* 49 * Supported coverage modes. 50 */ 51 typedef enum { 52 KS_MODE_NONE, 53 KS_MODE_TRACE, 54 KS_MODE_COUNTERS, 55 KS_MODE_STKSIZE, 56 KS_MODE_MAX 57 } ksancov_mode_t; 58 59 /* 60 * A header that is always present in every ksancov mode shared memory structure. 61 */ 62 typedef struct ksancov_header { 63 uint32_t kh_magic; 64 _Atomic uint32_t kh_enabled; 65 } ksancov_header_t; 66 67 /* 68 * TRACE mode data structure. 69 */ 70 71 /* 72 * All trace based tools share this structure. 73 */ 74 typedef struct ksancov_trace { 75 ksancov_header_t kt_hdr; /* header (must be always first) */ 76 uintptr_t kt_offset; /* All recorded PCs are relateive to this offset. */ 77 uint32_t kt_maxent; /* Maximum entries in this shared buffer. */ 78 _Atomic uint32_t kt_head; /* Pointer to the first unused element. */ 79 uint64_t kt_entries[]; /* Trace entries in this buffer. */ 80 } ksancov_trace_t; 81 82 83 /* PC tracing only records PC deltas from the offset. */ 84 typedef uint32_t ksancov_trace_pc_ent_t; 85 86 /* STKSIZE tracing records PC deltas and stack size. */ 87 typedef struct ksancov_trace_stksize_entry { 88 uint32_t pc; /* PC-delta (offset relative) */ 89 uint32_t stksize; /* associated stack size */ 90 } ksancov_trace_stksize_ent_t; 91 92 /* 93 * COUNTERS mode data structure. 94 */ 95 typedef struct ksancov_counters { 96 ksancov_header_t kc_hdr; 97 uint32_t kc_nedges; /* total number of edges */ 98 uint8_t kc_hits[]; /* hits on each edge (8bit saturating) */ 99 } ksancov_counters_t; 100 101 /* 102 * Edge to PC mapping. 103 */ 104 typedef struct ksancov_edgemap { 105 uint32_t ke_magic; 106 uint32_t ke_nedges; 107 uintptr_t ke_offset; /* edge addrs relative to this */ 108 uint32_t ke_addrs[]; /* address of each edge relative to 'offset' */ 109 } ksancov_edgemap_t; 110 111 /* 112 * Represents state of a ksancov device when userspace asks for coverage data recording. 113 */ 114 115 struct ksancov_dev { 116 ksancov_mode_t mode; 117 118 union { 119 ksancov_header_t *hdr; 120 ksancov_trace_t *trace; 121 ksancov_counters_t *counters; 122 }; 123 size_t sz; /* size of allocated trace/counters buffer */ 124 125 size_t maxpcs; 126 127 thread_t thread; 128 dev_t dev; 129 lck_mtx_t lock; 130 }; 131 typedef struct ksancov_dev * ksancov_dev_t; 132 133 134 #endif /* CONFIG_KSANCOV */ 135 136 #endif /* KERNEL_PRIVATE */ 137 138 #endif /* _KCOV_KSANCOV_DATA_H_ */ 139