-
- /*
- * Capture the kernel's mach_header in its entirety and the contents of
- * its LINKEDIT segment (and only that segment). This is sufficient to
- * build all the fbt probes lazily the first time a client looks to
- * the fbt provider. Remeber these on the global struct modctl g_fbt_kernctl.
- */
- header_size = sizeof(kernel_mach_header_t) + _mh_execute_header.sizeofcmds;
- p = getsegdatafromheader(&_mh_execute_header, SEG_LINKEDIT, &size);
-
- round_size = round_page(header_size + size);
- /* "q" will accomodate copied kernel_mach_header_t, its load commands, and LINKEIT segment. */
- ret = kmem_alloc_pageable(kernel_map, (vm_offset_t *)&q, round_size);
-
- if (p && (ret == KERN_SUCCESS)) {
- kernel_segment_command_t *sgp;
-
- bcopy( (void *)&_mh_execute_header, q, header_size);
- bcopy( p, (char *)q + header_size, size);
-
- sgp = getsegbynamefromheader(q, SEG_LINKEDIT);
-
- if (sgp) {
- sgp->vmaddr = (uintptr_t)((char *)q + header_size);
- g_fbt_kernctl.address = (vm_address_t)q;
- g_fbt_kernctl.size = header_size + size;
- } else {
- kmem_free(kernel_map, (vm_offset_t)q, round_size);
- g_fbt_kernctl.address = (vm_address_t)NULL;
- g_fbt_kernctl.size = 0;
- }
- } else {
- if (ret == KERN_SUCCESS)
- kmem_free(kernel_map, (vm_offset_t)q, round_size);
- g_fbt_kernctl.address = (vm_address_t)NULL;
- g_fbt_kernctl.size = 0;
- }
-
- strncpy((char *)&(g_fbt_kernctl.mod_modname), "mach_kernel", KMOD_MAX_NAME);
- ((char *)&(g_fbt_kernctl.mod_modname))[KMOD_MAX_NAME -1] = '\0';