]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Part way to rtld startup.
authorRoland McGrath <roland@hack.frob.com>
Tue, 7 May 2013 21:51:54 +0000 (14:51 -0700)
committerRoland McGrath <roland@hack.frob.com>
Tue, 7 May 2013 21:51:54 +0000 (14:51 -0700)
sysdeps/arm/nacl/dl-machine.h
sysdeps/nacl/dl-osinfo.h
sysdeps/nacl/dl-sysdep.c [new file with mode: 0644]
sysdeps/nacl/dl-sysdep.h
sysdeps/nacl/entry.h [new file with mode: 0644]

index aa9202f80de76fe9f6ce95470d62b54d3524fc50..97a06f4d4072cd6535d235ef70a27556fe2c78e6 100644 (file)
@@ -20,7 +20,7 @@
 
 /* This is only needed for handling TEXTRELs and NaCl will never
    support TEXTRELs at all.  */
-#define CLEAR_CACHE(start, end) abort ()
+#define CLEAR_CACHE(start, end) __builtin_trap ()
 
 #endif
 
    This #include is outside the #ifndef because the parts of
    dl-machine.h used only by dynamic-link.h are outside the guard.  */
 #include <sysdeps/arm/dl-machine.h>
+
+#ifdef dl_machine_h
+
+/* Initial entry point code for the dynamic linker.
+   The C function `_dl_start' is the real entry point;
+   its return value is the user program's entry point.  */
+#undef RTLD_START
+#define RTLD_START asm ("\
+.text\n\
+.globl _start\n\
+.type _start, %function\n\
+_start:\n\
+        @ r0 has the pointer to the info block (see nacl_startup.h)\n\
+        mov r1, sp              @ Save stack base for __libc_stack_end.\n\
+        push {r0-r3}            @ Push those, maintaining alignment to 16.\n\
+        mov r0, sp              @ Pointer to {info, sp} is argument.\n\
+        sfi_bl _dl_start\n\
+        pop {r1-r4}             @ Restore stack, getting info block into r1.\n\
+        mov lr, #0              @ Return address for noreturn call.\n\
+        b _dl_start_user");
+
+#endif
index 505eb4ba864084dd3b93d2ebc655bdf75c4ac150..0aacf4ec45f584540aef99e1d237926c90678d38 100644 (file)
 
 #include "nacl-interfaces.h"
 
+#ifndef SHARED
 /* This doesn't really have anything to do with the purpose for
    which this macro is used in Linux configurations.  But it is
    called at the right place in __libc_start_main.  */
-
-#define DL_SYSDEP_OSCHECK(fatal)        __nacl_initialize_interfaces ()
+# define DL_SYSDEP_OSCHECK(fatal)      __nacl_initialize_interfaces ()
+#endif
 
 
 #endif /* dl-osinfo.h */
diff --git a/sysdeps/nacl/dl-sysdep.c b/sysdeps/nacl/dl-sysdep.c
new file mode 100644 (file)
index 0000000..7e6a092
--- /dev/null
@@ -0,0 +1,83 @@
+/* Operating system support for run-time dynamic linker.  NaCl version.
+   Copyright (C) 2013 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifdef SHARED
+
+#include <assert.h>
+#include <ldsodefs.h>
+#include <stdint.h>
+
+/* NaCl's elf32.h is incompatible with the real <elf.h>.  */
+#define NATIVE_CLIENT_SRC_INCLUDE_ELF32_H_
+#include <native_client/src/untrusted/nacl/nacl_startup.h>
+
+/* The RTLD_START code sets up the pointer that gets to these
+   macros as COOKIE to point to two words:
+   [0] the argument to the entry point from the system (see nacl_startup.h)
+   [1] the stack base
+*/
+
+#define DL_FIND_ARG_COMPONENTS(cookie, argc, argv, envp, auxp) \
+  do {                                                         \
+    uint32_t *_info = ((void **) (cookie))[0];                 \
+    (argc) = nacl_startup_argc (_info);                                \
+    (argv) = nacl_startup_argv (_info);                                \
+    (envp) = nacl_startup_envp (_info);                                \
+    (auxp) = nacl_startup_auxv (_info);                                \
+  } while (0)
+
+#define DL_STACK_END(cookie)   (((void **) (cookie))[1])
+
+/* This is called from the entry point (_start), defined by the RTLD_START
+   macro in the machine-specific dl-machine.h file.  At this point, dynamic
+   linking has been completed and the first argument is the application's
+   entry point.  */
+attribute_hidden internal_function
+void
+_dl_start_user (void (*user_entry) (uint32_t info[]), uint32_t info[])
+{
+  if (_dl_skip_args > 0)
+    {
+      /* There are some arguments that the user program should not see.
+         Just slide up the INFO pointer so its NACL_STARTUP_ARGV points
+         to what should now be argv[0], and copy back the earlier fields.  */
+      assert (nacl_startup_argc (info) >= _dl_skip_args);
+      assert (NACL_STARTUP_ARGV == 3);
+      uint32_t envc = info[NACL_STARTUP_ENVC];
+      uint32_t argc = info[NACL_STARTUP_ARGC];
+      info += _dl_skip_args;
+      info[NACL_STARTUP_ENVC] = envc;
+      info[NACL_STARTUP_ARGC] = argc - _dl_skip_args;
+    }
+
+  /* Pass our finalizer function to the user.  */
+  info[NACL_STARTUP_FINI] = (uintptr_t) &_dl_fini;
+
+  /* Run initializers.  */
+  _dl_init (GL(dl_ns)[0]._ns_loaded,
+            nacl_startup_argc (info),
+            nacl_startup_argv (info),
+            nacl_startup_envp (info));
+
+  /* Call the user's entry point.  This should never return.  */
+  (*user_entry) (info);
+}
+
+#endif  /* SHARED */
+
+#include <elf/dl-sysdep.c>
index 19c23cb0ac4322411b2dc3990dc991dfaa555428..86813dde5ecfb0d92b9cdae0daac458455dffa1d 100644 (file)
@@ -25,3 +25,6 @@
    but we too want to store its value.  */
 #define NEED_DL_SYSINFO         1
 #define DL_SYSINFO_DEFAULT      0
+
+/* sysdeps/arm/dl-sysdep.h defines this but it does not apply to NaCl.  */
+#undef  DL_ARGV_NOT_RELRO
diff --git a/sysdeps/nacl/entry.h b/sysdeps/nacl/entry.h
new file mode 100644 (file)
index 0000000..e9dc190
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef __ASSEMBLY__
+# include <stdint.h>
+extern void _start (uint32_t info[]) attribute_hidden;
+#endif
+
+#define ENTRY_POINT _start