+ /*
+ * Make sure what we get from the file is really ours (as specified
+ * by macho_size).
+ */
+ if (scp64->fileoff + scp64->filesize > (uint64_t)macho_size)
+ return (LOAD_BADMACHO);
+
+ seg_size = round_page_64(scp64->vmsize);
+ if (seg_size == 0)
+ return(KERN_SUCCESS);
+
+ /*
+ * Round sizes to page size.
+ */
+ map_size = round_page_64(scp64->filesize); /* limited to 32 bits */
+ map_addr = round_page_64(scp64->vmaddr);
+
+ if (map_addr == 0 &&
+ map_size == 0 &&
+ seg_size != 0 &&
+ (scp64->initprot & VM_PROT_ALL) == VM_PROT_NONE &&
+ (scp64->maxprot & VM_PROT_ALL) == VM_PROT_NONE) {
+ /*
+ * This is a "page zero" segment: it starts at address 0,
+ * is not mapped from the binary file and is not accessible.
+ * User-space should never be able to access that memory, so
+ * make it completely off limits by raising the VM map's
+ * minimum offset.
+ */
+ ret = vm_map_raise_min_offset(map, seg_size);
+ if (ret != KERN_SUCCESS) {
+ return LOAD_FAILURE;
+ }
+ return LOAD_SUCCESS;
+ }
+
+ map_offset = pager_offset + scp64->fileoff; /* limited to 32 bits */
+
+ if (map_size > 0) {
+ initprot = (scp64->initprot) & VM_PROT_ALL;
+ maxprot = (scp64->maxprot) & VM_PROT_ALL;
+ /*
+ * Map a copy of the file into the address space.
+ */
+ ret = mach_vm_map(map,
+ &map_addr, map_size, (mach_vm_offset_t)0,
+ VM_FLAGS_FIXED, pager, map_offset, TRUE,
+ initprot, maxprot,
+ VM_INHERIT_DEFAULT);
+ if (ret != KERN_SUCCESS)
+ return(LOAD_NOSPACE);
+
+ /*
+ * If the file didn't end on a page boundary,
+ * we need to zero the leftover.
+ */
+ delta_size = map_size - scp64->filesize;
+#if FIXME
+ if (delta_size > 0) {
+ mach_vm_offset_t tmp;
+
+ ret = vm_allocate(kernel_map, &tmp, delta_size, VM_FLAGS_ANYWHERE);
+ if (ret != KERN_SUCCESS)
+ return(LOAD_RESOURCE);
+
+ if (copyout(tmp, map_addr + scp64->filesize,
+ delta_size)) {
+ (void) vm_deallocate(
+ kernel_map, tmp, delta_size);