xref: /xnu-8796.101.5/osfmk/kdp/kdp_common.h (revision aca3beaa3dfbd42498b42c5e5ce20a938e6554e5)
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 });
70 
71 __options_closed_decl(kdp_traverse_mappings_flags_t, uint32_t, {
72 	KDP_TRAVERSE_MAPPINGS_FLAGS_NONE = 0x0,
73 	KDP_TRAVERSE_MAPPINGS_FLAGS_PHYSICAL = 0x1 /* Use physical addresses instead of virtual addresses */
74 });
75 
76 typedef int (*kdp_traverse_mappings_callback)(vm_offset_t start, vm_offset_t end, void *context);
77 
78 /*
79  * Traverse mappings in the specified task.
80  *
81  * - task                      The task
82  * - fault_flags               Controls whether to fault in pages that are not resident.
83  * - traverse_mappings_flags   Controls whether the callback is called with physical addresses
84  * - callback                  The callback is called for each memory region.
85  * - context                   Context passed to the callback.
86  */
87 kern_return_t
88 kdp_traverse_mappings(
89 	task_t task,
90 	kdp_fault_flags_t fault_flags,
91 	kdp_traverse_mappings_flags_t traverse_mappings_flags,
92 	kdp_traverse_mappings_callback callback,
93 	void * context);
94 
95 /*
96  * Get dyld information from the specified task
97  *
98  * - task               The task
99  * - fault_flags        Controls whether to fault in pages that are not resident.
100  * - dyld_load_address  The dyld load address is stored here.
101  * - dyld_uuid          The dyld uuid is stored here.
102  * - task_page_size     The task's page size is stored here.
103  */
104 kern_return_t
105 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);
106 
107 /*
108  * Returns the physical address of the specified map:target address,
109  * using the kdp fault path if requested and the page is not resident.
110  */
111 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);
112 
113 /*
114  * Generic function to find a physical page for the specified map:target_addr.
115  */
116 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);
117 
118 /*
119  * Generic copyin from userspace vm map.
120  *
121  * - map             The vm map to use
122  * - uaddr           Userspace VA to copy bytes from
123  * - dest            Destination address
124  * - size            Number of bytes to copy
125  * - fault_flags     Controls whether to fault in pages that are not resident. This is passed to `find_phys_fn`.
126  * - find_phys_fn    The function to use to return a physical address given a map and target address.
127  *                   If additional filtering/handling is not required, use `(find_phys_fn_t)kdp_find_phys`
128  *                   for this parameter.
129  * - context         Reference context passed to find_phys_fn
130  *
131  * Copies in `size` bytes from `map:uaddr` to `dest`, using the specified function to find a physical address.
132  * Returns 0 if successful, an errno otherwise.
133  */
134 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);
135 
136 /*
137  * Copies in a word from the specified task and address.
138  *
139  * - task            The task to use
140  * - addr            Address to copy from
141  * - result          Where to store result
142  * - fault_flags     Controls whether to fault in pages that are not resident. This is passed to `find_phys_fn`
143  * - find_phys_fn    The function to use to return a physical address given a map and target address.
144  *                   If additional filtering/handling is not required, use `(find_phys_fn_t)kdp_find_phys`
145  *                   for this parameter.
146  * - context         Reference context passed to find_phys_fn
147  *
148  * Returns 0 if successful, an errno otherwise.
149  */
150 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);
151 
152 /*
153  * Copies in a string from the specified task and address.
154  *
155  * - task            The task to use
156  * - addr            Address to copy from
157  * - buf             Where to store result
158  * - buf_sz          Size of destination buffer
159  * - fault_flags     Controls whether to fault in pages that are not resident. This is passed to `find_phys_fn`
160  * - find_phys_fn    The function to use to return a physical address given a map and target address.
161  *                   If additional filtering/handling is not required, use `(find_phys_fn_t)kdp_find_phys`
162  *                   for this parameter.
163  * - context         Reference context passed to find_phys_fn
164  *
165  * Returns number of bytes copied if successful, -1 otherwise.
166  */
167 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);
168 
169 #endif /* XNU_KERNEL_PRIVATE */
170 
171 #endif /* __KDP_COMMON_H */
172