OSDN Git Service

Based in part on related code in glibc, this might even be correct.
authorEric Andersen <andersen@codepoet.org>
Fri, 10 Jun 2005 20:06:11 +0000 (20:06 -0000)
committerEric Andersen <andersen@codepoet.org>
Fri, 10 Jun 2005 20:06:11 +0000 (20:06 -0000)
ldso/ldso/arm/dl-startup.h

index cd4a104..b7ab57b 100644 (file)
@@ -8,18 +8,51 @@ asm(
     "  .text\n"
     "  .globl  _start\n"
     "  .type   _start,%function\n"
-    "_start:\n"
-    "  mov     r7, sp\n"
-    "  @ldr    r0, [sp], #4\n"
-    "  mov     r0, sp\n"
-    "  bl      _dl_start\n"
-    "  mov     r6, r0\n"
-    "  mov     r0, r7\n"
-    "  mov     pc, r6\n"
+       "_start:\n"
+       "       @ at start time, all the args are on the stack\n"
+       "       mov     r0, sp\n"
+       "       bl      _dl_start\n"
+       "       @ returns user entry point in r0\n"
+       "       mov     r6, r0\n"
+       "       @ we are PIC code, so get global offset table\n"
+       "       ldr     sl, .L_GET_GOT\n"
+       "       add     sl, pc, sl\n"
+       ".L_GOT_GOT:\n"
+       "       @ See if we were run as a command with the executable file\n"
+       "       @ name as an extra leading argument.\n"
+       "       ldr     r4, .L_SKIP_ARGS\n"
+       "       ldr     r4, [sl, r4]\n"
+       "       @ get the original arg count\n"
+       "       ldr     r1, [sp]\n"
+       "       @ subtract _dl_skip_args from it\n"
+       "       sub     r1, r1, r4\n"
+       "       @ adjust the stack pointer to skip them\n"
+       "       add     sp, sp, r4, lsl #2\n"
+       "       @ get the argv address\n"
+       "       add     r2, sp, #4\n"
+       "       @ store the new argc in the new stack location\n"
+       "       str     r1, [sp]\n"
+       "       @ compute envp\n"
+       "       add     r3, r2, r1, lsl #2\n"
+       "       add     r3, r3, #4\n"
+       "\n\n"
+       "       @ load the finalizer function\n"
+       "       ldr     r0, .L_FINI_PROC\n"
+       "       ldr     r0, [sl, r0]\n"
+       "       @ jump to the user_s entry point\n"
+       "       mov     pc, r6\n"
+       ".L_GET_GOT:\n"
+       "       .word   _GLOBAL_OFFSET_TABLE_ - .L_GOT_GOT - 4\n"
+       ".L_SKIP_ARGS:\n"
+       "       .word   _dl_skip_args(GOTOFF)\n"
+       ".L_FINI_PROC:\n"
+       "       .word   _dl_fini(GOT)\n"
+       "\n\n"
     "  .size   _start,.-_start\n"
-    "  .previous\n"
+       ".previous\n"
 );
 
+
 /* Get a pointer to the argv array.  On many platforms this can be just
  * the address if the first argument, on other platforms we need to
  * do something a little more subtle here.  */