|
@@ -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")
|
|
|
+}
|