xref: /xnu-11215.41.3/osfmk/kdp/kdp_common.h (revision 33de042d024d46de5ff4e89f2471de6608e37fa4)
1 /*
2  * Copyright (c) 2021 Apple Computer, 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 #ifndef __KDP_COMMON_H
29 #define __KDP_COMMON_H
30 
31 #ifdef XNU_KERNEL_PRIVATE
32 
33 #include <kern/task.h>
34 #include <vm/vm_map.h>
35 
36 /*
37  * Wrapper around memcpy.
38  * This copies individual bytes if running in the panic context. Otherwise, this
39  * calls the standard memcpy function.
40  */
41 void kdp_memcpy(void *dst, const void *src, size_t len);
42 
43 /*
44  * A version of strlcpy that is safe to run from the panic context. This calls
45  * kdp_memcpy() internally, which copies individual bytes if running in the panic context.
46  */
47 size_t kdp_strlcpy(char *dst, const char *src, size_t maxlen);
48 
49 /*
50  * Get the page size from the specified vm map. This correctly handles K16/U4 (Rosetta) and
51  * K4/U16 (armv7k) environments.
52  */
53 size_t kdp_vm_map_get_page_size(vm_map_t map, size_t *effective_page_mask);
54 
55 __options_closed_decl(kdp_fault_result_flags_t, uint32_t, {
56 	KDP_FAULT_RESULT_PAGED_OUT = 0x1, /* some data was unable to be retrieved */
57 	KDP_FAULT_RESULT_TRIED_FAULT = 0x2, /* tried to fault in data */
58 	KDP_FAULT_RESULT_FAULTED_IN = 0x3, /* successfully faulted in data */
59 });
60 
61 struct kdp_fault_result {
62 	kdp_fault_result_flags_t flags;
63 	uint64_t time_spent_faulting;
64 };
65 
66 __options_closed_decl(kdp_fault_flags_t, uint32_t, {
67 	KDP_FAULT_FLAGS_NONE = 0x0,
68 	KDP_FAULT_FLAGS_ENABLE_FAULTING = 0x1, /* try faulting if pages are not resident */
69 	KDP_FAULT_FLAGS_MULTICPU = 0x2, /* multicpu kdp context */
70 });
71 
72 __options_closed_decl(kdp_traverse_mappings_flags_t, uint32_t, {
73 	KDP_TRAVERSE_MAPPINGS_FLAGS_NONE = 0x0,
74 	KDP_TRAVERSE_MAPPINGS_FLAGS_PHYSICAL = 0x1 /* Use physical addresses instead of virtual addresses */
75 });
76 
77 typedef int (*kdp_traverse_mappings_callback)(vm_offset_t start, vm_offset_t end, void *context);
78 
79 /*
80  * Traverse mappings in the specified task.
81  *
82  * - task                      The task
83  * - fault_flags               Controls whether to fault in pages that are not resident.
84  * - traverse_mappings_flags   Controls whether the callback is called with physical addresses
85  * - callback                  The callback is called for each memory region.
86  * - context                   Context passed to the callback.
87  */
88 kern_return_t
89 kdp_traverse_mappings(
90 	task_t task,
91 	kdp_fault_flags_t fault_flags,
92 	kdp_traverse_mappings_flags_t traverse_mappings_flags,
93 	kdp_traverse_mappings_callback callback,
94 	void * context);
95 
96 /*
97  * Get dyld information from the specified task
98  *
99  * - task               The task
100  * - fault_flags        Controls whether to fault in pages that are not resident.
101  * - dyld_load_address  The dyld load address is stored here.
102  * - dyld_uuid          The dyld uuid is stored here.
103  * - task_page_size     The task's page size is stored here.
104  */
105 kern_return_t
106 kdp_task_dyld_info(task_t task, kdp_fault_flags_t fault_flags, uint64_t * dyld_load_address, uuid_t dyld_uuid, size_t * task_page_size);
107 
108 /*
109  * Returns the physical address of the specified map:target address,
110  * using the kdp fault path if requested and the page is not resident.
111  */
112 vm_offset_t kdp_find_phys(vm_map_t map, vm_offset_t target_addr, kdp_fault_flags_t fault_flags, struct kdp_fault_result *fault_results);
113 
114 /*
115  * Generic function to find a physical page for the specified map:target_addr.
116  */
117 typedef vm_offset_t (*find_phys_fn_t)(vm_map_t map, vm_offset_t target_addr, kdp_fault_flags_t fault_flags, void * context);
118 
119 /*
120  * Generic copyin from userspace vm map.
121  *
122  * - map             The vm map to use
123  * - uaddr           Userspace VA to copy bytes from
124  * - dest            Destination address
125  * - size            Number of bytes to copy
126  * - fault_flags     Controls whether to fault in pages that are not resident. This is passed to `find_phys_fn`.
127  * - find_phys_fn    The function to use to return a physical address given a map and target address.
128  *                   If additional filtering/handling is not required, use `(find_phys_fn_t)kdp_find_phys`
129  *                   for this parameter.
130  * - context         Reference context passed to find_phys_fn
131  *
132  * Copies in `size` bytes from `map:uaddr` to `dest`, using the specified function to find a physical address.
133  * Returns 0 if successful, an errno otherwise.
134  */
135 int kdp_generic_copyin(vm_map_t map, uint64_t uaddr, void *dest, size_t size, kdp_fault_flags_t fault_flags, find_phys_fn_t find_phys_fn, void *context);
136 
137 /*
138  * Copies in a word from the specified task and address.
139  *
140  * - task            The task to use
141  * - addr            Address to copy from
142  * - result          Where to store result
143  * - fault_flags     Controls whether to fault in pages that are not resident. This is passed to `find_phys_fn`
144  * - find_phys_fn    The function to use to return a physical address given a map and target address.
145  *                   If additional filtering/handling is not required, use `(find_phys_fn_t)kdp_find_phys`
146  *                   for this parameter.
147  * - context         Reference context passed to find_phys_fn
148  *
149  * Returns 0 if successful, an errno otherwise.
150  */
151 int kdp_generic_copyin_word(task_t task, uint64_t addr, uint64_t *result, kdp_fault_flags_t fault_flags, find_phys_fn_t find_phys_fn, void *context);
152 
153 /*
154  * Copies in a string from the specified task and address.
155  *
156  * - task            The task to use
157  * - addr            Address to copy from
158  * - buf             Where to store result
159  * - buf_sz          Size of destination buffer
160  * - fault_flags     Controls whether to fault in pages that are not resident. This is passed to `find_phys_fn`
161  * - find_phys_fn    The function to use to return a physical address given a map and target address.
162  *                   If additional filtering/handling is not required, use `(find_phys_fn_t)kdp_find_phys`
163  *                   for this parameter.
164  * - context         Reference context passed to find_phys_fn
165  *
166  * Returns number of bytes copied if successful, -1 otherwise.
167  */
168 int kdp_generic_copyin_string(task_t task, uint64_t addr, char *buf, int buf_sz, kdp_fault_flags_t fault_flags, find_phys_fn_t find_phys_fn, void *context);
169 
170 #endif /* XNU_KERNEL_PRIVATE */
171 
172 #endif /* __KDP_COMMON_H */
173