Browse Source

ldso: sh: handle _dl_skip_args in linker startup instead of __uClibc_main

Handle _dl_skip_args in the asm part of the dynamic linker startup,
to skip the ldso arguments, so we can keep this symbol hidden as other archs do.

Signed-off-by: Filippo Arcidiacono <filippo.arcidiacono@st.com>
Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
Filippo Arcidiacono 12 years ago
parent
commit
f8111809ba
3 changed files with 10 additions and 26 deletions
  1. 0 10
      ldso/ldso/ldso.c
  2. 10 0
      ldso/ldso/sh/dl-startup.h
  3. 0 16
      libc/misc/internals/__uClibc_main.c

+ 0 - 10
ldso/ldso/ldso.c

@@ -77,17 +77,7 @@ char *_dl_debug_bindings  = NULL;
 int   _dl_debug_file      = 2;
 #endif
 
-#if defined (__LDSO_STANDALONE_SUPPORT__) && defined (__sh__)
-/* Not hidden, needed for standalone execution. */
-/*
- * FIXME: align dl_start for SH to other archs so that we can keep this symbol
- *        hidden and we don't need to handle in __uClibc_main
- */
-
-unsigned long _dl_skip_args = 0;
-#else
 unsigned long attribute_hidden _dl_skip_args = 0;
-#endif
 
 const char *_dl_progname = UCLIBC_LDSO;      /* The name of the executable being run */
 #include "dl-startup.c"

+ 10 - 0
ldso/ldso/sh/dl-startup.h

@@ -17,12 +17,22 @@ __asm__(
     "	mov.l   .L_got, r12   ! Load the GOT on r12\n"
     "	mova    .L_got, r0\n"
     "	add     r0, r12\n"
+    "	mov.l .L_dl_skip_args,r0\n"
+    "	mov.l @(r0,r12),r0\n"
+    "	mov.l @r0,r0\n"
+    "	mov.l @r15,r5         ! Get the original argument count\n"
+    "	sub r0,r5             ! Subtract _dl_skip_args from it\n"
+    "	shll2 r0\n"
+    "	add r0,r15 ! Adjust the stack pointer to skip _dl_skip_args words\n"
+    "	mov.l r5,@r15         ! Store back the modified argument count\n"
     "	mov.l   .L_dl_fini, r0\n"
     "	mov.l   @(r0,r12), r4 ! Pass the finalizer in r4\n"
     "	jmp     @r8\n"
     "	nop\n"
     ".L_dl_start:\n"
     "	.long   _dl_start-.jmp_loc\n"
+    ".L_dl_skip_args:\n"
+    "	.long   _dl_skip_args@GOT\n"
     ".L_dl_fini:\n"
     "	.long	_dl_fini@GOT\n"
     ".L_got:\n"

+ 0 - 16
libc/misc/internals/__uClibc_main.c

@@ -146,10 +146,6 @@ extern void (*__fini_array_end []) (void) attribute_hidden;
 # endif
 #endif
 
-#if defined (__LDSO_STANDALONE_SUPPORT__) && defined (SHARED) && defined __sh__
-extern unsigned long _dl_skip_args;
-#endif
-
 attribute_hidden const char *__uclibc_progname = "";
 #ifdef __UCLIBC_HAS_PROGRAM_INVOCATION_NAME__
 const char *program_invocation_short_name = "";
@@ -339,18 +335,6 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
 
     __rtld_fini = rtld_fini;
 
-#if defined __LDSO_STANDALONE_SUPPORT__ && defined SHARED && defined __sh__
-	/*
-	 * Skip ld.so and its arguments
-	 * Other archs except for SH do this in _dl_start before passing
-	 * control to the application.
-	 * FIXME: align SH _dl_start to other archs and remove this from here,
-	 *        so that we can keep the visibility hidden.
-	 */
-	argc -= _dl_skip_args;
-	argv += _dl_skip_args;
-#endif
-
     /* The environment begins right after argv.  */
     __environ = &argv[argc + 1];