/* * Copyright (c) 2007 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. The rights granted to you under the License * may not be used to create, or enable the creation or redistribution of, * unlawful or unlicensed copies of an Apple operating system, or to * circumvent, violate, or enable the circumvention or violation of, any * terms of an Apple operating system software license agreement. * * Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce * support for mandatory and extensible security protections. This notice * is included in support of clause 2.2 (b) of the Apple Public License, * Version 2.0. */ #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 #if CONFIG_MACF_KEXT // module-specific data from the plist kmod_args_t user_data; mach_msg_type_number_t user_data_length; #endif } 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, #if CONFIG_MACF_KEXT kmod_args_t user_data, mach_msg_type_number_t user_data_length, #endif #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, #if CONFIG_MACF_KEXT kmod_args_t user_data, mach_msg_type_number_t user_data_length, #endif #endif /* KERNEL */ const char * expected_kmod_name, const char * expected_kmod_vers, vm_address_t load_address, char is_kernel_component); dgraph_entry_t ** fill_backward_load_order( dgraph_entry_t ** backward_load_order, unsigned int * list_length, dgraph_entry_t * first_entry, unsigned int * last_index /* out param */); #ifdef __cplusplus } #endif #endif /* __DGRAPH_H__ */