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