]> git.saurik.com Git - apple/xnu.git/blob - libsa/dgraph.h
xnu-1228.7.58.tar.gz
[apple/xnu.git] / libsa / dgraph.h
1 /*
2 * Copyright (c) 2007 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 * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce
30 * support for mandatory and extensible security protections. This notice
31 * is included in support of clause 2.2 (b) of the Apple Public License,
32 * Version 2.0.
33 */
34 #ifndef __DGRAPH_H__
35 #define __DGRAPH_H__
36
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40
41 #ifdef KERNEL
42 #include <libsa/stdlib.h>
43 #include <IOKit/IOLib.h>
44 #else
45 #include <stdlib.h>
46 #include <mach/mach.h>
47 #endif /* KERNEL */
48
49 typedef struct dgraph_entry_t {
50
51 char is_kernel_component; // means that name is a CFBundleIdentifier!!!
52 char is_symbol_set;
53 char opaques;
54 char opaque_link;
55
56 // What we have to start from
57 char * name; // filename if user space, bundleid if kernel or kernel comp.
58
59 void * object; // In kernel we keep track of the object file
60 size_t object_length; // we don't own this, however; it's just a ref
61 #ifdef KERNEL
62 bool object_is_kmem; // Only used when mapping a file!
63 #endif /* KERNEL */
64
65 /* If is_kernel_component is true then the do_load field is cleared and
66 * the kmod_id field gets set.
67 */
68
69 // Immediate dependencies of this entry
70 unsigned int dependencies_capacity;
71 unsigned int num_dependencies;
72 struct dgraph_entry_t ** dependencies;
73
74 // These are filled in when the entry is created, and are written into
75 // the kmod linked image at load time.
76 char * expected_kmod_name;
77 char * expected_kmod_vers;
78
79 bool is_mapped; // kld_file_map() has been called for this entry
80
81 // For tracking already-loaded kmods or for doing symbol generation only
82 int do_load; // actually loading
83 vm_address_t loaded_address; // address loaded at or being faked at for symbol generation
84 #ifndef KERNEL
85 char * link_output_file;
86 bool link_output_file_alloc;
87 #endif
88 struct mach_header * linked_image;
89 vm_size_t linked_image_length;
90
91 vm_address_t symbols;
92 vm_size_t symbols_length;
93 vm_address_t symbols_malloc;
94
95 // for loading into kernel
96 vm_address_t kernel_alloc_address;
97 unsigned long kernel_alloc_size;
98 vm_address_t kernel_load_address;
99 unsigned long kernel_load_size;
100 unsigned long kernel_hdr_size;
101 unsigned long kernel_hdr_pad;
102 int need_cleanup; // true if load failed with kernel memory allocated
103 kmod_t kmod_id; // the id assigned by the kernel to a loaded kmod
104
105 #if CONFIG_MACF_KEXT
106 // module-specific data from the plist
107 kmod_args_t user_data;
108 mach_msg_type_number_t user_data_length;
109 #endif
110
111 } dgraph_entry_t;
112
113 typedef struct {
114 unsigned int capacity;
115 unsigned int length;
116 dgraph_entry_t ** graph;
117 dgraph_entry_t ** load_order;
118 dgraph_entry_t * root;
119 char have_loaded_symbols;
120 char has_symbol_sets;
121 char has_opaque_links;
122 vm_address_t opaque_base_image;
123 vm_size_t opaque_base_length;
124 } dgraph_t;
125
126 typedef enum {
127 dgraph_error = -1,
128 dgraph_invalid = 0,
129 dgraph_valid = 1
130 } dgraph_error_t;
131
132
133 enum { kOpaqueLink = 0x01, kRawKernelLink = 0x02 };
134
135 dgraph_error_t dgraph_init(dgraph_t * dgraph);
136
137 #ifndef KERNEL
138 /**********
139 * Initialize a dependency graph passed in. Returns nonzero on success, zero
140 * on failure.
141 *
142 * dependency_graph: a pointer to the dgraph to initialize.
143 * argc: the number of arguments in argv
144 * argv: an array of strings defining the dependency graph. This is a
145 * series of dependency lists, delimited by "-d" (except before
146 * the first list, naturally). Each list has as its first entry
147 * the dependent, followed by any number of DIRECT dependencies.
148 * The lists may be given in any order, but the first item in each
149 * list must be the dependent. Also, there can only be one root
150 * item (an item with no dependents upon it), and it must not be
151 * a kernel component.
152 */
153 dgraph_error_t dgraph_init_with_arglist(
154 dgraph_t * dgraph,
155 int expect_addresses,
156 const char * dependency_delimiter,
157 const char * kernel_dependency_delimiter,
158 int argc,
159 char * argv[]);
160 #endif /* not KERNEL */
161
162 void dgraph_free(
163 dgraph_t * dgraph,
164 int free_graph);
165
166 dgraph_entry_t * dgraph_find_root(dgraph_t * dgraph);
167
168 int dgraph_establish_load_order(dgraph_t * dgraph);
169
170 #ifndef KERNEL
171 void dgraph_print(dgraph_t * dgraph);
172 #endif /* not kernel */
173 void dgraph_log(dgraph_t * depgraph);
174
175
176 /*****
177 * These functions are useful for hand-building a dgraph.
178 */
179 dgraph_entry_t * dgraph_find_dependent(dgraph_t * dgraph, const char * name);
180
181 dgraph_entry_t * dgraph_add_dependent(
182 dgraph_t * dgraph,
183 const char * name,
184 #ifdef KERNEL
185 void * object,
186 size_t object_length,
187 bool object_is_kmem,
188 #if CONFIG_MACF_KEXT
189 kmod_args_t user_data,
190 mach_msg_type_number_t user_data_length,
191 #endif
192 #endif /* KERNEL */
193 const char * expected_kmod_name,
194 const char * expected_kmod_vers,
195 vm_address_t load_address,
196 char is_kernel_component);
197
198 dgraph_entry_t * dgraph_add_dependency(
199 dgraph_t * dgraph,
200 dgraph_entry_t * current_dependent,
201 const char * name,
202 #ifdef KERNEL
203 void * object,
204 size_t object_length,
205 bool object_is_kmem,
206 #if CONFIG_MACF_KEXT
207 kmod_args_t user_data,
208 mach_msg_type_number_t user_data_length,
209 #endif
210 #endif /* KERNEL */
211 const char * expected_kmod_name,
212 const char * expected_kmod_vers,
213 vm_address_t load_address,
214 char is_kernel_component);
215
216 dgraph_entry_t ** fill_backward_load_order(
217 dgraph_entry_t ** backward_load_order,
218 unsigned int * list_length,
219 dgraph_entry_t * first_entry,
220 unsigned int * last_index /* out param */);
221
222 #ifdef __cplusplus
223 }
224 #endif
225
226 #endif /* __DGRAPH_H__ */