OSDN Git Service

first pass at updating sparc ldso with code from glibc
authorMike Frysinger <vapier@gentoo.org>
Thu, 19 Jan 2006 10:31:33 +0000 (10:31 -0000)
committerMike Frysinger <vapier@gentoo.org>
Thu, 19 Jan 2006 10:31:33 +0000 (10:31 -0000)
ldso/ldso/sparc/dl-startup.h

index 73db327..7da9722 100644 (file)
@@ -3,15 +3,46 @@
  * needed for this architecture.  See arm/boot1_arch.h for an example of what
  * can be done.
  */
-asm(
-       "       .text\n"
-       "       .global _start\n"
-       "       .type   _start,%function\n"
-       "_start:\n"
-       "       .set _start,_dl_start\n"
-       "       .size _start,.-_start\n"
-       "       .previous\n"
-);
+
+asm ("\
+       .text\n\
+       .global _start\n\
+       .type   _start,%function\n\
+       .align 32\n\
+_start:\n\
+       /* Allocate space for functions to drop their arguments. */\n\
+       sub     %sp, 6*4, %sp\n\
+       /* Pass pointer to argument block to _dl_start. */\n\
+       call _dl_start\n\
+       add    %sp, 22*4, %o0\n\
+       /* FALTHRU */\n\
+       .globl  _dl_start_user\n\
+       .type   _dl_start_user, @function\n\
+_dl_start_user:\n\
+  /* Load the PIC register.  */\n\
+1:     call    2f\n\
+       sethi  %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7\n\
+2:     or  %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7\n\
+       add %l7, %o7, %l7\n\
+  /* Save the user entry point address in %l0 */\n\
+       mov %o0, %l0\n\
+  /* See if we were run as a command with the executable file name as an\n\
+        extra leading argument.  If so, adjust the contents of the stack.  */\n\
+       sethi   %hi(_dl_skip_args), %g2\n\
+       or  %g2, %lo(_dl_skip_args), %g2\n\
+       ld  [%l7+%g2], %i0\n\
+       ld  [%i0], %i0\n\
+       tst %i0\n\
+  /* Pass our finalizer function to the user in %g1.  */\n\
+       sethi   %hi(_dl_fini), %g1\n\
+       or      %g1, %lo(_dl_fini), %g1\n\
+       ld      [%l7+%g1], %g1\n\
+  /* Jump to the user's entry point and deallocate the extra stack we got.  */\n\
+       jmp %l0\n\
+        add    %sp, 6*4, %sp\n\
+       .size   _dl_start_user, . - _dl_start_user\n\
+       .previous\n\
+");
 
 /*
  * Get a pointer to the argv array.  On many platforms this can be just
@@ -19,17 +50,15 @@ asm(
  * do something a little more subtle here.  We assume that argc is stored
  * at the word just below the argvp that we return here.
  */
-#define GET_ARGV(ARGVP, ARGS) __asm__("\tadd %%fp,68,%0\n" : "=r" (ARGVP));
+#define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long *) ARGS) + 1)
 
 /*
  * Here is a macro to perform a relocation.  This is only used when
  * bootstrapping the dynamic loader.
  */
 #define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \
-       switch(ELF32_R_TYPE((RELP)->r_info)) { \
+switch(ELF_R_TYPE((RELP)->r_info)) { \
        case R_SPARC_32: \
-               *REL = SYMBOL + (RELP)->r_addend; \
-               break; \
        case R_SPARC_GLOB_DAT: \
                *REL = SYMBOL + (RELP)->r_addend; \
                break; \
@@ -38,7 +67,6 @@ asm(
                REL[2] = 0x81c06000 | (SYMBOL & 0x3ff); \
                break; \
        case R_SPARC_NONE: \
-               break; \
        case R_SPARC_WDISP30: \
                break; \
        case R_SPARC_RELATIVE: \
@@ -46,18 +74,4 @@ asm(
                break; \
        default: \
                _dl_exit(1); \
-       }
-
-/*
- * Transfer control to the user's application, once the dynamic loader
- * is done.  The crt calls atexit with $g1 if not null, so we need to
- * ensure that it contains NULL.
- */
-
-#define START() \
-       __asm__ volatile ( \
-               "add %%g0,%%g0,%%g1\n\t" \
-               "jmpl %0, %%o7\n\t"     \
-               "restore %%g0,%%g0,%%g0\n\t" \
-               : /*"=r" (status) */ : \
-               "r" (_dl_elf_main): "g1", "o0", "o1")
+}