summary refs log tree commit diff
path: root/sysdeps/powerpc/elf/start.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/powerpc/elf/start.c')
-rw-r--r--sysdeps/powerpc/elf/start.c77
1 files changed, 45 insertions, 32 deletions
diff --git a/sysdeps/powerpc/elf/start.c b/sysdeps/powerpc/elf/start.c
index 9b1cf1c026..001d6aa97c 100644
--- a/sysdeps/powerpc/elf/start.c
+++ b/sysdeps/powerpc/elf/start.c
@@ -26,22 +26,27 @@
 /* Just a little assembler stub before gcc gets its hands on our
    stack pointer... */
 asm ("\
-	.text
+	.section \".text\"
+	.align 2
 	.globl _start
 _start:
  # save the stack pointer, in case we're statically linked under Linux
-        mr 8,1
+	mr 8,1
  # set up an initial stack frame, and clear the LR
-        addi 1,1,-16
-        clrrwi 1,1,4
-        li 0,0
-        stw 0,0(1)
-        mtlr 0
+	addi 1,1,-16
+	clrrwi 1,1,4
+	li 0,0
+	stw 0,0(1)
+	mtlr 0
  # set r13 to point at the 'small data area'
-        lis 13,_SDA_BASE_@ha
-        addi 13,13,_SDA_BASE_@l
+	lis 13,_SDA_BASE_@ha
+	addi 13,13,_SDA_BASE_@l
  # and continue below.
-        b __start1
+	b __start1
+0:
+	.size	 _start,0b-_start
+ # undo '.section text'.
+	.previous
 ");
 
 /* Define a symbol for the first piece of initialized data.  */
@@ -53,38 +58,46 @@ weak_alias (__data_start, data_start)
 void (*_mach_init_routine) (void);
 void (*_thread_init_routine) (void);
 
-void __libc_init_first (int argc, char **argv, char **envp);
-int main (int argc, char **argv, char **envp, void *auxvec);
+extern void __libc_init_first (int argc, char **argv, char **envp);
+extern int main (int argc, char **argv, char **envp, void *auxvec);
 #ifdef HAVE_INITFINI
-void _init (void);
-void _fini (void);
+extern void _init (void);
+extern void _fini (void);
 #endif
 
-
+#if 0
+/* I'd like to say this, but it causes GCC to strip the whole procedure
+   from the object file (this is sort of reasonable, because you've told
+   GCC that the procedure is unused). :-( */
 static void __start1(int argc, char **argv, char **envp,
-		     void *auxvec, void (*exitfn) (void), char **arguments)
+		     void *auxvec, void (*exitfn) (void),
+		     char **stack_on_entry)
      __attribute__ ((unused));
-static void
+
+static
+#endif
+void
 __start1(int argc, char **argv, char **envp,
 	 void *auxvec, void (*exitfn) (void),
-	 char **arguments)
+	 char **stack_on_entry)
 {
   /* the PPC SVR4 ABI says that the top thing on the stack will
      be a NULL pointer, so if not we assume that we're being called
-     as a statically-linked program by Linux. */
-  int abi_compliant_startup = *arguments == NULL;
-
-  if (!abi_compliant_startup)
-  {
-    argc = *(int *) arguments;
-    argv = arguments+1;
-    envp = argv+argc+1;
-    auxvec = envp;
-    while (auxvec != NULL)
-      auxvec++;
-    auxvec++;
-    exitfn = NULL;
-  }
+     as a statically-linked program by Linux...	 */
+  if (*stack_on_entry != NULL)
+    {
+      /* ...in which case, we have argc as the top thing on the
+	 stack, followed by argv (NULL-terminated), envp (likewise),
+	 and the auxilary vector.  */
+      argc = *(int *) stack_on_entry;
+      argv = stack_on_entry + 1;
+      envp = argv + argc + 1;
+      auxvec = envp;
+      while (*(char **) auxvec != NULL)
+	++auxvec;
+      ++auxvec;
+      exitfn = NULL;
+    }
 
   if (exitfn != NULL)
     atexit (exitfn);