]>
Commit | Line | Data |
---|---|---|
55e303ae A |
1 | #ifndef __DGRAPH_H__ |
2 | #define __DGRAPH_H__ | |
3 | ||
4 | #ifdef __cplusplus | |
5 | extern "C" { | |
6 | #endif | |
7 | ||
8 | #ifdef KERNEL | |
9 | #include <libsa/stdlib.h> | |
10 | #include <IOKit/IOLib.h> | |
11 | #else | |
12 | #include <stdlib.h> | |
13 | #include <mach/mach.h> | |
14 | #endif /* KERNEL */ | |
15 | ||
16 | typedef struct dgraph_entry_t { | |
17 | ||
18 | char is_kernel_component; // means that name is a CFBundleIdentifier!!! | |
19 | char is_symbol_set; | |
20 | char opaques; | |
21 | char opaque_link; | |
22 | ||
23 | // What we have to start from | |
24 | char * name; // filename if user space, bundleid if kernel or kernel comp. | |
25 | ||
26 | void * object; // In kernel we keep track of the object file | |
27 | size_t object_length; // we don't own this, however; it's just a ref | |
28 | #ifdef KERNEL | |
29 | bool object_is_kmem; // Only used when mapping a file! | |
30 | #endif /* KERNEL */ | |
31 | ||
32 | /* If is_kernel_component is true then the do_load field is cleared and | |
33 | * the kmod_id field gets set. | |
34 | */ | |
35 | ||
36 | // Immediate dependencies of this entry | |
37 | unsigned int dependencies_capacity; | |
38 | unsigned int num_dependencies; | |
39 | struct dgraph_entry_t ** dependencies; | |
40 | ||
41 | // These are filled in when the entry is created, and are written into | |
42 | // the kmod linked image at load time. | |
43 | char * expected_kmod_name; | |
44 | char * expected_kmod_vers; | |
45 | ||
46 | bool is_mapped; // kld_file_map() has been called for this entry | |
47 | ||
48 | // For tracking already-loaded kmods or for doing symbol generation only | |
49 | int do_load; // actually loading | |
50 | vm_address_t loaded_address; // address loaded at or being faked at for symbol generation | |
51 | #ifndef KERNEL | |
52 | char * link_output_file; | |
53 | bool link_output_file_alloc; | |
54 | #endif | |
55 | struct mach_header * linked_image; | |
56 | vm_size_t linked_image_length; | |
57 | ||
58 | vm_address_t symbols; | |
59 | vm_size_t symbols_length; | |
60 | vm_address_t symbols_malloc; | |
61 | ||
62 | // for loading into kernel | |
63 | vm_address_t kernel_alloc_address; | |
64 | unsigned long kernel_alloc_size; | |
65 | vm_address_t kernel_load_address; | |
66 | unsigned long kernel_load_size; | |
67 | unsigned long kernel_hdr_size; | |
68 | unsigned long kernel_hdr_pad; | |
69 | int need_cleanup; // true if load failed with kernel memory allocated | |
70 | kmod_t kmod_id; // the id assigned by the kernel to a loaded kmod | |
71 | ||
72 | } dgraph_entry_t; | |
73 | ||
74 | typedef struct { | |
75 | unsigned int capacity; | |
76 | unsigned int length; | |
77 | dgraph_entry_t ** graph; | |
78 | dgraph_entry_t ** load_order; | |
79 | dgraph_entry_t * root; | |
80 | char have_loaded_symbols; | |
81 | char has_symbol_sets; | |
82 | char has_opaque_links; | |
83 | vm_address_t opaque_base_image; | |
84 | vm_size_t opaque_base_length; | |
85 | } dgraph_t; | |
86 | ||
87 | typedef enum { | |
88 | dgraph_error = -1, | |
89 | dgraph_invalid = 0, | |
90 | dgraph_valid = 1 | |
91 | } dgraph_error_t; | |
92 | ||
93 | ||
94 | dgraph_error_t dgraph_init(dgraph_t * dgraph); | |
95 | ||
96 | #ifndef KERNEL | |
97 | /********** | |
98 | * Initialize a dependency graph passed in. Returns nonzero on success, zero | |
99 | * on failure. | |
100 | * | |
101 | * dependency_graph: a pointer to the dgraph to initialize. | |
102 | * argc: the number of arguments in argv | |
103 | * argv: an array of strings defining the dependency graph. This is a | |
104 | * series of dependency lists, delimited by "-d" (except before | |
105 | * the first list, naturally). Each list has as its first entry | |
106 | * the dependent, followed by any number of DIRECT dependencies. | |
107 | * The lists may be given in any order, but the first item in each | |
108 | * list must be the dependent. Also, there can only be one root | |
109 | * item (an item with no dependents upon it), and it must not be | |
110 | * a kernel component. | |
111 | */ | |
112 | dgraph_error_t dgraph_init_with_arglist( | |
113 | dgraph_t * dgraph, | |
114 | int expect_addresses, | |
115 | const char * dependency_delimiter, | |
116 | const char * kernel_dependency_delimiter, | |
117 | int argc, | |
118 | char * argv[]); | |
119 | #endif /* not KERNEL */ | |
120 | ||
121 | void dgraph_free( | |
122 | dgraph_t * dgraph, | |
123 | int free_graph); | |
124 | ||
125 | dgraph_entry_t * dgraph_find_root(dgraph_t * dgraph); | |
126 | ||
127 | int dgraph_establish_load_order(dgraph_t * dgraph); | |
128 | ||
129 | #ifndef KERNEL | |
130 | void dgraph_print(dgraph_t * dgraph); | |
131 | #endif /* not kernel */ | |
132 | void dgraph_log(dgraph_t * depgraph); | |
133 | ||
134 | ||
135 | /***** | |
136 | * These functions are useful for hand-building a dgraph. | |
137 | */ | |
138 | dgraph_entry_t * dgraph_find_dependent(dgraph_t * dgraph, const char * name); | |
139 | ||
140 | dgraph_entry_t * dgraph_add_dependent( | |
141 | dgraph_t * dgraph, | |
142 | const char * name, | |
143 | #ifdef KERNEL | |
144 | void * object, | |
145 | size_t object_length, | |
146 | bool object_is_kmem, | |
147 | #endif /* KERNEL */ | |
148 | const char * expected_kmod_name, | |
149 | const char * expected_kmod_vers, | |
150 | vm_address_t load_address, | |
151 | char is_kernel_component); | |
152 | ||
153 | dgraph_entry_t * dgraph_add_dependency( | |
154 | dgraph_t * dgraph, | |
155 | dgraph_entry_t * current_dependent, | |
156 | const char * name, | |
157 | #ifdef KERNEL | |
158 | void * object, | |
159 | size_t object_length, | |
160 | bool object_is_kmem, | |
161 | #endif /* KERNEL */ | |
162 | const char * expected_kmod_name, | |
163 | const char * expected_kmod_vers, | |
164 | vm_address_t load_address, | |
165 | char is_kernel_component); | |
166 | ||
167 | #ifdef __cplusplus | |
168 | } | |
169 | #endif | |
170 | ||
171 | #endif /* __DGRAPH_H__ */ |