The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/libsa/load.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /***************
    2 * HEADERS
    3 ***************/
    4 #ifndef KERNEL
    5 
    6 #include <CoreFoundation/CoreFoundation.h>
    7 
    8 #include <libc.h>
    9 #include <stdlib.h>
   10 #include <stdarg.h>
   11 #include <stdio.h>
   12 #include <string.h>
   13 #include <unistd.h>
   14 
   15 #include <sys/stat.h>
   16 #include <sys/file.h>
   17 #include <sys/param.h>
   18 #include <sys/types.h>
   19 #include <sys/mman.h>
   20 
   21 #include <mach/mach.h>
   22 #include <mach/mach_init.h>
   23 #include <mach/mach_error.h>
   24 #include <mach/mach_host.h>
   25 #include <mach/mach_port.h>
   26 #include <mach-o/kld.h>
   27 #include <mach-o/arch.h>
   28 #include <mach-o/fat.h>
   29 #include <mach-o/loader.h>
   30 #include <mach-o/nlist.h>
   31 #include <libkern/OSByteOrder.h>
   32 
   33 #include "vers_rsrc.h"
   34 
   35 #else
   36 
   37 #include <mach-o/kld.h>
   38 #include <mach-o/loader.h>
   39 #include <mach-o/nlist.h>
   40 #include <libsa/vers_rsrc.h>
   41 
   42 #endif /* not KERNEL */
   43 
   44 #include "load.h"
   45 #include "dgraph.h"
   46 #include "kld_patch.h"
   47 
   48 /***************
   49 * MACROS
   50 ***************/
   51 
   52 #ifndef KERNEL
   53 
   54 #define PRIV_EXT
   55 
   56 #else
   57 
   58 #define PRIV_EXT  __private_extern__
   59 
   60 #ifdef DEBUG
   61 #define LOG_DELAY(x)    IODelay((x) * 1000000)
   62 #define VTYELLOW  "\033[33m"
   63 #define VTRESET   "\033[0m"
   64 #else
   65 #define LOG_DELAY()
   66 #define VTYELLOW
   67 #define VTRESET
   68 #endif /* DEBUG */
   69 
   70 #endif /* not KERNEL */
   71 
   72 /***************
   73 * FUNCTION PROTOS
   74 ***************/
   75 
   76 #ifdef KERNEL
   77 extern kern_return_t
   78 kmod_create_internal(
   79             kmod_info_t *info,
   80             kmod_t *id);
   81 
   82 extern kern_return_t
   83 kmod_destroy_internal(kmod_t id);
   84 
   85 extern kern_return_t
   86 kmod_start_or_stop(
   87     kmod_t id,
   88     int start,
   89     kmod_args_t *data,
   90     mach_msg_type_number_t *dataCount);
   91 
   92 extern kern_return_t kmod_retain(kmod_t id);
   93 extern kern_return_t kmod_release(kmod_t id);
   94 
   95 extern void flush_dcache(vm_offset_t addr, unsigned cnt, int phys);
   96 extern void invalidate_icache(vm_offset_t addr, unsigned cnt, int phys);
   97 #endif /* KERNEL */
   98 
   99 
  100 // Used to pass info between kld library and callbacks
  101 static dgraph_entry_t * G_current_load_entry = NULL;
  102 
  103 #ifndef KERNEL
  104 static mach_port_t G_kernel_port = PORT_NULL;
  105 static mach_port_t G_kernel_priv_port = PORT_NULL;
  106 static int G_syms_only;
  107 
  108 static kload_error
  109 register_prelink(dgraph_entry_t * entry,
  110                     kmod_info_t * local_kmod_info, vm_offset_t kernel_kmod_info);
  111 
  112 struct PrelinkState
  113 {
  114     kmod_info_t modules[1];
  115 };
  116 struct PrelinkState *   G_prelink;
  117 CFMutableDataRef        G_prelink_data;
  118 CFMutableDataRef        G_prelink_dependencies;
  119 
  120 #endif /* not KERNEL */
  121 
  122 // used by dgraph.c so can't be static
  123 kload_log_level log_level = 0;
  124 
  125 #ifndef KERNEL
  126 static void __kload_null_log(const char * format, ...);
  127 static void __kload_null_err_log(const char * format, ...);
  128 static int __kload_null_approve(int default_answer, const char * format, ...);
  129 static int __kload_null_veto(int default_answer, const char * format, ...);
  130 static const char * __kload_null_input(const char * format, ...);
  131 
  132 void (*__kload_log_func)(const char * format, ...) =
  133     &__kload_null_log;
  134 void (*__kload_err_log_func)(const char * format, ...) = &__kload_null_err_log;
  135 int (*__kload_approve_func)(int default_answer,
  136     const char * format, ...) = &__kload_null_approve;
  137 int (*__kload_veto_func)(int default_answer,
  138     const char * format, ...) = &__kload_null_veto;
  139 const char * (*__kload_input_func)(const char * format, ...) =
  140     &__kload_null_input;
  141 #endif /* not KERNEL */
  142 
  143 static unsigned long __kload_linkedit_address(
  144     unsigned long size,
  145     unsigned long headers_size);
  146 static void __kload_clean_up_entry(dgraph_entry_t * entry);
  147 static void __kload_clear_kld_globals(void);
  148 static kload_error __kload_patch_dgraph(dgraph_t * dgraph
  149 #ifndef KERNEL
  150     ,
  151     const char * kernel_file
  152 #endif /* not KERNEL */
  153     );
  154 static kload_error __kload_load_modules(dgraph_t * dgraph
  155 #ifndef KERNEL
  156     ,
  157     const char * kernel_file,
  158     const char * patch_file, const char * patch_dir,
  159     const char * symbol_file, const char * symbol_dir,
  160     int do_load, int do_start_kmod, int do_prelink,
  161     int interactive_level,
  162     int ask_overwrite_symbols, int overwrite_symbols
  163 #endif /* not KERNEL */
  164     );
  165 
  166 static kload_error __kload_check_module_loaded(
  167     dgraph_t * dgraph,
  168     dgraph_entry_t * entry,
  169 #ifndef KERNEL
  170     kmod_info_t * kmod_list,
  171 #endif /* not KERNEL */
  172     int log_if_already);
  173 
  174 static kload_error __kload_load_module(dgraph_t * dgraph,
  175     dgraph_entry_t * entry,
  176     int is_root
  177 #ifndef KERNEL
  178     ,
  179     const char * symbol_file,
  180     const char * symbol_dir,
  181     int do_load,
  182     int interactive_level,
  183     int ask_overwrite_symbols,
  184     int overwrite_symbols
  185 #endif /* not KERNEL */
  186     );
  187 static kload_error __kload_set_module_dependencies(dgraph_entry_t * entry);
  188 static kload_error __kload_start_module(dgraph_entry_t * entry);
  189 
  190 #ifndef KERNEL
  191 static kload_error __kload_output_patches(
  192     dgraph_t * dgraph,
  193     const char * patch_file,
  194     const char * patch_dir,
  195     int ask_overwrite_symbols,
  196     int overwrite_symbols);
  197 
  198 Boolean _IOReadBytesFromFile(CFAllocatorRef alloc, const char *path, void **bytes,
  199                                 CFIndex *length, CFIndex maxLength);
  200 Boolean _IOWriteBytesToFile(const char *path, const void *bytes, CFIndex length);
  201 
  202 #endif /* not KERNEL */
  203 
  204 /*******************************************************************************
  205 *
  206 *******************************************************************************/
  207 PRIV_EXT
  208 kload_error kload_load_dgraph(dgraph_t * dgraph
  209 #ifndef KERNEL
  210     ,
  211     const char * kernel_file,
  212     const char * patch_file, const char * patch_dir,
  213     const char * symbol_file, const char * symbol_dir,
  214     int do_load, int do_start_kmod, int do_prelink,
  215     int interactive_level,
  216     int ask_overwrite_symbols, int overwrite_symbols
  217 #endif /* not KERNEL */
  218     )
  219 {
  220     kload_error result = kload_error_none;
  221     int one_has_address = 0;
  222     int one_lacks_address = 0;
  223     unsigned int i;
  224 #ifndef KERNEL
  225     int syms_only;
  226 
  227     syms_only = (!do_load) && (symbol_dir || symbol_file);
  228 
  229     if (log_level >= kload_log_level_load_details) {
  230         kload_log_message("loading dependency graph:" KNL);
  231         dgraph_log(dgraph);
  232     }
  233 
  234     if (syms_only && log_level >= kload_log_level_load_details) {
  235         kload_log_message("loading for symbol generation only" KNL);
  236     }
  237 
  238    /*****
  239     * If we're not loading and have no request to emit a symbol
  240     * or patch file, there's nothing to do!
  241     */
  242     if (!do_load && !symbol_dir && !symbol_file &&
  243         !patch_dir && !patch_file) {
  244 
  245         if (syms_only && log_level >= kload_log_level_load_details) {
  246             kload_log_message("loader has no work to do" KNL);
  247         }
  248 
  249         result = kload_error_none;  // fixme: should this be USAGE error?
  250         goto finish;
  251     }
  252 
  253    /*****
  254     * If we're doing symbols only, then all entries in the dgraph must
  255     * have addresses assigned, or none must.
  256     */
  257     if (syms_only) {
  258         if (log_level >= kload_log_level_load_details) {
  259             kload_log_message("checking whether modules have addresses assigned" KNL);
  260         }
  261         for (i = 0; i < dgraph->length; i++) {
  262             struct dgraph_entry_t * entry = dgraph->load_order[i];
  263             if (entry->is_kernel_component) {
  264                 continue;
  265             }
  266             if (entry->loaded_address != 0) {
  267                 one_has_address = 1;
  268             } else {
  269                 one_lacks_address = 1;
  270             }
  271         }
  272     }
  273 #endif /* not KERNEL */
  274 
  275     if (one_has_address && one_lacks_address) {
  276         kload_log_error(
  277             "either all modules must have addresses set to nonzero values or "
  278             "none must" KNL);
  279         result = kload_error_invalid_argument;
  280         goto finish;
  281     }
  282 
  283 #ifndef KERNEL
  284    /* we need the priv port to check/load modules in the kernel.
  285     */
  286     if (PORT_NULL == G_kernel_priv_port) {
  287         G_kernel_priv_port = mach_host_self();  /* if we are privileged */
  288     }
  289 #endif /* not KERNEL */
  290 
  291 /*****
  292  * In the kernel, ALWAYS get load addresses of existing loaded kmods.
  293  */
  294 #ifndef KERNEL
  295    /*****
  296     * If we don't have addresses, then get them from the kernel.
  297     */
  298     if (!one_has_address && !do_prelink && (do_load || symbol_file || symbol_dir)) {
  299 #endif /* not KERNEL */
  300         if (log_level >= kload_log_level_load_details) {
  301             kload_log_message("getting module addresses from kernel" KNL);
  302         }
  303 #ifndef KERNEL
  304         result = kload_set_load_addresses_from_kernel(dgraph, kernel_file,
  305             do_load);
  306 #else
  307         result = kload_set_load_addresses_from_kernel(dgraph);
  308 #endif /* not KERNEL */
  309         if (result == kload_error_already_loaded) {
  310 
  311 #ifndef KERNEL
  312             if (do_load) {
  313                 goto finish;
  314             }
  315 #else
  316             goto finish;
  317 #endif /* not KERNEL */
  318 
  319         } else if (result != kload_error_none) {
  320             kload_log_error("can't check load addresses of modules" KNL);
  321             goto finish;
  322         }
  323 #ifndef KERNEL
  324     }
  325 #endif /* not KERNEL */
  326 
  327 #ifndef KERNEL
  328    /*****
  329     * At this point, if we're doing symbols only, it's an error to not
  330     * have a load address for every module.
  331     */
  332     if (syms_only && !do_prelink) {
  333         if (log_level >= kload_log_level_load_details) {
  334             kload_log_message("checking that all modules have addresses assigned" KNL);
  335         }
  336         for (i = 0; i < dgraph->length; i++) {
  337             struct dgraph_entry_t * entry = dgraph->load_order[i];
  338             if (entry->is_kernel_component) {
  339                 continue;
  340             }
  341             if (!entry->loaded_address) {
  342                 kload_log_error(
  343                     "missing load address during symbol generation: %s" KNL,
  344                     entry->name);
  345                 result = kload_error_unspecified;
  346                 goto finish;
  347             }
  348        }
  349     }
  350 
  351     if (do_prelink)
  352     {
  353         void *          bytes;
  354         CFIndex        length;
  355         CFAllocatorRef alloc;
  356 
  357         // We need a real allocator to pass to _IOReadBytesFromFile
  358         alloc = CFRetain(CFAllocatorGetDefault());
  359         if (_IOReadBytesFromFile(alloc, "prelinkstate", &bytes, &length, 0))
  360         {
  361             G_prelink_data = CFDataCreateMutable(alloc, 0);
  362             CFDataAppendBytes(G_prelink_data, (UInt8 *) bytes, length);
  363             CFAllocatorDeallocate(alloc, bytes);
  364         }
  365         G_prelink_dependencies = CFDataCreateMutable(alloc, 0);
  366         if (_IOReadBytesFromFile(alloc, "prelinkdependencies", &bytes, &length, 0))
  367         {
  368             CFDataAppendBytes(G_prelink_dependencies, (UInt8 *) bytes, length);
  369             CFAllocatorDeallocate(alloc, bytes);
  370         }
  371         CFRelease(alloc);
  372 
  373         if (!G_prelink_data) {
  374             kload_log_error(
  375                 "can't get load address for prelink %s" KNL, kernel_file);
  376             result = kload_error_link_load;
  377             goto finish;
  378         }
  379         else
  380             G_prelink = (struct PrelinkState *) CFDataGetMutableBytePtr(G_prelink_data);
  381     }
  382     else
  383         G_prelink = 0;
  384 #endif /* not KERNEL */
  385 
  386 #ifndef KERNEL
  387 
  388     result = __kload_load_modules(dgraph, kernel_file,
  389         patch_file, patch_dir, symbol_file, symbol_dir,
  390         do_load, do_start_kmod, do_prelink, interactive_level,
  391         ask_overwrite_symbols, overwrite_symbols);
  392 #else
  393     result = __kload_load_modules(dgraph);
  394 #endif /* not KERNEL */
  395 
  396 finish:
  397 
  398 #ifndef KERNEL
  399    /* Dispose of the host port to prevent security breaches and port
  400     * leaks. We don't care about the kern_return_t value of this
  401     * call for now as there's nothing we can do if it fails.
  402     */
  403     if (PORT_NULL != G_kernel_priv_port) {
  404         mach_port_deallocate(mach_task_self(), G_kernel_priv_port);
  405         G_kernel_priv_port = PORT_NULL;
  406     }
  407 #endif /* not KERNEL */
  408 
  409     for (i = 0; i < dgraph->length; i++) {
  410         dgraph_entry_t * current_entry = dgraph->graph[i];
  411         __kload_clean_up_entry(current_entry);
  412     }
  413 
  414 #ifndef KERNEL
  415     if (G_prelink)
  416     {
  417         SInt32       length;
  418         const void * bytes;
  419         Boolean      success;
  420 
  421         length = CFDataGetLength(G_prelink_data);
  422         bytes = (0 == length) ? (const void *)"" : CFDataGetBytePtr(G_prelink_data);
  423         success = _IOWriteBytesToFile("prelinkstate", bytes, length);
  424         if (!success)
  425         {
  426             kload_log_error("write prelinkstate" KNL);
  427             result = kload_error_link_load;
  428         }
  429         length = CFDataGetLength(G_prelink_dependencies);
  430         bytes = (0 == length) ? (const void *)"" : CFDataGetBytePtr(G_prelink_dependencies);
  431         success = _IOWriteBytesToFile("prelinkdependencies", bytes, length);
  432         if (!success)
  433         {
  434             kload_log_error("write prelinkdependencies" KNL);
  435             result = kload_error_link_load;
  436         }
  437     }
  438 #endif /* not KERNEL */
  439 
  440     return result;
  441 }
  442 
  443 #ifndef KERNEL
  444 /*******************************************************************************
  445 * This function claims the option flags d and D for object file dependencies
  446 * and in-kernel dependencies, respectively.
  447 *******************************************************************************/
  448 kload_error kload_load_with_arglist(
  449     int argc, char **argv,
  450     const char * kernel_file,
  451     const char * patch_file, const char * patch_dir,
  452     const char * symbol_file, const char * symbol_dir,
  453     int do_load, int do_start_kmod,
  454     int interactive_level,
  455     int ask_overwrite_symbols, int overwrite_symbols)
  456 {
  457     kload_error result = kload_error_none;
  458     dgraph_error_t dgraph_result;
  459     int syms_only = (!do_load) && (symbol_file || symbol_dir);
  460 
  461     static dgraph_t dependency_graph;
  462 
  463    /* Zero out fields in dependency graph for proper error handling later.
  464     */
  465     bzero(&dependency_graph, sizeof(dependency_graph));
  466 
  467     dgraph_result = dgraph_init_with_arglist(&dependency_graph,
  468         syms_only, "-d", "-D", argc, argv);
  469     if (dgraph_result == dgraph_error) {
  470         kload_log_error("error processing dependency list" KNL);
  471         result = kload_error_unspecified;
  472         goto finish;
  473     } else if (dgraph_result == dgraph_invalid) {
  474         // anything to print here, or did init call print something?
  475         result = kload_error_invalid_argument;
  476         goto finish;
  477     }
  478 
  479     result = kload_load_dgraph(&dependency_graph, kernel_file,
  480         patch_file, patch_dir, symbol_file, symbol_dir,
  481         do_load, do_start_kmod, false /* do_prelink */, interactive_level,
  482         ask_overwrite_symbols, overwrite_symbols);
  483 
  484 finish:
  485     return result;
  486 }
  487 #endif /* not KERNEL */
  488 /*******************************************************************************
  489 *
  490 *******************************************************************************/
  491 static
  492 kload_error __kload_keep_symbols(dgraph_entry_t * entry)
  493 {
  494     struct mach_header *        hdr;
  495     struct segment_command *    seg;
  496     struct nlist *              sym;
  497     struct symtab_command *     symcmd;
  498     unsigned long               idx, ncmds;
  499     vm_size_t                   size;
  500     vm_address_t                mem;
  501 
  502     if (entry->symbols)
  503         return kload_error_none;
  504 
  505     hdr   = entry->linked_image;
  506     ncmds = hdr->ncmds;
  507     seg   = (struct segment_command *)(hdr + 1);
  508     for (idx = 0;
  509             idx < ncmds;
  510             idx++, seg = (struct segment_command *)(((vm_offset_t)seg) + seg->cmdsize))
  511     {
  512         if (LC_SYMTAB == seg->cmd)
  513             break;
  514     }
  515     if (idx >= ncmds)
  516     {
  517         kload_log_error("no LC_SYMTAB" KNL);
  518         return kload_error_unspecified;
  519     }
  520 
  521     symcmd = (struct symtab_command *) seg;
  522 
  523     struct load_cmds {
  524         struct mach_header     hdr;
  525         struct segment_command seg;
  526         struct symtab_command  symcmd;
  527     };
  528     struct load_cmds * cmd;
  529     unsigned int symtabsize;
  530 
  531     symtabsize = symcmd->stroff + symcmd->strsize - symcmd->symoff;
  532 
  533     size = sizeof(struct load_cmds) + symtabsize;
  534 
  535     mem = (vm_offset_t) malloc(size);
  536 
  537     cmd = (struct load_cmds *) mem;
  538     sym = (struct nlist *) (cmd + 1);
  539 
  540     cmd->hdr    = *hdr;
  541     cmd->symcmd = *symcmd;
  542     bcopy((const void *) (((vm_offset_t) hdr) + symcmd->symoff), 
  543             sym,
  544             symtabsize);
  545 
  546     hdr                 = (struct mach_header *) mem;
  547     cmd->hdr.ncmds      = 2;
  548     cmd->hdr.sizeofcmds = sizeof(struct load_cmds);
  549     cmd->hdr.flags     &= ~MH_INCRLINK;
  550 
  551     cmd->symcmd.stroff -= (symcmd->symoff - sizeof(struct load_cmds));
  552     cmd->symcmd.symoff  = sizeof(struct load_cmds);
  553 
  554     cmd->seg.cmd        = LC_SEGMENT;
  555     cmd->seg.cmdsize    = sizeof(struct segment_command);
  556     strcpy(cmd->seg.segname, SEG_LINKEDIT);
  557     cmd->seg.vmaddr     = 0;
  558     cmd->seg.vmsize     = 0;
  559     cmd->seg.fileoff    = cmd->symcmd.symoff;
  560     cmd->seg.filesize   = symtabsize;
  561     cmd->seg.maxprot    = 7;
  562     cmd->seg.initprot   = 1;
  563     cmd->seg.nsects     = 0;
  564     cmd->seg.flags      = 0;
  565 
  566     sym = (struct nlist *) (cmd + 1);
  567     for (idx = 0; idx < symcmd->nsyms; idx++, sym++)
  568     {
  569         if ( (sym->n_type & N_TYPE) == N_SECT) {
  570             sym->n_sect = NO_SECT;
  571             sym->n_type = (sym->n_type & ~N_TYPE) | N_ABS;
  572         }
  573     }
  574     if (log_level >= kload_log_level_load_details)
  575     {
  576         kload_log_message("__kload_keep_symbols %s, nsyms %ld, 0x%x bytes" KNL, 
  577                             entry->name, symcmd->nsyms, size);
  578     }
  579 
  580     entry->symbols        = mem;
  581     entry->symbols_malloc = mem;
  582     entry->symbols_length = size;
  583 
  584     return kload_error_none;
  585 }
  586 
  587 
  588 static
  589 kload_error __kload_make_opaque_basefile(dgraph_t * dgraph, struct mach_header * hdr)
  590 {
  591     struct segment_command *    seg;
  592     struct segment_command *    data_seg;
  593     struct segment_command *    text_seg;
  594     struct section *            sec;
  595     int                         j;
  596     vm_offset_t                 offset;
  597     unsigned long               idx, ncmds;
  598     vm_size_t                   size;
  599     vm_address_t                mem, out;
  600     static vm_address_t         keep_base_image;
  601     static vm_size_t            keep_base_size;
  602 
  603     if (dgraph->opaque_base_image)
  604         return kload_error_none;
  605 
  606     if (keep_base_image)
  607     {
  608         dgraph->opaque_base_image  = keep_base_image;
  609         dgraph->opaque_base_length = keep_base_size;
  610         return kload_error_none;
  611     }
  612 
  613     data_seg = text_seg = NULL;
  614     ncmds = hdr->ncmds;
  615     seg = (struct segment_command *)(hdr + 1);
  616     for (idx = 0;
  617             idx < ncmds;
  618             idx++, seg = (struct segment_command *)(((vm_offset_t)seg) + seg->cmdsize))
  619     {
  620         if (LC_SEGMENT != seg->cmd)
  621             continue;
  622         if (!strcmp(SEG_TEXT, seg->segname))
  623             text_seg = seg;
  624         else if (!strcmp(SEG_DATA, seg->segname))
  625             data_seg = seg;
  626     }
  627     if (!text_seg || !data_seg)
  628     {
  629         kload_log_error("no SEG_TEXT or SEG_DATA" KNL);
  630         return kload_error_unspecified;
  631     }
  632 
  633     size = sizeof(struct mach_header) + text_seg->cmdsize + data_seg->cmdsize;
  634     mem = (vm_offset_t) malloc(size);
  635 
  636     out = mem;
  637     bcopy(hdr, (void *) out, sizeof(struct mach_header));
  638     hdr = (struct mach_header *) out;
  639     out += sizeof(struct mach_header);
  640 
  641     bcopy(text_seg, (void *) out, text_seg->cmdsize);
  642     text_seg = (struct segment_command *) out;
  643     out += text_seg->cmdsize;
  644 
  645     bcopy(data_seg, (void *) out, data_seg->cmdsize);
  646     data_seg = (struct segment_command *) out;
  647     out += data_seg->cmdsize;
  648 
  649     hdr->ncmds = 2;
  650     hdr->sizeofcmds = text_seg->cmdsize + data_seg->cmdsize;
  651 
  652     offset = hdr->sizeofcmds;
  653 
  654     text_seg->fileoff  = offset;
  655     text_seg->filesize = 0;
  656 
  657     sec = (struct section *)(text_seg + 1);
  658     for (j = 0; j < text_seg->nsects; j++, sec++)
  659     {
  660 //      sec->addr   = (unsigned long) addr;
  661         sec->size   = 0;
  662         sec->offset = offset;
  663         sec->nreloc = 0;
  664     }
  665 
  666     data_seg->fileoff  = offset;
  667     data_seg->filesize = 0;
  668 
  669     sec = (struct section *)(data_seg + 1);
  670     for (j = 0; j < data_seg->nsects; j++, sec++)
  671     {
  672 //      sec->addr   = (unsigned long) addr;
  673         sec->size   = 0;
  674         sec->offset = offset;
  675         sec->nreloc = 0;
  676     }
  677 
  678     dgraph->opaque_base_image  = mem;
  679     dgraph->opaque_base_length = size;
  680     keep_base_image            = mem;
  681     keep_base_size             = size;
  682 
  683     return kload_error_none;
  684 }
  685 
  686 /*******************************************************************************
  687 *
  688 *******************************************************************************/
  689 static
  690 kload_error __kload_load_modules(dgraph_t * dgraph
  691 #ifndef KERNEL
  692     ,
  693     const char * kernel_file,
  694     const char * patch_file,
  695     const char * patch_dir,
  696     const char * symbol_file,
  697     const char * symbol_dir,
  698     int do_load,
  699     int do_start_kmod,
  700     int do_prelink,
  701     int interactive_level,
  702     int ask_overwrite_symbols,
  703     int overwrite_symbols
  704 #endif /* not KERNEL */
  705     )
  706 {
  707     kload_error result = kload_error_none;
  708 #ifndef KERNEL
  709     long int kernel_size = 0;
  710     kern_return_t mach_result = KERN_SUCCESS;
  711 #endif /* not KERNEL */
  712     char * kernel_base_addr = 0;
  713     int kld_result;
  714     Boolean cleanup_kld_loader = false;
  715     unsigned int i;
  716 
  717    /* We have to map all object files to get their CFBundleIdentifier
  718     * names.
  719     */
  720 #ifndef KERNEL
  721     result = kload_map_dgraph(dgraph, kernel_file);
  722 #else
  723     result = kload_map_dgraph(dgraph);
  724 #endif /* not KERNEL */
  725     if (result != kload_error_none) {
  726         kload_log_error("error mapping object files" KNL);
  727         goto finish;
  728     }
  729 
  730 #ifndef KERNEL
  731     result = __kload_patch_dgraph(dgraph, kernel_file);
  732 #else
  733     result = __kload_patch_dgraph(dgraph);
  734 #endif /* not KERNEL */
  735     if (result != kload_error_none) {
  736         // FIXME: print an error message here?
  737         goto finish;
  738     }
  739 
  740 #ifndef KERNEL
  741     // FIXME: check error return
  742     __kload_output_patches(dgraph, patch_file, patch_dir,
  743         ask_overwrite_symbols, overwrite_symbols);
  744 
  745    /*****
  746     * If we're not loading or writing symbols, we're done.
  747     */
  748     if (!do_load && !do_prelink && !symbol_file && !symbol_dir) {
  749         goto finish;
  750     }
  751 
  752     if (do_load && PORT_NULL == G_kernel_port) {
  753         mach_result = task_for_pid(mach_task_self(), 0, &G_kernel_port);
  754         if (mach_result != KERN_SUCCESS) {
  755             kload_log_error("unable to get kernel task port: %s" KNL,
  756                 mach_error_string(mach_result));
  757             kload_log_error("you must be running as root to load "
  758                 "modules into the kernel" KNL);
  759             result = kload_error_kernel_permission;
  760             goto finish;
  761         }
  762     }
  763 #endif /* not KERNEL */
  764 
  765     kld_address_func(&__kload_linkedit_address);
  766 
  767 #ifndef KERNEL
  768     G_syms_only = (!do_load) && (symbol_file || symbol_dir || patch_dir);
  769 
  770     kernel_base_addr = kld_file_getaddr(kernel_file, &kernel_size);
  771     if (!kernel_base_addr) {
  772         kload_log_error(
  773             "can't get load address for kernel %s" KNL, kernel_file);
  774         result = kload_error_link_load;
  775         goto finish;
  776     }
  777 #else /* KERNEL */
  778 
  779     const char * kernel_file = "(kernel)";
  780     extern struct mach_header _mh_execute_header;
  781     kernel_base_addr = (char *) &_mh_execute_header;
  782 
  783 #endif /* not KERNEL */
  784 
  785     kld_result = true;
  786     if (dgraph->has_symbol_sets)
  787     {
  788         result = __kload_make_opaque_basefile(dgraph, (struct mach_header *) kernel_base_addr);
  789         if (result != kload_error_none) {
  790             kload_log_error("can't construct opaque base image from %s" KNL, kernel_file);
  791             goto finish;
  792         }
  793 
  794         kld_result = kld_load_basefile_from_memory(kernel_file,
  795                             (char *)  dgraph->opaque_base_image, 
  796                                        dgraph->opaque_base_length);
  797     }
  798 #ifndef KERNEL
  799     else
  800         kld_result = kld_load_basefile_from_memory(kernel_file,
  801                             (char *)  kernel_base_addr, kernel_size);
  802 #endif /* not KERNEL */
  803 
  804     if (!kld_result) {
  805         kload_log_error("can't link base image %s" KNL, kernel_file);
  806         result = kload_error_link_load;
  807         goto finish;
  808     }
  809 
  810     cleanup_kld_loader = true;
  811     bool opaque_now = false;
  812 
  813     for (i = 0; i < dgraph->length; i++) {
  814         dgraph_entry_t * current_entry = dgraph->load_order[i];
  815 
  816         opaque_now |= current_entry->opaque_link;
  817 
  818         if (opaque_now)
  819         {
  820             unsigned int k, j;
  821 
  822             if (log_level >= kload_log_level_load_details)
  823             {
  824                 kload_log_message("opaque link for %s" KNL, current_entry->name);
  825             }
  826 
  827             kld_set_link_options(KLD_STRIP_ALL);        // KLD_STRIP_NONE
  828 
  829             if (dgraph->have_loaded_symbols)
  830             {
  831                 kld_unload_all(1);
  832                 kld_result = kld_load_basefile_from_memory(kernel_file,
  833                                                     (char *)  dgraph->opaque_base_image, 
  834                                                                 dgraph->opaque_base_length);
  835                 if (!kld_result) {
  836                     kload_log_error("can't link base image %s" KNL, kernel_file);
  837                     result = kload_error_link_load;
  838                     goto finish;
  839                 }
  840             }
  841 
  842             dgraph->have_loaded_symbols = false;
  843 
  844             for (j = 0; j < dgraph->length; j++)
  845             {
  846                 for (k = 0;
  847                     (k < current_entry->num_dependencies)
  848                     && (current_entry->dependencies[k] != dgraph->load_order[j]);
  849                     k++)        {}
  850 
  851                 if (k == current_entry->num_dependencies)
  852                     continue;
  853 
  854                 dgraph_entry_t * image_dep = current_entry->dependencies[k];
  855                 if (!image_dep->symbols)
  856                 {
  857                     kload_log_error("internal error; no dependent symbols" KNL);
  858                     result = kload_error_link_load;
  859                     goto finish;
  860                 }
  861                 else
  862                 {
  863                     struct mach_header * kld_header;
  864 
  865 #ifndef KERNEL
  866                     kld_result = kld_load_from_memory(&kld_header, image_dep->name,
  867                             (char *) image_dep->symbols, image_dep->symbols_length, NULL);
  868 #else
  869                     kld_result = kld_load_from_memory(&kld_header, image_dep->name,
  870                             (char *) image_dep->symbols, image_dep->symbols_length);
  871 #endif /* not KERNEL */
  872                     if (!kld_result) {
  873                         kload_log_error("can't link dependent image %s" KNL, image_dep->name);
  874                         result = kload_error_link_load;
  875                         goto finish;
  876                     }
  877                     kld_forget_symbol("_kmod_info");
  878                     dgraph->have_loaded_symbols = true;
  879                 }
  880             }
  881         } /* opaque_now */
  882 
  883         if (dgraph->has_opaque_links
  884 #ifndef KERNEL
  885             || symbol_file || symbol_dir
  886 #endif
  887             )
  888             kld_set_link_options(KLD_STRIP_NONE);
  889         else
  890             kld_set_link_options(KLD_STRIP_ALL);
  891 
  892 #ifndef KERNEL
  893         result = __kload_load_module(dgraph, current_entry,
  894             (current_entry == dgraph->root),
  895             symbol_file, symbol_dir, do_load,
  896             interactive_level, ask_overwrite_symbols, overwrite_symbols);
  897 #else
  898         result = __kload_load_module(dgraph, current_entry,
  899             (current_entry == dgraph->root));
  900 #endif /* not KERNEL */
  901         if (result != kload_error_none) {
  902             goto finish;
  903         }
  904 
  905         if (dgraph->has_opaque_links && (current_entry != dgraph->root))
  906         {
  907             result = __kload_keep_symbols(current_entry);
  908             if (result != kload_error_none) {
  909                 kload_log_error("__kload_keep_symbols() failed for module %s" KNL,
  910                     current_entry->name);
  911                 goto finish;
  912             }
  913         }
  914 
  915 #ifndef KERNEL
  916         if (do_load && current_entry->do_load) {
  917 #else
  918         if (current_entry->do_load) {
  919 #endif /* not KERNEL */
  920             result = __kload_set_module_dependencies(current_entry);
  921             if ( ! (result == kload_error_none ||
  922                     result == kload_error_already_loaded) ) {
  923                 goto finish;
  924             }
  925 
  926 #ifndef KERNEL
  927             if ( (interactive_level == 1 && current_entry == dgraph->root) ||
  928                  (interactive_level == 2) ) {
  929 
  930                 int approve = (*__kload_approve_func)(1,
  931                     "\nStart module %s (ansering no will abort the load)",
  932                     current_entry->name);
  933 
  934                 if (approve > 0) {
  935                     do_start_kmod = true; // override 'cause user said so
  936                 } else {
  937                     kern_return_t mach_result;
  938                     if (approve < 0) {
  939                          kload_log_message("error reading user response; "
  940                             "destroying loaded module" KNL);
  941                     } else {
  942                          kload_log_message("user canceled module start; "
  943                             "destroying loaded module" KNL);
  944                     }
  945                     mach_result = kmod_destroy(G_kernel_priv_port, current_entry->kmod_id);
  946                     if (mach_result != KERN_SUCCESS) {
  947                         kload_log_error("kmod_destroy() failed" KNL);
  948                     }
  949                     if (approve < 0) {
  950                         result = kload_error_unspecified;
  951                         goto finish;
  952                     } else {
  953                         result = kload_error_user_abort;
  954                         goto finish;
  955                     }
  956                 }
  957             }
  958 #endif /* not KERNEL */
  959 
  960 #ifndef KERNEL
  961             if (current_entry != dgraph->root ||
  962                 (current_entry == dgraph->root && do_start_kmod)) {
  963 #endif /* not KERNEL */
  964 
  965                 result = __kload_start_module(current_entry);
  966                 if ( ! (result == kload_error_none ||
  967                         result == kload_error_already_loaded) ) {
  968                     goto finish;
  969 #ifndef KERNEL
  970                 } else if (interactive_level ||
  971                            log_level >= kload_log_level_load_details) {
  972 #else
  973                 } else if (log_level >= kload_log_level_load_details) {
  974 #endif /* not KERNEL */
  975 
  976                      kload_log_message("started module %s" KNL,
  977                         current_entry->name);
  978                 } /* log_level */
  979 #ifndef KERNEL
  980             } /* current_entry... */
  981 #endif /* not KERNEL */
  982 
  983 
  984 #ifndef KERNEL
  985         } /* if do_load */
  986 #else
  987         } /* if do_load */
  988 #endif /* not KERNEL */
  989     } /* for i, dgraph->length */
  990 
  991 finish:
  992 
  993 #ifndef KERNEL
  994    /* Dispose of the kernel port to prevent security breaches and port
  995     * leaks. We don't care about the kern_return_t value of this
  996     * call for now as there's nothing we can do if it fails.
  997     */
  998     if (PORT_NULL != G_kernel_port) {
  999         mach_port_deallocate(mach_task_self(), G_kernel_port);
 1000         G_kernel_port = PORT_NULL;
 1001     }
 1002 #endif /* not KERNEL */
 1003 
 1004     if (cleanup_kld_loader) {
 1005         kld_unload_all(1);
 1006     }
 1007 
 1008     return result;
 1009 }
 1010 
 1011 
 1012 /*******************************************************************************
 1013 *
 1014 *******************************************************************************/
 1015 
 1016 #ifndef KERNEL
 1017 #define __KLOAD_SYMBOL_EXTENSION   ".sym"
 1018 #endif /* not KERNEL */
 1019 
 1020 static
 1021 kload_error __kload_load_module(dgraph_t * dgraph,
 1022     dgraph_entry_t * entry,
 1023     int is_root
 1024 #ifndef KERNEL
 1025     ,
 1026     const char * symbol_file,
 1027     const char * symbol_dir,
 1028     int do_load,
 1029     int interactive_level,
 1030     int ask_overwrite_symbols,
 1031     int overwrite_symbols
 1032     #endif /* not KERNEL */
 1033     )
 1034 {
 1035     kload_error result = kload_error_none;
 1036 
 1037     int kld_result;
 1038     int mach_result;
 1039     struct mach_header * kld_header;
 1040     const char * kmod_symbol = "_kmod_info";
 1041     unsigned long kernel_kmod_info;
 1042     kmod_info_t * local_kmod_info = NULL;
 1043     char * dest_address = 0;
 1044 #ifndef KERNEL
 1045     char * allocated_filename = NULL;
 1046     char * symbol_filename = NULL;
 1047     int file_check;
 1048     vm_address_t vm_buffer = 0;
 1049 #endif /* not KERNEL */
 1050 
 1051    /* A kernel component is by nature already linked and loaded and has
 1052     * no work to be done upon it.
 1053     */
 1054     if (entry->is_kernel_component && !entry->is_symbol_set) {
 1055         result = kload_error_none;
 1056         goto finish;
 1057     }
 1058 
 1059     G_current_load_entry = entry;
 1060 
 1061     if (log_level >= kload_log_level_load_basic) {
 1062 #ifndef KERNEL
 1063         if (do_load) {
 1064 #endif /* not KERNEL */
 1065             kload_log_message("link/loading file %s" KNL, entry->name);
 1066 #ifndef KERNEL
 1067         } else {
 1068             kload_log_message("linking file %s" KNL, entry->name);
 1069         }
 1070 #endif /* not KERNEL */
 1071     }
 1072 
 1073 #ifndef KERNEL
 1074     if (entry->link_output_file != entry->name) {
 1075         symbol_filename = entry->link_output_file;
 1076     }
 1077 
 1078     if (symbol_filename) {
 1079         file_check = kload_file_exists(symbol_filename);
 1080         if (file_check < 0) {
 1081             kload_log_error("error checking existence of file %s" KNL,
 1082                 symbol_filename);
 1083         } else if (file_check > 0 && !overwrite_symbols) {
 1084 
 1085             if (!ask_overwrite_symbols) {
 1086                 kload_log_message("symbol file %s exists; not overwriting" KNL,
 1087                     symbol_filename);
 1088                 symbol_filename = NULL;
 1089             } else {
 1090                 int approve = (*__kload_approve_func)(1,
 1091                     "\nSymbol file %s exists; overwrite", symbol_filename);
 1092 
 1093                 if (approve < 0) {
 1094                     result = kload_error_unspecified;
 1095                     goto finish;
 1096                 } else if (approve == 0) {
 1097                     if (allocated_filename) free(allocated_filename);
 1098                     allocated_filename = NULL;
 1099                     symbol_filename = NULL;
 1100                 }
 1101             }
 1102         }
 1103     }
 1104 
 1105     if (symbol_filename &&
 1106         (interactive_level ||
 1107          log_level >= kload_log_level_basic) ) {
 1108 
 1109         kload_log_message("writing symbol file %s" KNL, symbol_filename);
 1110     }
 1111 
 1112     if (do_load) {
 1113         if (interactive_level && entry->loaded_address) {
 1114             kload_log_message(
 1115                 "module %s is already loaded as %s at address 0x%08x" KNL,
 1116                 entry->name, entry->expected_kmod_name,
 1117                 entry->loaded_address);
 1118         } else if ( (interactive_level == 1 && is_root) ||
 1119              (interactive_level == 2) ) {
 1120 
 1121             int approve = (*__kload_approve_func)(1,
 1122                 "\nLoad module %s", entry->name);
 1123 
 1124             if (approve < 0) {
 1125                 result = kload_error_unspecified;
 1126                 goto finish;
 1127             } else if (approve == 0) {
 1128                 result = kload_error_user_abort;
 1129                 goto finish;
 1130             }
 1131         }
 1132     }
 1133 #endif /* not KERNEL */
 1134 
 1135     entry->object = kld_file_getaddr(entry->name, &entry->object_length);
 1136     if (!entry->object) {
 1137         kload_log_error("kld_file_getaddr() failed for module %s" KNL,
 1138             entry->name);
 1139         __kload_clear_kld_globals();
 1140         result = kload_error_link_load;
 1141         goto finish;
 1142     }
 1143 
 1144     if (entry->is_symbol_set) {
 1145         entry->symbols        = (vm_address_t) entry->object;
 1146         entry->symbols_length = entry->object_length;
 1147 
 1148 #ifndef KERNEL
 1149         if (symbol_filename) {
 1150             if (!_IOWriteBytesToFile(symbol_filename, (void *) entry->symbols, entry->symbols_length)) {
 1151                 kload_log_error("write symbol file failed for module %s" KNL,
 1152                     entry->name);
 1153                 __kload_clear_kld_globals();
 1154                 result = kload_error_link_load;
 1155                 goto finish;
 1156             }
 1157             symbol_filename = 0;
 1158             if (G_prelink && (entry->name != entry->link_output_file))
 1159             {
 1160                 kload_log_error("prelink %s %s %s" KNL,
 1161                     entry->name, entry->link_output_file, entry->expected_kmod_name);
 1162                 register_prelink(entry, NULL, NULL);
 1163             }
 1164         }
 1165 #endif /* not KERNEL */
 1166         if (entry->opaques) {
 1167             result = kload_error_none;
 1168             goto finish;
 1169         }
 1170     }
 1171 
 1172 #ifndef KERNEL
 1173     kld_result = kld_load_from_memory(&kld_header, entry->name,
 1174             entry->object, entry->object_length, symbol_filename);
 1175 #else
 1176     kld_result = kld_load_from_memory(&kld_header, entry->name,
 1177             entry->object, entry->object_length);
 1178 #endif /* not KERNEL */
 1179 
 1180 #ifndef KERNEL
 1181     fflush(stdout);
 1182     fflush(stderr);
 1183 #endif /* not KERNEL */
 1184 
 1185     dgraph->have_loaded_symbols = true;
 1186 
 1187     if (!kld_result || !entry->kernel_load_address) {
 1188         kload_log_error("kld_load_from_memory() failed for module %s" KNL,
 1189             entry->name);
 1190         __kload_clear_kld_globals();
 1191         entry->need_cleanup = 1;
 1192         result = kload_error_link_load;
 1193         goto finish;
 1194     }
 1195 
 1196     if (entry->is_symbol_set) {
 1197         result = kload_error_none;
 1198         goto finish;
 1199     }
 1200 
 1201     entry->linked_image = kld_header;
 1202     entry->linked_image_length = -1;    // unknown!
 1203 
 1204 /* If we're in the kernel and not loading (as when handling an
 1205  * already-loaded dependency), we don't need to waste any CPU
 1206  * cycles looking up the kmod_info struct.
 1207  */
 1208 #ifdef KERNEL
 1209     if (entry->do_load) {
 1210 #endif /* KERNEL */
 1211 
 1212     kld_result = kld_lookup(kmod_symbol, &kernel_kmod_info);
 1213     if (!kld_result) {
 1214         kload_log_error("kld_lookup(\"%s\") failed for module %s" KNL,
 1215             kmod_symbol, entry->name);
 1216         entry->need_cleanup = 1;
 1217         result = kload_error_link_load;
 1218         goto finish;
 1219     }
 1220 
 1221 #ifdef KERNEL
 1222     }
 1223 #endif /* KERNEL */
 1224 
 1225     kld_result = kld_forget_symbol(kmod_symbol);
 1226 #ifndef KERNEL
 1227     fflush(stdout);
 1228     fflush(stderr);
 1229 #endif /* not KERNEL */
 1230     if (!kld_result) {
 1231         kload_log_error("kld_forget_symbol(\"%s\") failed for module %s" KNL,
 1232             kmod_symbol, entry->name);
 1233         entry->need_cleanup = 1;
 1234         result = kload_error_link_load;
 1235         goto finish;
 1236     }
 1237 
 1238 /* This section is always done in userland, but in kernel space
 1239  * only if we're loading the kext, because what we have in kernel
 1240  * space for an already-loaded kext is the kext itself, which
 1241  * must not be touched again after it's been loaded and started.
 1242  */
 1243 #ifdef KERNEL
 1244     if (entry->do_load)
 1245 #endif /* KERNEL */
 1246     {
 1247 
 1248 
 1249    /* Get the linked image's kmod_info by translating from the
 1250     * destined kernel-space address at kernel_kmod_info to an
 1251     * offset from kld_header.
 1252     */
 1253     local_kmod_info = (kmod_info_t *)((unsigned long)kernel_kmod_info -
 1254         (unsigned long)G_current_load_entry->kernel_load_address +
 1255         (unsigned long)kld_header);
 1256 
 1257    /* Stamp the bundle ID and version from the entry over anything
 1258     * resident inside the kmod.
 1259     */
 1260     bzero(local_kmod_info->name, sizeof(local_kmod_info->name));
 1261     strcpy(local_kmod_info->name, entry->expected_kmod_name);
 1262 
 1263     bzero(local_kmod_info->version, sizeof(local_kmod_info->version));
 1264     strcpy(local_kmod_info->version, entry->expected_kmod_vers);
 1265 
 1266     if (log_level >= kload_log_level_details) {
 1267         kload_log_message("kmod name: %s" KNL, local_kmod_info->name);
 1268         kload_log_message("kmod start @ 0x%x (offset 0x%lx)" KNL,
 1269            (vm_address_t)local_kmod_info->start,
 1270            (unsigned long)local_kmod_info->start - (unsigned long)G_current_load_entry->kernel_load_address);
 1271         kload_log_message("kmod stop @ 0x%x (offset 0x%lx)" KNL,
 1272            (vm_address_t)local_kmod_info->stop,
 1273            (unsigned long)local_kmod_info->stop - (unsigned long)G_current_load_entry->kernel_load_address);
 1274     }
 1275 
 1276     if (!local_kmod_info->start || !local_kmod_info->start) {
 1277         kload_log_error(
 1278             "error for module file %s; start or stop address is zero" KNL,
 1279             entry->name);
 1280         entry->need_cleanup = 1;
 1281         result = kload_error_link_load;
 1282         goto finish;
 1283     }
 1284 
 1285    /* Record link info into kmod_info struct, rounding the hdr_size
 1286     * to fit the adjustment that was made in __kload_linkedit_address().
 1287     */
 1288     if (entry->kernel_alloc_address) {
 1289         local_kmod_info->address = entry->kernel_alloc_address;
 1290     } else {
 1291         local_kmod_info->address = entry->loaded_address;
 1292     }
 1293     local_kmod_info->size = entry->kernel_alloc_size;
 1294     local_kmod_info->hdr_size = round_page(entry->kernel_hdr_size);
 1295 
 1296     }
 1297 
 1298 #ifndef KERNEL
 1299     if (G_prelink && (entry->name != entry->link_output_file))
 1300     {
 1301         register_prelink(entry, local_kmod_info, kernel_kmod_info);
 1302     }
 1303 
 1304     if (do_load && entry->do_load) {
 1305         mach_result = vm_allocate(mach_task_self(), &vm_buffer,
 1306             entry->kernel_alloc_size, TRUE);
 1307         if (mach_result != KERN_SUCCESS) {
 1308             kload_log_error("unable to vm_allocate() copy buffer" KNL);
 1309             entry->need_cleanup = 1;
 1310             result = kload_error_no_memory;  // FIXME: kernel error?
 1311             goto finish;
 1312         }
 1313 
 1314         dest_address = (char *)vm_buffer;
 1315 
 1316         memcpy(dest_address, kld_header, entry->kernel_hdr_size);
 1317         memcpy(dest_address + round_page(entry->kernel_hdr_size),
 1318                (void *)((unsigned long)kld_header + entry->kernel_hdr_size),
 1319                entry->kernel_load_size - entry->kernel_hdr_size);
 1320 
 1321         mach_result = vm_write(G_kernel_port, entry->kernel_alloc_address,
 1322             vm_buffer, entry->kernel_alloc_size);
 1323         if (mach_result != KERN_SUCCESS) {
 1324             kload_log_error("unable to write module to kernel memory" KNL);
 1325             entry->need_cleanup = 1;
 1326             result = kload_error_kernel_error;
 1327             goto finish;
 1328         }
 1329 
 1330         mach_result = kmod_create(G_kernel_priv_port,
 1331             (vm_address_t)kernel_kmod_info, &(entry->kmod_id));
 1332 
 1333 #else
 1334     if (entry->do_load) {
 1335         dest_address = (char *)entry->kernel_alloc_address;
 1336         memcpy(dest_address, kld_header, entry->kernel_hdr_size);
 1337         memcpy(dest_address + round_page(entry->kernel_hdr_size),
 1338                (void *)((unsigned long)kld_header + entry->kernel_hdr_size),
 1339                entry->kernel_load_size - entry->kernel_hdr_size);
 1340 
 1341        /* We've written data & instructions into kernel memory, so flush
 1342         * the data cache and invalidate the instruction cache.
 1343         */
 1344         flush_dcache(entry->kernel_alloc_address, entry->kernel_alloc_size, false);
 1345         invalidate_icache(entry->kernel_alloc_address, entry->kernel_alloc_size, false);
 1346 
 1347         mach_result = kmod_create_internal(
 1348             (kmod_info_t *)kernel_kmod_info, &(entry->kmod_id));
 1349 
 1350 #endif /* not KERNEL */
 1351 
 1352         if (mach_result != KERN_SUCCESS) {
 1353             kload_log_error("unable to register module with kernel" KNL);
 1354             entry->need_cleanup = 1;
 1355             result = kload_error_kernel_error;
 1356             goto finish;
 1357         }
 1358 
 1359 #ifndef KERNEL
 1360         if (interactive_level || log_level >= kload_log_level_load_basic) {
 1361 #else
 1362         if (log_level >= kload_log_level_load_basic) {
 1363 #endif /* not KERNEL */
 1364             kload_log_message(
 1365                 "module %s created as # %d at address 0x%x, size %ld" KNL,
 1366                 entry->expected_kmod_name, entry->kmod_id,
 1367                 entry->kernel_alloc_address,
 1368                 entry->kernel_alloc_size);
 1369 
 1370 #ifndef KERNEL
 1371         }
 1372 #else
 1373         }
 1374 #endif /* not KERNEL */
 1375 
 1376 #ifndef KERNEL
 1377         if (interactive_level) {
 1378             kload_log_message(
 1379                 "You can now break to the debugger and set breakpoints "
 1380                 " for this extension." KNL);
 1381         }
 1382 #endif /* not KERNEL */
 1383 
 1384 #ifndef KERNEL
 1385     }
 1386 #else
 1387     }
 1388 #endif /* not KERNEL */
 1389 
 1390 finish:
 1391 
 1392 #ifndef KERNEL
 1393     if (allocated_filename) {
 1394         free(allocated_filename);
 1395     }
 1396     if (vm_buffer) {
 1397         vm_deallocate(mach_task_self(), vm_buffer, entry->kernel_alloc_size);
 1398     }
 1399 #endif /* not KERNEL */
 1400     __kload_clear_kld_globals();
 1401 
 1402     return result;
 1403 }
 1404 
 1405 /*******************************************************************************
 1406 *******************************************************************************/
 1407 
 1408 #ifndef KERNEL
 1409 static kload_error
 1410 register_prelink(dgraph_entry_t * entry, 
 1411                     kmod_info_t * local_kmod_info, vm_offset_t kernel_kmod_info)
 1412 {
 1413     CFIndex i, j, depoffset;
 1414     Boolean exists;
 1415     kmod_info_t desc;
 1416 
 1417     depoffset = CFDataGetLength(G_prelink_dependencies) / sizeof(CFIndex);
 1418 
 1419     for (i = 0; i < entry->num_dependencies; i++)
 1420     {
 1421         exists = false;
 1422         for (j = 1; (j < (1 + G_prelink->modules[0].id)); j++)
 1423         {
 1424             exists = (0 == strcmp(entry->dependencies[i]->expected_kmod_name,
 1425                                     G_prelink->modules[j].name));
 1426             if (exists)
 1427                 break;
 1428         }
 1429         if (!exists)
 1430         {
 1431             bzero(&desc, sizeof(desc));
 1432             strcpy(desc.name, entry->dependencies[i]->expected_kmod_name);
 1433 
 1434             if (log_level >= kload_log_level_basic) {
 1435                 kload_log_message("[%d] (dep)\n    %s" KNL, 
 1436                                     G_prelink->modules[0].id + 1, desc.name);
 1437             }
 1438             G_prelink->modules[0].id++;
 1439             CFDataAppendBytes(G_prelink_data, (UInt8 *) &desc, sizeof(desc));
 1440             G_prelink = (struct PrelinkState *) CFDataGetMutableBytePtr(G_prelink_data);
 1441         }
 1442 
 1443         G_prelink->modules[0].reference_count++;
 1444         OSWriteBigInt32(&j, 0, j);
 1445         CFDataAppendBytes(G_prelink_dependencies, (UInt8 *) &j, sizeof(j));
 1446     }
 1447     if (log_level >= kload_log_level_basic) {
 1448         kload_log_message("[%d] 0x%08x info 0x%08x\n    %s,\n    %s" KNL, 
 1449                             G_prelink->modules[0].id + 1, entry->kernel_load_address,
 1450                             kernel_kmod_info, entry->link_output_file, entry->name);
 1451     }
 1452 
 1453     if (local_kmod_info)
 1454         desc = *local_kmod_info;
 1455     else
 1456     {
 1457         bzero(&desc, sizeof(desc));
 1458         desc.size = entry->symbols_length;
 1459     }
 1460 
 1461     desc.id = kernel_kmod_info;
 1462     desc.reference_count = entry->num_dependencies;
 1463     desc.reference_list  = (kmod_reference_t *) depoffset;
 1464 
 1465     /* Stamp the bundle ID and version from the entry over anything
 1466     * resident inside the kmod.
 1467     */
 1468     bzero(desc.name, sizeof(local_kmod_info->name));
 1469     strcpy(desc.name, entry->expected_kmod_name);
 1470     bzero(desc.version, sizeof(local_kmod_info->version));
 1471     strcpy(desc.version, entry->expected_kmod_vers);
 1472 
 1473     G_prelink->modules[0].id++;
 1474     CFDataAppendBytes(G_prelink_data, (UInt8 *) &desc, sizeof(desc));
 1475     G_prelink = (struct PrelinkState *) CFDataGetMutableBytePtr(G_prelink_data);
 1476 
 1477     return kload_error_none;
 1478 }
 1479 
 1480 #endif
 1481 
 1482 /*******************************************************************************
 1483 *
 1484 *******************************************************************************/
 1485 PRIV_EXT
 1486 #ifndef KERNEL
 1487 kload_error kload_map_dgraph(
 1488     dgraph_t * dgraph,
 1489     const char * kernel_file)
 1490 #else
 1491 kload_error kload_map_dgraph(
 1492     dgraph_t * dgraph)
 1493 #endif /* not KERNEL */
 1494 {
 1495     kload_error result = kload_error_none;
 1496     int i;
 1497 
 1498     if (log_level >= kload_log_level_load_details) {
 1499 #ifndef KERNEL
 1500         kload_log_message("mapping the kernel file %s" KNL, kernel_file);
 1501 #else
 1502         kload_log_message("mapping the kernel" KNL);
 1503 #endif /* not KERNEL */
 1504     }
 1505 
 1506 #ifndef KERNEL
 1507     if (!kld_file_map(kernel_file)) {
 1508         result = kload_error_link_load;
 1509         goto finish;
 1510     }
 1511 #endif /* not KERNEL */
 1512 
 1513     for (i = 0; i < dgraph->length; i++) {
 1514         dgraph_entry_t * entry = dgraph->load_order[i];
 1515 
 1516         if (entry->is_kernel_component && !entry->is_symbol_set) {
 1517             continue;
 1518         }
 1519 
 1520         result = kload_map_entry(entry);
 1521         if (result != kload_error_none) {
 1522             goto finish;
 1523         }
 1524     }
 1525 
 1526 finish:
 1527     return result;
 1528 
 1529 }
 1530 
 1531 /*******************************************************************************
 1532 *
 1533 *******************************************************************************/
 1534 PRIV_EXT
 1535 kload_error kload_map_entry(dgraph_entry_t * entry)
 1536 {
 1537     kload_error result = kload_error_none;
 1538 
 1539     if (entry->is_kernel_component && !entry->is_symbol_set) {
 1540         kload_log_error("attempt to map kernel component %s" KNL, entry->name);
 1541         result = kload_error_invalid_argument;
 1542         goto finish;
 1543     }
 1544 
 1545     if (log_level >= kload_log_level_load_details) {
 1546         kload_log_message("mapping module file %s" KNL, entry->name);
 1547     }
 1548 
 1549     if (kld_file_getaddr(entry->name, NULL)) {
 1550         if (log_level >= kload_log_level_load_details) {
 1551             kload_log_message("module file %s is already mapped" KNL, entry->name);
 1552         }
 1553         result = kload_error_none;
 1554         goto finish;
 1555     }
 1556 
 1557 #ifndef KERNEL
 1558     if (!kld_file_map(entry->name)) {
 1559 #else
 1560     if (!kld_file_map(entry->name, entry->object, entry->object_length,
 1561          entry->object_is_kmem)) {
 1562 #endif /* not KERNEL */
 1563         kload_log_error("error mapping module file %s" KNL, entry->name);
 1564 
 1565         result = kload_error_link_load;
 1566         goto finish;
 1567 #ifndef KERNEL
 1568     }
 1569 #else
 1570     }
 1571 #endif /* not KERNEL */
 1572 
 1573     entry->is_mapped = true;
 1574     
 1575    /* Clear these bits now, as the kld patch module now owns the info
 1576     * and it is subject to change. We reset them in the entry from the
 1577     * kld patch module as needed.
 1578     */
 1579     entry->object = 0;
 1580     entry->object_length = 0;
 1581 #ifdef KERNEL
 1582     entry->object_is_kmem = false;
 1583 #endif /* KERNEL */
 1584 
 1585     // FIXME: Stop using this symbol; have the info passed in by
 1586     // FIXME: ...the kext management library.
 1587 #ifndef KERNEL
 1588     if (!entry->is_kernel_component && !kld_file_lookupsymbol(entry->name, "_kmod_info")) {
 1589         kload_log_error("%s does not not contain kernel extension code" KNL,
 1590             entry->name);
 1591         result = kload_error_executable_bad;
 1592         goto finish;
 1593     }
 1594 #endif /* not KERNEL */
 1595 
 1596 finish:
 1597     return result;
 1598 }
 1599 
 1600 #ifndef KERNEL
 1601 /*******************************************************************************
 1602 *
 1603 *******************************************************************************/
 1604 kload_error kload_request_load_addresses(
 1605     dgraph_t * dgraph,
 1606     const char * kernel_file)
 1607 {
 1608     kload_error result = kload_error_none;
 1609     int i;
 1610     const char * user_response = NULL;  // must free
 1611     int scan_result;
 1612     unsigned int address;
 1613 
 1614    /* We have to map all object files to get their CFBundleIdentifier
 1615     * names.
 1616     */
 1617     result = kload_map_dgraph(dgraph, kernel_file);
 1618     if (result != kload_error_none) {
 1619         kload_log_error("error mapping object files" KNL);
 1620         goto finish;
 1621     }
 1622 
 1623     // fixme: this shouldn't be printf, should it?
 1624     printf("enter the hexadecimal load addresses for these modules:\n");
 1625 
 1626     for (i = 0; i < dgraph->length; i++) {
 1627         dgraph_entry_t * entry = dgraph->load_order[i];
 1628 
 1629         if (!entry) {
 1630             result = kload_error_unspecified;
 1631             goto finish;
 1632         }
 1633 
 1634         if (entry->is_kernel_component) {
 1635             continue;
 1636         }
 1637 
 1638         if (!entry->is_mapped) {
 1639             result = kload_error_unspecified;
 1640             goto finish;
 1641         }
 1642 
 1643         user_response = __kload_input_func("%s:",
 1644             entry->expected_kmod_name);
 1645         if (!user_response) {
 1646             result = kload_error_unspecified;
 1647             goto finish;
 1648         }
 1649         scan_result = sscanf(user_response, "%x", &address);
 1650         if (scan_result < 1 || scan_result == EOF) {
 1651             result = kload_error_unspecified;
 1652             goto finish;
 1653         }
 1654         entry->loaded_address = address;
 1655     }
 1656 
 1657 finish:
 1658     return result;
 1659 
 1660 }
 1661 
 1662 /*******************************************************************************
 1663 * addresses is a NULL-terminated list of string of the form "module_id@address"
 1664 *******************************************************************************/
 1665 kload_error kload_set_load_addresses_from_args(
 1666     dgraph_t * dgraph,
 1667     const char * kernel_file,
 1668     char ** addresses)
 1669 {
 1670     kload_error result = kload_error_none;
 1671     int i, j;
 1672 
 1673 
 1674    /* We have to map all object files to get their CFBundleIdentifier
 1675     * names.
 1676     */
 1677     result = kload_map_dgraph(dgraph, kernel_file);
 1678     if (result != kload_error_none) {
 1679         kload_log_error("error mapping object files" KNL);
 1680         goto finish;
 1681     }
 1682 
 1683    /*****
 1684     * Run through and assign all addresses to their relevant module
 1685     * entries.
 1686     */
 1687     for (i = 0; i < dgraph->length; i++) {
 1688         dgraph_entry_t * entry = dgraph->load_order[i];
 1689 
 1690         if (!entry) {
 1691             result = kload_error_unspecified;
 1692             goto finish;
 1693         }
 1694 
 1695         if (entry->is_kernel_component) {
 1696             continue;
 1697         }
 1698 
 1699         if (!entry->is_mapped) {
 1700             result = kload_error_unspecified;
 1701             goto finish;
 1702         }
 1703 
 1704         for (j = 0; addresses[j]; j++) {
 1705             char * this_addr = addresses[j];
 1706             char * address_string = NULL;
 1707             unsigned int address;
 1708             unsigned int module_namelen = strlen(entry->expected_kmod_name);
 1709 
 1710             if (!this_addr) {
 1711                 result = kload_error_unspecified;
 1712                 goto finish;
 1713             }
 1714 
 1715             if (strncmp(this_addr, entry->expected_kmod_name, module_namelen)) {
 1716                 continue;
 1717             }
 1718             if (this_addr[module_namelen] != '@') {
 1719                 continue;
 1720             }
 1721 
 1722             address_string = index(this_addr, '@');
 1723             if (!address_string) {
 1724                 result = kload_error_unspecified;
 1725                 goto finish;
 1726             }
 1727             address_string++;
 1728             address = strtoul(address_string, NULL, 16);
 1729             entry->loaded_address = address;
 1730         }
 1731     }
 1732 
 1733    /*****
 1734     * Now that we've done that see that all non-kernel modules do have
 1735     * addresses set. If even one doesn't, we can't complete the link
 1736     * relocation of symbols, so return a usage error.
 1737     */
 1738     for (i = 0; i < dgraph->length; i++) {
 1739         dgraph_entry_t * entry = dgraph->load_order[i];
 1740 
 1741         if (entry->is_kernel_component) {
 1742             continue;
 1743         }
 1744 
 1745         if (!entry->loaded_address) {
 1746             result = kload_error_invalid_argument;
 1747             goto finish;
 1748         }
 1749     }
 1750 
 1751 finish:
 1752     return result;
 1753 
 1754 }
 1755 
 1756 /*******************************************************************************
 1757 * This function requires G_kernel_priv_port to be set before it will work.
 1758 *******************************************************************************/
 1759 kload_error kload_set_load_addresses_from_kernel(
 1760     dgraph_t * dgraph,
 1761     const char * kernel_file,
 1762     int do_load)
 1763 {
 1764     kload_error result = kload_error_none;
 1765     int mach_result;
 1766     kmod_info_t * loaded_modules = NULL;
 1767     int           loaded_bytecount = 0;
 1768     unsigned int i;
 1769 
 1770 
 1771    /*****
 1772     * We have to map the dgraph's modules before checking whether they've
 1773     * been loaded.
 1774     */
 1775     result = kload_map_dgraph(dgraph, kernel_file);
 1776     if (result != kload_error_none) {
 1777         kload_log_error("can't map module files" KNL);
 1778         goto finish;
 1779     }
 1780 
 1781 
 1782    /* First clear all the load addresses.
 1783     */
 1784     for (i = 0; i < dgraph->length; i++) {
 1785         struct dgraph_entry_t * entry = dgraph->load_order[i];
 1786         entry->loaded_address = 0;
 1787     }
 1788 
 1789     mach_result = kmod_get_info(G_kernel_priv_port,
 1790             (void *)&loaded_modules, &loaded_bytecount);
 1791     if (mach_result != KERN_SUCCESS) {
 1792         kload_log_error("kmod_get_info() failed" KNL);
 1793         result = kload_error_kernel_error;
 1794         goto finish;
 1795     }
 1796 
 1797    /*****
 1798     * Find out which modules have already been loaded & verify
 1799     * that loaded versions are same as requested.
 1800     */
 1801     for (i = 0; i < dgraph->length; i++) {
 1802         kload_error cresult;
 1803         dgraph_entry_t * current_entry = dgraph->load_order[i];
 1804 
 1805        /* If necessary, check whether the current module is already loaded.
 1806         * (We already did the root module above.)
 1807         */
 1808         cresult = __kload_check_module_loaded(dgraph, current_entry,
 1809             loaded_modules, do_load);
 1810         if ( ! (cresult == kload_error_none ||
 1811                 cresult == kload_error_already_loaded) ) {
 1812             goto finish;
 1813         }
 1814         if (current_entry == dgraph->root &&
 1815             cresult == kload_error_already_loaded) {
 1816 
 1817             result = cresult;
 1818         }
 1819     }
 1820 
 1821 finish:
 1822 
 1823     if (loaded_modules) {
 1824         vm_deallocate(mach_task_self(), (vm_address_t)loaded_modules,
 1825             loaded_bytecount);
 1826         loaded_modules = 0;
 1827     }
 1828 
 1829     return result;
 1830 }
 1831 
 1832 #else
 1833 /*******************************************************************************
 1834 *
 1835 *******************************************************************************/
 1836 PRIV_EXT
 1837 kload_error kload_set_load_addresses_from_kernel(
 1838     dgraph_t * dgraph)
 1839 {
 1840     kload_error result = kload_error_none;
 1841 #ifndef KERNEL
 1842     int mach_result;
 1843     kmod_info_t * loaded_modules = NULL;
 1844     int           loaded_bytecount = 0;
 1845 #endif /* not KERNEL */
 1846     unsigned int i;
 1847 
 1848 
 1849    /*****
 1850     * We have to map the dgraph's modules before checking whether they've
 1851     * been loaded.
 1852     */
 1853     result = kload_map_dgraph(dgraph);
 1854     if (result != kload_error_none) {
 1855         kload_log_error("can't map module files" KNL);
 1856         goto finish;
 1857     }
 1858 
 1859 
 1860    /* First clear all the load addresses.
 1861     */
 1862     for (i = 0; i < dgraph->length; i++) {
 1863         struct dgraph_entry_t * entry = dgraph->load_order[i];
 1864         entry->loaded_address = 0;
 1865     }
 1866 
 1867    /*****
 1868     * Find out which modules have already been loaded & verify
 1869     * that loaded versions are same as requested.
 1870     */
 1871     for (i = 0; i < dgraph->length; i++) {
 1872         kload_error cresult;
 1873         dgraph_entry_t * current_entry = dgraph->load_order[i];
 1874 
 1875        /* If necessary, check whether the current module is already loaded.
 1876         * (We already did the root module above.)
 1877         */
 1878         cresult = __kload_check_module_loaded(dgraph, current_entry, false);
 1879         if ( ! (cresult == kload_error_none ||
 1880                 cresult == kload_error_already_loaded) ) {
 1881             goto finish;
 1882         }
 1883         if (current_entry == dgraph->root &&
 1884             cresult == kload_error_already_loaded) {
 1885 
 1886             result = cresult;
 1887         }
 1888     }
 1889 
 1890 finish:
 1891 
 1892     return result;
 1893 }
 1894 #endif /* not KERNEL */
 1895 
 1896 /*******************************************************************************
 1897 *
 1898 *******************************************************************************/
 1899 #ifdef KERNEL
 1900 extern kern_return_t kmod_load_from_cache(const char * kmod_name);
 1901 #endif /* KERNEL */
 1902 
 1903 static kmod_info_t * __kload_find_kmod_info(const char * kmod_name
 1904 #ifndef KERNEL
 1905     ,
 1906     kmod_info_t * kmod_list
 1907 #endif /* not KERNEL */
 1908     )
 1909 {
 1910 #ifndef KERNEL
 1911     unsigned int i;
 1912 
 1913     for (i = 0; ; i++) {
 1914         kmod_info_t * current_kmod = &(kmod_list[i]);
 1915         if (0 == strcmp(current_kmod->name, kmod_name)) {
 1916             return current_kmod;
 1917         }
 1918         if (kmod_list[i].next == 0) {
 1919             break;
 1920         }
 1921     }
 1922     return NULL;
 1923 #else
 1924     kmod_info_t * info;
 1925     info = kmod_lookupbyname_locked(kmod_name);
 1926     if (!info && (KERN_SUCCESS == kmod_load_from_cache(kmod_name))) {
 1927         info = kmod_lookupbyname_locked(kmod_name);
 1928     }
 1929     return info;
 1930 #endif /* not KERNEL */
 1931 }
 1932 
 1933 /*******************************************************************************
 1934 *
 1935 *******************************************************************************/
 1936 static
 1937 kload_error __kload_check_module_loaded(
 1938     dgraph_t * dgraph,
 1939     dgraph_entry_t * entry,
 1940 #ifndef KERNEL
 1941     kmod_info_t * kmod_list,
 1942 #endif /* not KERNEL */
 1943     int log_if_already)
 1944 {
 1945     kload_error result = kload_error_none;
 1946     const char * kmod_name;
 1947     kmod_info_t * current_kmod = 0;
 1948 
 1949     VERS_version entry_vers;
 1950     VERS_version loaded_vers;
 1951 
 1952     if (false && entry->is_kernel_component) {
 1953         kmod_name = entry->name;
 1954     } else {
 1955         kmod_name = entry->expected_kmod_name;
 1956         if (log_level >= kload_log_level_load_details) {
 1957             kload_log_message("checking whether module file %s is already loaded" KNL,
 1958                 kmod_name);
 1959         }
 1960     }
 1961 
 1962 #ifndef KERNEL
 1963     current_kmod = __kload_find_kmod_info(kmod_name, kmod_list);
 1964 #else
 1965     current_kmod = __kload_find_kmod_info(kmod_name);
 1966 #endif /* not KERNEL */
 1967 
 1968     if (!current_kmod) {
 1969         goto finish;
 1970     }
 1971 
 1972     entry->do_load = 0;
 1973     entry->kmod_id = current_kmod->id;
 1974     entry->loaded_address = current_kmod->address;
 1975 
 1976     if (entry->is_kernel_component) {
 1977         goto finish;
 1978     }
 1979 
 1980     if (log_level >= kload_log_level_load_details) {
 1981         kload_log_message("module file %s is loaded; checking status" KNL,
 1982             kmod_name);
 1983     }
 1984 
 1985     // We really want to move away from having this info in a kmod....
 1986     //
 1987     loaded_vers = VERS_parse_string(current_kmod->version);
 1988     if (loaded_vers < 0) {
 1989         kload_log_error(
 1990             "can't parse version string \"%s\" of loaded module %s" KNL,
 1991             current_kmod->version,
 1992             current_kmod->name);
 1993         result = kload_error_unspecified;
 1994         goto finish;
 1995     }
 1996 
 1997     entry_vers = VERS_parse_string(entry->expected_kmod_vers);
 1998     if (entry_vers < 0) {
 1999         kload_log_error(
 2000             "can't parse version string \"%s\" of module file %s" KNL,
 2001             entry->expected_kmod_name,
 2002             kmod_name);
 2003         result = kload_error_unspecified;
 2004         goto finish;
 2005     }
 2006 
 2007     if (loaded_vers != entry_vers) {
 2008         kload_log_error(
 2009             "loaded version %s of module %s differs from "
 2010             "requested version %s" KNL,
 2011             current_kmod->version,
 2012             current_kmod->name,
 2013             entry->expected_kmod_name);
 2014         if (entry == dgraph->root) {
 2015             result = kload_error_loaded_version_differs;
 2016         } else {
 2017             result = kload_error_dependency_loaded_version_differs;
 2018         }
 2019         goto finish;
 2020     } else {
 2021 
 2022         if (log_if_already && log_level >=
 2023                 kload_log_level_load_basic) {
 2024 
 2025             kload_log_message(
 2026                 "module %s (identifier %s) is already loaded" KNL,
 2027                 entry->name, kmod_name);
 2028         }
 2029         result = kload_error_already_loaded;
 2030         goto finish;
 2031     }
 2032 
 2033 finish:
 2034 #ifdef KERNEL
 2035     // Do this ONLY if in the kernel!
 2036     if (current_kmod) {
 2037         kfree((unsigned int)current_kmod, sizeof(kmod_info_t));
 2038     }
 2039 #endif /* KERNEL */
 2040     return result;
 2041 }
 2042 
 2043 /*******************************************************************************
 2044 *
 2045 *******************************************************************************/
 2046 PRIV_EXT
 2047 kload_error __kload_patch_dgraph(dgraph_t * dgraph
 2048 #ifndef KERNEL
 2049     ,
 2050     const char * kernel_file
 2051 #endif /* not KERNEL */
 2052     )
 2053 {
 2054     kload_error result = kload_error_none;
 2055     unsigned int i;
 2056 
 2057 #ifndef KERNEL
 2058     if (!kld_file_merge_OSObjects(kernel_file)) {
 2059         result = kload_error_link_load;
 2060         goto finish;
 2061     }
 2062 #endif /* not KERNEL */
 2063 
 2064     for (i = 0; i < dgraph->length; i++) {
 2065         dgraph_entry_t * current_entry = dgraph->load_order[i];
 2066 
 2067        /* The kernel has already been patched.
 2068         */
 2069         if (current_entry->is_kernel_component) {
 2070             continue;
 2071         }
 2072 
 2073         if (log_level >= kload_log_level_load_details) {
 2074             kload_log_message("patching C++ code in module %s" KNL,
 2075                 current_entry->name);
 2076         }
 2077 
 2078 #ifndef KERNEL
 2079        /* In userland, we call the patch function for all kmods,
 2080         * loaded or not, because we don't have all the info that
 2081         * the kernel environment has.
 2082         */
 2083         if (!kld_file_patch_OSObjects(current_entry->name)) {
 2084             result = kload_error_link_load;   // FIXME: need a "patch" error?
 2085             goto finish;
 2086         }
 2087 #else
 2088        /* In the kernel, we call the merge function for already-loaded
 2089         * kmods, since the kld patch environment retains info for kmods
 2090         * that have already been patched. The patch function does a little
 2091         * more work, and is only for kmods that haven't been processed yet.
 2092         * NOTE: We are depending here on kload_check_module_loaded()
 2093         * having been called, which is guaranteed by kload_load_dgraph()
 2094         * is used, but not by its subroutines (such as
 2095         * __kload_load_modules()).
 2096         */
 2097         if (current_entry->loaded_address) {
 2098             if (!kld_file_merge_OSObjects(current_entry->name)) {
 2099                 result = kload_error_link_load;   // FIXME: need a "patch" error?
 2100                 goto finish;
 2101             }
 2102         } else {
 2103             if (!kld_file_patch_OSObjects(current_entry->name)) {
 2104                 result = kload_error_link_load;   // FIXME: need a "patch" error?
 2105                 goto finish;
 2106             }
 2107         }
 2108 #endif /* not KERNEL */
 2109 
 2110     }
 2111 
 2112     if (!kld_file_prepare_for_link()) {
 2113         result = kload_error_link_load;   // FIXME: need more specific error?
 2114         goto finish;
 2115     }
 2116 
 2117 finish:
 2118     return result;
 2119 }
 2120 
 2121 #ifndef KERNEL
 2122 /*******************************************************************************
 2123 *
 2124 *******************************************************************************/
 2125 #define __KLOAD_PATCH_EXTENSION ".patch"
 2126 
 2127 kload_error __kload_output_patches(
 2128     dgraph_t * dgraph,
 2129     const char * patch_file,
 2130     const char * patch_dir,
 2131     int ask_overwrite_symbols,
 2132     int overwrite_symbols)
 2133 {
 2134     kload_error result = kload_error_none;
 2135     unsigned int i;
 2136     char * allocated_filename = NULL;
 2137     char * patch_filename = NULL;
 2138     int file_check;
 2139     int output_patch;
 2140 
 2141     if (patch_dir) {
 2142 
 2143         for (i = 0; i < dgraph->length; i++) {
 2144 
 2145             struct dgraph_entry_t * entry = dgraph->load_order[i];
 2146             unsigned long length;
 2147 
 2148             if (entry->is_kernel_component) {
 2149                 continue;
 2150             }
 2151 
 2152             length = strlen(patch_dir) +
 2153                 strlen(entry->expected_kmod_name) +
 2154                 strlen(__KLOAD_PATCH_EXTENSION) +
 2155                 1 + 1 ;   // 1 for '/' added, 1 for terminating null
 2156             if (length >= MAXPATHLEN) {
 2157                 kload_log_error(
 2158                     "output filename \"%s/%s%s\" would be too long" KNL,
 2159                     patch_dir, entry->expected_kmod_name,
 2160                     __KLOAD_PATCH_EXTENSION);
 2161                 result = kload_error_invalid_argument;
 2162                 goto finish;
 2163             }
 2164 
 2165             allocated_filename = (char *)malloc(length);
 2166             if (! allocated_filename) {
 2167                 kload_log_error("malloc failure" KNL);
 2168                 result = kload_error_no_memory;
 2169                 goto finish;
 2170             }
 2171 
 2172             patch_filename = allocated_filename;
 2173             strcpy(patch_filename, patch_dir);
 2174             strcat(patch_filename, "/");
 2175             strcat(patch_filename, entry->expected_kmod_name);
 2176             strcat(patch_filename, __KLOAD_PATCH_EXTENSION);
 2177 
 2178             output_patch = 1;
 2179             file_check = kload_file_exists(patch_filename);
 2180 
 2181             if (file_check < 0) {
 2182                 kload_log_error("error checking existence of file %s" KNL,
 2183                     patch_filename);
 2184             } else if (file_check > 0 && !overwrite_symbols) {
 2185                 if (!ask_overwrite_symbols) {
 2186                     kload_log_error(
 2187                         "patch file %s exists; not overwriting" KNL,
 2188                         patch_filename);
 2189                     output_patch = 0;
 2190                 } else {
 2191                     int approve = (*__kload_approve_func)(1,
 2192                         "\nPatch file %s exists; overwrite", patch_filename);
 2193 
 2194                     if (approve < 0) {
 2195                         result = kload_error_unspecified;
 2196                         goto finish;
 2197                     } else {
 2198                         output_patch = approve;
 2199                     }
 2200                 }
 2201             }
 2202 
 2203             if (output_patch) {
 2204                 if (log_level >= kload_log_level_basic) {
 2205                     kload_log_message("writing patch file %s" KNL, patch_filename);
 2206                 }
 2207                 kld_file_debug_dump(entry->name, patch_filename);
 2208             }
 2209 
 2210             if (allocated_filename) free(allocated_filename);
 2211             allocated_filename = NULL;
 2212         }
 2213 
 2214     } else if (patch_file) {
 2215         output_patch = 1;
 2216         file_check = kload_file_exists(patch_file);
 2217 
 2218         if (file_check < 0) {
 2219             kload_log_error("error checking existence of file %s" KNL,
 2220                 patch_file);
 2221         } else if (file_check > 0 && !overwrite_symbols) {
 2222             if (!ask_overwrite_symbols) {
 2223                 kload_log_error("patch file %s exists; not overwriting" KNL,
 2224                     patch_filename);
 2225                 output_patch = 0;
 2226             } else {
 2227                 int approve = (*__kload_approve_func)(1,
 2228                     "\nPatch file %s exists; overwrite", patch_filename);
 2229 
 2230                 if (approve < 0) {
 2231                     result = kload_error_unspecified;
 2232                     goto finish;
 2233                 } else {
 2234                     output_patch = approve;
 2235                 }
 2236             }
 2237         }
 2238 
 2239         if (output_patch) {
 2240             if (log_level >= kload_log_level_basic) {
 2241                 kload_log_message("writing patch file %s" KNL, patch_filename);
 2242             }
 2243             kld_file_debug_dump(dgraph->root->name, patch_file);
 2244         }
 2245     }
 2246 
 2247 finish:
 2248     if (allocated_filename) free(allocated_filename);
 2249 
 2250     return result;
 2251 }
 2252 #endif /* not KERNEL */
 2253 
 2254 /*******************************************************************************
 2255 *
 2256 *******************************************************************************/
 2257 PRIV_EXT
 2258 kload_error __kload_set_module_dependencies(dgraph_entry_t * entry) {
 2259     kload_error result = kload_error_none;
 2260     int mach_result;
 2261 #ifndef KERNEL
 2262     void * kmod_control_args = 0;
 2263     int num_args = 0;
 2264 #endif /* not KERNEL */
 2265     kmod_t packed_id;
 2266     unsigned int i;
 2267     dgraph_entry_t * current_dep = NULL;
 2268 
 2269     if (!entry->do_load) {
 2270         result = kload_error_already_loaded;
 2271         goto finish;
 2272     }
 2273 
 2274     for (i = 0; i < entry->num_dependencies; i++) {
 2275         current_dep = entry->dependencies[i];
 2276 
 2277         if (log_level >= kload_log_level_load_details) {
 2278             kload_log_message("adding reference from %s (%d) to %s (%d)" KNL,
 2279                 entry->expected_kmod_name, entry->kmod_id,
 2280                 current_dep->expected_kmod_name, current_dep->kmod_id);
 2281         }
 2282 
 2283         packed_id = KMOD_PACK_IDS(entry->kmod_id, current_dep->kmod_id);
 2284 #ifndef KERNEL
 2285         mach_result = kmod_control(G_kernel_priv_port,
 2286                 packed_id, KMOD_CNTL_RETAIN, &kmod_control_args, &num_args);
 2287 #else
 2288         mach_result = kmod_retain(packed_id);
 2289 #endif /* not KERNEL */
 2290         if (mach_result != KERN_SUCCESS) {
 2291             kload_log_error(
 2292                 "kmod retain failed for %s; destroying kmod" KNL,
 2293                 entry->expected_kmod_name);
 2294 #ifndef KERNEL
 2295             mach_result = kmod_destroy(G_kernel_priv_port, entry->kmod_id);
 2296 #else
 2297             mach_result = kmod_destroy_internal(entry->kmod_id);
 2298 #endif /* not KERNEL */
 2299             if (mach_result != KERN_SUCCESS) {
 2300                 kload_log_error("kmod destroy failed" KNL);
 2301             }
 2302             result = kload_error_link_load;
 2303             goto finish;
 2304         }
 2305     }
 2306 
 2307     if (log_level >= kload_log_level_load_basic) {
 2308         kload_log_message("module # %d reference counts incremented" KNL,
 2309             entry->kmod_id);
 2310     }
 2311 
 2312 finish:
 2313     return result;
 2314 }
 2315 
 2316 /*******************************************************************************
 2317 *
 2318 *******************************************************************************/
 2319 PRIV_EXT
 2320 kload_error __kload_start_module(dgraph_entry_t * entry) {
 2321     kload_error result = kload_error_none;
 2322     int mach_result;
 2323 #ifndef KERNEL
 2324     void * kmod_control_args = 0;
 2325     int num_args = 0;
 2326 #endif /* not KERNEL */
 2327 
 2328     if (!entry->do_load) {
 2329         result = kload_error_already_loaded;
 2330         goto finish;
 2331     }
 2332 
 2333 #ifndef KERNEL
 2334     mach_result = kmod_control(G_kernel_priv_port,
 2335             entry->kmod_id, KMOD_CNTL_START, &kmod_control_args, &num_args);
 2336 #else
 2337     mach_result = kmod_start_or_stop(entry->kmod_id, 1, 0, 0);
 2338 #endif /* not KERNEL */
 2339 
 2340     if (mach_result != KERN_SUCCESS) {
 2341         kload_log_error(
 2342             "kmod_control/start failed for %s; destroying kmod" KNL,
 2343             entry->expected_kmod_name);
 2344 #ifndef KERNEL
 2345         mach_result = kmod_destroy(G_kernel_priv_port, entry->kmod_id);
 2346 #else
 2347         mach_result = kmod_destroy_internal(entry->kmod_id);
 2348 #endif /* not KERNEL */
 2349         if (mach_result != KERN_SUCCESS) {
 2350             kload_log_error("kmod destroy failed" KNL);
 2351         }
 2352         result = kload_error_link_load;
 2353         goto finish;
 2354     }
 2355 
 2356     if (log_level >= kload_log_level_load_basic) {
 2357         kload_log_message("module # %d started" KNL,
 2358            entry->kmod_id);
 2359     }
 2360 
 2361 finish:
 2362     return result;
 2363 }
 2364 
 2365 /*******************************************************************************
 2366 *******************************************************************************/
 2367 
 2368 /*******************************************************************************
 2369 *
 2370 *******************************************************************************/
 2371 static
 2372 unsigned long __kload_linkedit_address(
 2373     unsigned long size,
 2374     unsigned long headers_size)
 2375 {
 2376     unsigned long round_segments_size;
 2377     unsigned long round_headers_size;
 2378     unsigned long round_size;
 2379     int mach_result;
 2380     const struct machOMapping {
 2381         struct mach_header h;
 2382         struct segment_command seg[1];
 2383     } *machO;
 2384 
 2385     if (!G_current_load_entry) {
 2386         return 0;
 2387     }
 2388 
 2389     // the actual size allocated by kld_load_from_memory()
 2390     G_current_load_entry->kernel_load_size = size;
 2391 
 2392     round_headers_size = round_page(headers_size);
 2393     round_segments_size = round_page(size - headers_size);
 2394     round_size = round_headers_size + round_segments_size;
 2395 
 2396     G_current_load_entry->kernel_alloc_size = round_size;
 2397 
 2398     // will need to be rounded *after* load/link
 2399     G_current_load_entry->kernel_hdr_size = headers_size;
 2400     G_current_load_entry->kernel_hdr_pad = round_headers_size - headers_size;
 2401     
 2402     if (G_current_load_entry->loaded_address) {
 2403         G_current_load_entry->kernel_load_address =
 2404             G_current_load_entry->loaded_address +
 2405             G_current_load_entry->kernel_hdr_pad;
 2406         if (log_level >= kload_log_level_load_basic) {
 2407             kload_log_message(
 2408                 "using %s load address 0x%x (0x%x with header pad)" KNL,
 2409                 G_current_load_entry->kmod_id ? "existing" : "provided",
 2410                 G_current_load_entry->loaded_address,
 2411                 G_current_load_entry->kernel_load_address);
 2412         }
 2413         return G_current_load_entry->kernel_load_address;
 2414     }
 2415 
 2416     machO = (const struct machOMapping *) G_current_load_entry->object;
 2417     if (machO->seg[0].vmaddr)
 2418     {
 2419         G_current_load_entry->loaded_address = trunc_page(machO->seg[0].vmaddr - machO->seg[0].fileoff);
 2420 
 2421         G_current_load_entry->kernel_load_address = G_current_load_entry->loaded_address 
 2422                 + G_current_load_entry->kernel_hdr_pad;
 2423 
 2424         return G_current_load_entry->kernel_load_address;
 2425     }
 2426 
 2427 #ifndef KERNEL
 2428     if (G_prelink) {
 2429         G_current_load_entry->kernel_alloc_address = G_prelink->modules[0].address;
 2430         G_prelink->modules[0].address += round_page(G_current_load_entry->kernel_alloc_size);
 2431         mach_result = KERN_SUCCESS;
 2432         
 2433     } else if (G_syms_only) {
 2434         kload_log_error(
 2435             "internal error; asked to allocate kernel memory" KNL);
 2436         // FIXME: no provision for cleanup here
 2437         return kload_error_unspecified;
 2438 
 2439     } else
 2440 #endif /* not KERNEL */
 2441 
 2442     {
 2443 #ifndef KERNEL
 2444         mach_result = vm_allocate(G_kernel_port,
 2445                 &G_current_load_entry->kernel_alloc_address,
 2446                 G_current_load_entry->kernel_alloc_size, TRUE);
 2447 #else
 2448         mach_result = vm_allocate(kernel_map,
 2449             &G_current_load_entry->kernel_alloc_address,
 2450             G_current_load_entry->kernel_alloc_size, TRUE);
 2451 #endif /* not KERNEL */
 2452     }
 2453 
 2454     if (mach_result != KERN_SUCCESS) {
 2455         kload_log_error("can't allocate kernel memory" KNL);
 2456         // FIXME: no provision for cleanup here
 2457         return kload_error_kernel_error;
 2458     }
 2459 
 2460     if (log_level >= kload_log_level_load_basic) {
 2461         kload_log_message("allocated %ld bytes in kernel space at 0x%x" KNL,
 2462             G_current_load_entry->kernel_alloc_size,
 2463             G_current_load_entry->kernel_alloc_address);
 2464     }
 2465 
 2466     G_current_load_entry->kernel_load_address =
 2467         G_current_load_entry->kernel_alloc_address +
 2468         G_current_load_entry->kernel_hdr_pad;
 2469 
 2470     G_current_load_entry->loaded_address = G_current_load_entry->kernel_alloc_address;
 2471 
 2472     if (log_level >= kload_log_level_load_basic) {
 2473         kload_log_message(
 2474             "using load address of 0x%x" KNL,
 2475             G_current_load_entry->kernel_alloc_address);
 2476     }
 2477 
 2478     return G_current_load_entry->kernel_load_address;
 2479 }
 2480 
 2481 /*******************************************************************************
 2482 *
 2483 *******************************************************************************/
 2484 static
 2485 void __kload_clear_kld_globals(void) {
 2486     G_current_load_entry = NULL;
 2487     return;
 2488 }
 2489 
 2490 /*******************************************************************************
 2491 *
 2492 *******************************************************************************/
 2493 static
 2494 void __kload_clean_up_entry(dgraph_entry_t * entry) {
 2495     int mach_result;
 2496 
 2497     if (entry->need_cleanup && entry->kernel_alloc_address) {
 2498 #ifndef KERNEL
 2499         if (G_prelink) {
 2500 
 2501             if ((entry->kernel_alloc_address + entry->kernel_alloc_size) == G_prelink->modules[0].address) {
 2502                 G_prelink->modules[0].address = entry->kernel_alloc_address;
 2503             } else {
 2504                 kload_log_error(
 2505                     "bad free load address of 0x%x (last 0x%x)" KNL,
 2506                     entry->kernel_alloc_address, G_prelink->modules[0].address);
 2507             }
 2508         } else {
 2509             mach_result = vm_deallocate(G_kernel_port, entry->kernel_alloc_address,
 2510                 entry->kernel_alloc_size);
 2511         }
 2512 #else
 2513         mach_result = vm_deallocate(kernel_map, entry->kernel_alloc_address,
 2514             entry->kernel_alloc_size);
 2515 #endif /* not KERNEL */
 2516         entry->kernel_alloc_address = 0;
 2517     }
 2518     return;
 2519 }
 2520 
 2521 #ifndef KERNEL
 2522 /*******************************************************************************
 2523 *
 2524 *******************************************************************************/
 2525 int kload_file_exists(const char * path)
 2526 {
 2527     int result = 0;  // assume it doesn't exist
 2528     struct stat stat_buf;
 2529 
 2530     if (stat(path, &stat_buf) == 0) {
 2531         result = 1;  // the file does exist; we don't care beyond that
 2532         goto finish;
 2533     }
 2534 
 2535     switch (errno) {
 2536       case ENOENT:
 2537         result = 0;  // the file doesn't exist
 2538         goto finish;
 2539         break;
 2540       default:
 2541         result = -1;  // unknown error
 2542         goto finish;
 2543         break;
 2544     }
 2545 
 2546 finish:
 2547     return result;
 2548 }
 2549 #endif /* not KERNEL */
 2550 
 2551 /*******************************************************************************
 2552 *
 2553 *******************************************************************************/
 2554 PRIV_EXT
 2555 void kload_set_log_level(kload_log_level level)
 2556 {
 2557     log_level = level;
 2558     return;
 2559 }
 2560 
 2561 #ifndef KERNEL
 2562 /*******************************************************************************
 2563 *
 2564 *******************************************************************************/
 2565 void kload_set_log_function(
 2566     void (*func)(const char * format, ...))
 2567 {
 2568     if (!func) {
 2569         __kload_log_func = &__kload_null_log;
 2570     } else {
 2571         __kload_log_func = func;
 2572     }
 2573     return;
 2574 }
 2575 
 2576 /*******************************************************************************
 2577 *
 2578 *******************************************************************************/
 2579 void kload_set_error_log_function(
 2580     void (*func)(const char * format, ...))
 2581 {
 2582     if (!func) {
 2583         __kload_err_log_func = &__kload_null_err_log;
 2584     } else {
 2585         __kload_err_log_func = func;
 2586     }
 2587     return;
 2588 }
 2589 
 2590 /*******************************************************************************
 2591 *
 2592 *******************************************************************************/
 2593 void kload_set_user_approve_function(
 2594     int (*func)(int default_answer, const char * format, ...))
 2595 {
 2596     if (!func) {
 2597         __kload_approve_func = &__kload_null_approve;
 2598     } else {
 2599         __kload_approve_func = func;
 2600     }
 2601     return;
 2602 }
 2603 
 2604 /*******************************************************************************
 2605 *
 2606 *******************************************************************************/
 2607 void kload_set_user_veto_function(
 2608     int (*func)(int default_answer, const char * format, ...))
 2609 {
 2610     if (!func) {
 2611         __kload_veto_func = &__kload_null_veto;
 2612     } else {
 2613         __kload_veto_func = func;
 2614     }
 2615     return;
 2616 }
 2617 
 2618 /*******************************************************************************
 2619 *
 2620 *******************************************************************************/
 2621 void kload_set_user_input_function(
 2622     const char * (*func)(const char * format, ...))
 2623 {
 2624     if (!func) {
 2625         __kload_input_func = &__kload_null_input;
 2626     } else {
 2627         __kload_input_func = func;
 2628     }
 2629     return;
 2630 }
 2631 
 2632 /*******************************************************************************
 2633 *
 2634 *******************************************************************************/
 2635 PRIV_EXT
 2636 void kload_log_message(const char * format, ...)
 2637 {
 2638     va_list ap;
 2639     char fake_buffer[2];
 2640     int output_length;
 2641     char * output_string;
 2642 
 2643     if (log_level <= kload_log_level_silent) {
 2644         return;
 2645     }
 2646 
 2647     va_start(ap, format);
 2648     output_length = vsnprintf(fake_buffer, 1, format, ap);
 2649     va_end(ap);
 2650 
 2651     output_string = (char *)malloc(output_length + 1);
 2652     if (!output_string) {
 2653         return;
 2654     }
 2655 
 2656     va_start(ap, format);
 2657     vsprintf(output_string, format, ap);
 2658     va_end(ap);
 2659 
 2660     __kload_log_func(output_string);
 2661     free(output_string);
 2662 
 2663     return;
 2664 }
 2665 
 2666 /*******************************************************************************
 2667 *
 2668 *******************************************************************************/
 2669 PRIV_EXT
 2670 void kload_log_error(const char * format, ...)
 2671 {
 2672     va_list ap;
 2673     char fake_buffer[2];
 2674     int output_length;
 2675     char * output_string;
 2676 
 2677     if (log_level <= kload_log_level_silent) {
 2678         return;
 2679     }
 2680 
 2681     va_start(ap, format);
 2682     output_length = vsnprintf(fake_buffer, 1, format, ap);
 2683     va_end(ap);
 2684 
 2685     output_string = (char *)malloc(output_length + 1);
 2686     if (!output_string) {
 2687         return;
 2688     }
 2689 
 2690     va_start(ap, format);
 2691     vsprintf(output_string, format, ap);
 2692     va_end(ap);
 2693 
 2694     __kload_err_log_func(output_string);
 2695     free(output_string);
 2696 
 2697     return;
 2698 }
 2699 /*******************************************************************************
 2700 *
 2701 *******************************************************************************/
 2702 void __kload_null_log(const char * format, ...)
 2703 {
 2704     return;
 2705 }
 2706 
 2707 /*******************************************************************************
 2708 *
 2709 *******************************************************************************/
 2710 void __kload_null_err_log(const char * format, ...)
 2711 {
 2712     return;
 2713 }
 2714 
 2715 /*******************************************************************************
 2716 *
 2717 *******************************************************************************/
 2718 int __kload_null_approve(int default_answer, const char * format, ...)
 2719 {
 2720     return 0;
 2721 }
 2722 
 2723 /*******************************************************************************
 2724 *
 2725 *******************************************************************************/
 2726 int __kload_null_veto(int default_answer, const char * format, ...)
 2727 {
 2728     return 1;
 2729 }
 2730 
 2731 /*******************************************************************************
 2732 *
 2733 *******************************************************************************/
 2734 const char * __kload_null_input(const char * format, ...)
 2735 {
 2736     return NULL;
 2737 }
 2738 
 2739 /*******************************************************************************
 2740 * The kld_patch.c module uses this function, if defined, to print errors. In
 2741 * the kernel this function is defined in libsa/misc.c.
 2742 *******************************************************************************/
 2743 void kld_error_vprintf(const char * format, va_list ap) {
 2744     if (log_level <= kload_log_level_silent) return;
 2745     vfprintf(stderr, format, ap);
 2746     return;
 2747 }
 2748 
 2749 #endif /* not KERNEL */

Cache object: 8feda68432d7011ef47d1cd835112240


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.