9 #include <libsa/stdlib.h>
10 #include <IOKit/IOLib.h>
13 #include <mach/mach.h>
16 typedef struct dgraph_entry_t
{
18 char is_kernel_component
; // means that name is a CFBundleIdentifier!!!
23 // What we have to start from
24 char * name
; // filename if user space, bundleid if kernel or kernel comp.
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
29 bool object_is_kmem
; // Only used when mapping a file!
32 /* If is_kernel_component is true then the do_load field is cleared and
33 * the kmod_id field gets set.
36 // Immediate dependencies of this entry
37 unsigned int dependencies_capacity
;
38 unsigned int num_dependencies
;
39 struct dgraph_entry_t
** dependencies
;
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
;
46 bool is_mapped
; // kld_file_map() has been called for this entry
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
52 char * link_output_file
;
53 bool link_output_file_alloc
;
55 struct mach_header
* linked_image
;
56 vm_size_t linked_image_length
;
59 vm_size_t symbols_length
;
60 vm_address_t symbols_malloc
;
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
75 unsigned int capacity
;
77 dgraph_entry_t
** graph
;
78 dgraph_entry_t
** load_order
;
79 dgraph_entry_t
* root
;
80 char have_loaded_symbols
;
82 char has_opaque_links
;
83 vm_address_t opaque_base_image
;
84 vm_size_t opaque_base_length
;
94 enum { kOpaqueLink
= 0x01, kRawKernelLink
= 0x02 };
96 dgraph_error_t
dgraph_init(dgraph_t
* dgraph
);
100 * Initialize a dependency graph passed in. Returns nonzero on success, zero
103 * dependency_graph: a pointer to the dgraph to initialize.
104 * argc: the number of arguments in argv
105 * argv: an array of strings defining the dependency graph. This is a
106 * series of dependency lists, delimited by "-d" (except before
107 * the first list, naturally). Each list has as its first entry
108 * the dependent, followed by any number of DIRECT dependencies.
109 * The lists may be given in any order, but the first item in each
110 * list must be the dependent. Also, there can only be one root
111 * item (an item with no dependents upon it), and it must not be
112 * a kernel component.
114 dgraph_error_t
dgraph_init_with_arglist(
116 int expect_addresses
,
117 const char * dependency_delimiter
,
118 const char * kernel_dependency_delimiter
,
121 #endif /* not KERNEL */
127 dgraph_entry_t
* dgraph_find_root(dgraph_t
* dgraph
);
129 int dgraph_establish_load_order(dgraph_t
* dgraph
);
132 void dgraph_print(dgraph_t
* dgraph
);
133 #endif /* not kernel */
134 void dgraph_log(dgraph_t
* depgraph
);
138 * These functions are useful for hand-building a dgraph.
140 dgraph_entry_t
* dgraph_find_dependent(dgraph_t
* dgraph
, const char * name
);
142 dgraph_entry_t
* dgraph_add_dependent(
147 size_t object_length
,
150 const char * expected_kmod_name
,
151 const char * expected_kmod_vers
,
152 vm_address_t load_address
,
153 char is_kernel_component
);
155 dgraph_entry_t
* dgraph_add_dependency(
157 dgraph_entry_t
* current_dependent
,
161 size_t object_length
,
164 const char * expected_kmod_name
,
165 const char * expected_kmod_vers
,
166 vm_address_t load_address
,
167 char is_kernel_component
);
173 #endif /* __DGRAPH_H__ */