xf.li | bdd93d5 | 2023-05-12 07:10:14 -0700 | [diff] [blame] | 1 | /* Operating system support for run-time dynamic linker. NaCl version. |
| 2 | Copyright (C) 2015-2016 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. |
| 4 | |
| 5 | The GNU C Library is free software; you can redistribute it and/or |
| 6 | modify it under the terms of the GNU Lesser General Public |
| 7 | License as published by the Free Software Foundation; either |
| 8 | version 2.1 of the License, or (at your option) any later version. |
| 9 | |
| 10 | The GNU C Library is distributed in the hope that it will be useful, |
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 13 | Lesser General Public License for more details. |
| 14 | |
| 15 | You should have received a copy of the GNU Lesser General Public |
| 16 | License along with the GNU C Library; if not, see |
| 17 | <http://www.gnu.org/licenses/>. */ |
| 18 | |
| 19 | #ifdef SHARED |
| 20 | |
| 21 | # include <assert.h> |
| 22 | # include <ldsodefs.h> |
| 23 | # include <stdint.h> |
| 24 | # include <nacl-interfaces.h> |
| 25 | |
| 26 | /* NaCl's elf32.h is incompatible with the real <elf.h>. */ |
| 27 | # define NATIVE_CLIENT_SRC_INCLUDE_ELF32_H_ |
| 28 | # include <native_client/src/untrusted/nacl/nacl_startup.h> |
| 29 | |
| 30 | /* The RTLD_START code sets up the pointer that gets to these |
| 31 | macros as COOKIE to point to two words: |
| 32 | [0] the argument to the entry point from the system (see nacl_startup.h) |
| 33 | [1] the stack base |
| 34 | */ |
| 35 | |
| 36 | # define DL_FIND_ARG_COMPONENTS(cookie, argc, argv, envp, auxp) \ |
| 37 | do { \ |
| 38 | uint32_t *_info = ((void **) (cookie))[0]; \ |
| 39 | (argc) = nacl_startup_argc (_info); \ |
| 40 | (argv) = nacl_startup_argv (_info); \ |
| 41 | (envp) = nacl_startup_envp (_info); \ |
| 42 | (auxp) = nacl_startup_auxv (_info); \ |
| 43 | } while (0) |
| 44 | |
| 45 | # define DL_STACK_END(cookie) (((void **) (cookie))[1]) |
| 46 | |
| 47 | /* This is called from the entry point (_start), defined by the RTLD_START |
| 48 | macro in the machine-specific dl-machine.h file. At this point, dynamic |
| 49 | linking has been completed and the first argument is the application's |
| 50 | entry point. */ |
| 51 | attribute_hidden internal_function __attribute__ ((noreturn)) |
| 52 | void |
| 53 | _dl_start_user (void (*user_entry) (uint32_t info[]), uint32_t info[]) |
| 54 | { |
| 55 | if (_dl_skip_args > 0) |
| 56 | { |
| 57 | /* There are some arguments that the user program should not see. |
| 58 | Just slide up the INFO pointer so its NACL_STARTUP_ARGV points |
| 59 | to what should now be argv[0], and copy back the earlier fields. */ |
| 60 | assert (nacl_startup_argc (info) >= _dl_skip_args); |
| 61 | assert (NACL_STARTUP_ARGV == 3); |
| 62 | uint32_t envc = info[NACL_STARTUP_ENVC]; |
| 63 | uint32_t argc = info[NACL_STARTUP_ARGC]; |
| 64 | info += _dl_skip_args; |
| 65 | info[NACL_STARTUP_ENVC] = envc; |
| 66 | info[NACL_STARTUP_ARGC] = argc - _dl_skip_args; |
| 67 | } |
| 68 | |
| 69 | /* Pass our finalizer function to the user. */ |
| 70 | info[NACL_STARTUP_FINI] = (uintptr_t) &_dl_fini; |
| 71 | |
| 72 | /* Run initializers. */ |
| 73 | _dl_init (GL(dl_ns)[0]._ns_loaded, |
| 74 | nacl_startup_argc (info), |
| 75 | nacl_startup_argv (info), |
| 76 | nacl_startup_envp (info)); |
| 77 | |
| 78 | /* Call the user's entry point. This should never return. */ |
| 79 | (*user_entry) (info); |
| 80 | |
| 81 | /* Fail clearly just in case it did return. */ |
| 82 | __builtin_trap (); |
| 83 | } |
| 84 | |
| 85 | # define DL_SYSDEP_INIT __nacl_initialize_interfaces () |
| 86 | |
| 87 | #endif /* SHARED */ |
| 88 | |
| 89 | #include <elf/dl-sysdep.c> |
| 90 | |
| 91 | #include <dl-sysdep-open.h> |
| 92 | #include <nacl-interfaces.h> |
| 93 | #include <assert.h> |
| 94 | #include <string.h> |
| 95 | #include <unistd.h> |
| 96 | |
| 97 | char * |
| 98 | internal_function |
| 99 | _dl_sysdep_open_object (const char *name, size_t namelen, int *fd) |
| 100 | { |
| 101 | int error = __nacl_irt_resource_open.open_resource (name, fd); |
| 102 | if (error) |
| 103 | return NULL; |
| 104 | assert (*fd != -1); |
| 105 | char *realname = __strdup (name); |
| 106 | if (__glibc_unlikely (realname == NULL)) |
| 107 | { |
| 108 | __close (*fd); |
| 109 | *fd = -1; |
| 110 | } |
| 111 | return realname; |
| 112 | } |