Browse Source

Based in part on related code in glibc, this might even be correct.

Eric Andersen 19 years ago
parent
commit
099530b70a
1 changed files with 42 additions and 9 deletions
  1. 42 9
      ldso/ldso/arm/dl-startup.h

+ 42 - 9
ldso/ldso/arm/dl-startup.h

@@ -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.  */