Browse Source

rtld: Add startup code

Implement _start: compute parameters for __self_reloc, and give
control to the user program.

	* ldso/ldso/arm/dl-startup.h: Implement _start for __FDPIC__.

Signed-off-by: Mickaël Guêné <mickael.guene@st.com>
Signed-off-by: Christophe Lyon <christophe.lyon@st.com>
Christophe Lyon 5 years ago
parent
commit
75bce1a732
1 changed files with 66 additions and 1 deletions
  1. 66 1
      ldso/ldso/arm/dl-startup.h

+ 66 - 1
ldso/ldso/arm/dl-startup.h

@@ -8,6 +8,71 @@
 #include <features.h>
 #include <bits/arm_bx.h>
 
+#if defined(__FDPIC__)
+#if !defined(__thumb__) || defined(__thumb2__)
+__asm__(
+	"	.arm\n"
+	"	.text\n"
+	"	.globl  _start\n"
+	"	.type   _start,%function\n"
+	"_start:\n"
+	/* We compute the parameters for __self_reloc:
+	   - r0 is a pointer to the loadmap (either from r8 or r7 if rtld is
+	   lauched in standalone mode)
+	   - r1 is a pointer to the start of .rofixup section
+	   - r2 is a pointer to the last word of .rofixup section
+
+	   __self_reloc will fix indirect addresses in .rofixup
+	   section and will return the relocated GOT value.
+	*/
+	"	sub	r4, pc, #8\n"
+	"	ldr	r1, .L__ROFIXUP_LIST__\n"
+	"	add	r1, r1, r4\n"
+	"	ldr	r2, .L__ROFIXUP_END__\n"
+	"	add	r2, r2, r4\n"
+	"	movs	r0, r8\n"
+	"	moveq	r0, r7\n"
+	"	push	{r7, r8, r9, r10}\n"
+	"	bl	__self_reloc;\n"
+	"	pop	{r7, r8, r9, r10}\n"
+	/* We compute the parameters for dl_start(). See DL_START()
+	   macro below.  The address of the user entry point is
+	   returned in dl_main_funcdesc (on stack).  */
+	"	mov	r1, r7\n"
+	"	mov	r2, r8\n"
+	"	mov	r3, r9\n"
+	"	mov	r4, sp\n"
+	"	sub	r5, sp, #8\n"
+	"	sub sp, sp, #16\n"
+	"	str	r4, [sp, #4]\n"
+	"	str	r5, [sp, #0]\n"
+	"	mov	r9, r0\n"
+	/* Save r9 into r4, to preserve the GOT pointer.  */
+	"	mov	r4, r9\n"
+	"	bl _dl_start;\n"
+	/* Now compute parameters for entry point according to FDPIC ABI.  */
+	"	ldr	r10, .L_dl_fini_gotofffuncdesc\n"
+	/* Save GOT value from r4.  */
+	"	add	r10, r10, r4\n"
+	"	ldr	r5, [sp, #8]\n"
+	"	ldr	r9, [sp, #12]\n"
+	"	add sp, sp, #16\n"
+	"	bx	r5\n"
+	".loopforever:\n"
+	"	b	.loopforever\n"
+	".L__ROFIXUP_LIST__:\n"
+	"	.word	__ROFIXUP_LIST__ - _start\n"
+	".L__ROFIXUP_END__:\n"
+	"	.word	__ROFIXUP_END__ - _start\n"
+	".L_dl_fini_gotofffuncdesc:\n"
+	"	.word	_dl_fini(GOTOFFFUNCDESC)\n"
+	"	.size	_start,.-_start\n"
+	"	.previous\n"
+);
+#else /* !defined(__thumb__) */
+#error Thumb-1 is not supported
+#endif /* !defined(__thumb__) */
+#else /* defined(__FDPIC__) */
 #if !defined(__thumb__)
 __asm__(
     "	.text\n"
@@ -121,7 +186,7 @@ __asm__(
 	".previous\n"
 );
 #endif
-
+#endif /* defined(__FDPIC__) */
 
 /* Get a pointer to the argv array.  On many platforms this can be just
  * the address of the first argument, on other platforms we need to