+static
+load_return_t
+load_uuid(
+ struct uuid_command *uulp,
+ char *command_end,
+ load_result_t *result
+)
+{
+ /*
+ * We need to check the following for this command:
+ * - The command size should be atleast the size of struct uuid_command
+ * - The UUID part of the command should be completely within the mach-o header
+ */
+
+ if ((uulp->cmdsize < sizeof(struct uuid_command)) ||
+ (((char *)uulp + sizeof(struct uuid_command)) > command_end)) {
+ return (LOAD_BADMACHO);
+ }
+
+ memcpy(&result->uuid[0], &uulp->uuid[0], sizeof(result->uuid));
+ return (LOAD_SUCCESS);
+}
+
+static
+load_return_t
+load_main(
+ struct entry_point_command *epc,
+ thread_t thread,
+ int64_t slide,
+ load_result_t *result
+)
+{
+ mach_vm_offset_t addr;
+ kern_return_t ret;
+
+ if (epc->cmdsize < sizeof(*epc))
+ return (LOAD_BADMACHO);
+ if (result->thread_count != 0) {
+ return (LOAD_FAILURE);
+ }
+
+ if (thread == THREAD_NULL)
+ return (LOAD_SUCCESS);
+
+ /* LC_MAIN specifies stack size but not location */
+ if (epc->stacksize) {
+ result->prog_stack_size = 1;
+ result->user_stack_size = epc->stacksize;
+ } else {
+ result->prog_stack_size = 0;
+ result->user_stack_size = MAXSSIZ;
+ }
+ result->prog_allocated_stack = 0;
+
+ /* use default location for stack */
+ ret = thread_userstackdefault(thread, &addr);
+ if (ret != KERN_SUCCESS)
+ return(LOAD_FAILURE);
+
+ /* The stack slides down from the default location */
+ result->user_stack = addr;
+ result->user_stack -= slide;
+
+ if (result->using_lcmain || result->entry_point != MACH_VM_MIN_ADDRESS) {
+ /* Already processed LC_MAIN or LC_UNIXTHREAD */
+ return (LOAD_FAILURE);
+ }
+
+ /* kernel does *not* use entryoff from LC_MAIN. Dyld uses it. */
+ result->needs_dynlinker = TRUE;
+ result->using_lcmain = TRUE;
+
+ ret = thread_state_initialize( thread );
+ if (ret != KERN_SUCCESS) {
+ return(LOAD_FAILURE);
+ }
+
+ result->unixproc = TRUE;
+ result->thread_count++;
+
+ return(LOAD_SUCCESS);
+}
+
+