| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 #include <assert.h> |
| 7 #include <unistd.h> | 8 #include <unistd.h> |
| 8 | 9 |
| 9 #include "native_client/src/include/elf32.h" | 10 #include "native_client/src/include/elf32.h" |
| 10 #include "native_client/src/include/elf_auxv.h" | 11 #include "native_client/src/include/elf_auxv.h" |
| 11 #include "native_client/src/untrusted/irt/irt_elf_utils.h" | |
| 12 #include "native_client/src/untrusted/irt/irt_interfaces.h" | 12 #include "native_client/src/untrusted/irt/irt_interfaces.h" |
| 13 #include "native_client/src/untrusted/nacl/nacl_irt.h" |
| 14 #include "native_client/src/untrusted/nacl/nacl_startup.h" |
| 13 | 15 |
| 16 void __libc_init_array(void); |
| 14 | 17 |
| 15 void jump_to_elf_start(void *initial_stack_pointer, | 18 void __pthread_initialize(void); |
| 16 uintptr_t entry_point, | 19 void __pthread_shutdown(void); |
| 17 uintptr_t atexit_func); | |
| 18 | 20 |
| 19 /* | 21 /* |
| 20 * We have a typedef for the size of argc on the stack because this | 22 * This is the true entry point for untrusted code. |
| 21 * varies between NaCl platforms. | 23 * See nacl_startup.h for the layout at the argument pointer. |
| 22 * See http://code.google.com/p/nativeclient/issues/detail?id=1226 | |
| 23 * TODO(mseaborn): Unify the ABIs. | |
| 24 */ | 24 */ |
| 25 #if defined(__x86_64__) | 25 void _start(uint32_t *info) { |
| 26 typedef int64_t argc_type; | 26 void (*fini)(void) = nacl_startup_fini(info); |
| 27 #else | 27 char **envp = nacl_startup_envp(info); |
| 28 typedef int32_t argc_type; | 28 Elf32_auxv_t *auxv = nacl_startup_auxv(info); |
| 29 #endif | |
| 30 | 29 |
| 31 int main(int argc, char **argv) { | 30 environ = envp; |
| 32 struct auxv_entry *auxv = __find_auxv(argc, argv); | 31 |
| 33 struct auxv_entry *entry = __find_auxv_entry(auxv, AT_ENTRY); | 32 /* |
| 33 * TODO(mcgrathr): This ought to use IRT-private tables explicitly. |
| 34 */ |
| 35 __libnacl_irt_init(auxv); |
| 36 |
| 37 /* |
| 38 * We are the true entry point, never called by a dynamic linker. |
| 39 * So the finalizer function pointer is always NULL. |
| 40 * We don't bother registering anything with atexit anyway, |
| 41 * since we do not expect our own exit function ever to be called. |
| 42 * Any cleanup we might need done must happen in nacl_irt_exit (irt_basic.c). |
| 43 */ |
| 44 assert(fini == NULL); |
| 45 |
| 46 __pthread_initialize(); |
| 47 |
| 48 __libc_init_array(); |
| 49 |
| 50 Elf32_auxv_t *entry = NULL; |
| 51 for (Elf32_auxv_t *av = auxv; av->a_type != AT_NULL; ++av) { |
| 52 if (av->a_type == AT_ENTRY) { |
| 53 entry = av; |
| 54 break; |
| 55 } |
| 56 } |
| 34 if (entry == NULL) { | 57 if (entry == NULL) { |
| 35 static const char fatal_msg[] = | 58 static const char fatal_msg[] = |
| 36 "irt_entry: No AT_ENTRY item found in auxv. " | 59 "irt_entry: No AT_ENTRY item found in auxv. " |
| 37 "Is there no user executable loaded?\n"; | 60 "Is there no user executable loaded?\n"; |
| 38 write(2, fatal_msg, sizeof(fatal_msg) - 1); | 61 write(2, fatal_msg, sizeof(fatal_msg) - 1); |
| 39 _exit(127); | 62 _exit(-1); |
| 40 } | 63 } |
| 41 uintptr_t entry_point = entry->a_val; | 64 void (*user_start)(uint32_t *) = (void (*)(uint32_t *)) entry->a_un.a_val; |
| 42 | 65 |
| 43 /* | 66 /* |
| 44 * The user application does not need to see the AT_ENTRY item. | 67 * The user application does not need to see the AT_ENTRY item. |
| 45 * Reuse the auxv slot and overwrite it with the IRT query function. | 68 * Reuse the auxv slot and overwrite it with the IRT query function. |
| 46 */ | 69 */ |
| 47 entry->a_type = AT_SYSINFO; | 70 entry->a_type = AT_SYSINFO; |
| 48 entry->a_val = (uintptr_t) nacl_irt_interface; | 71 entry->a_un.a_val = (uintptr_t) nacl_irt_interface; |
| 49 | 72 |
| 50 void *stack_pointer = (char *) argv - sizeof(argc_type); | 73 /* |
| 51 jump_to_elf_start(stack_pointer, entry_point, 0); | 74 * Call the user entry point function. It should not return. |
| 75 */ |
| 76 (*user_start)(info); |
| 52 | 77 |
| 53 /* This should never be reached. */ | 78 /* |
| 54 return 0; | 79 * But just in case it does... |
| 80 */ |
| 81 _exit(0); |
| 55 } | 82 } |
| 83 |
| 84 /* |
| 85 * This is never actually called, but there is an artificial undefined |
| 86 * reference to it. |
| 87 */ |
| 88 int main(void) { |
| 89 } |
| OLD | NEW |