فهرست منبع

Based on start.S from debian's glibc, this gets arm working
properly with the new ABI

Eric Andersen 19 سال پیش
والد
کامیت
299d67551e
1فایلهای تغییر یافته به همراه69 افزوده شده و 138 حذف شده
  1. 69 138
      libc/sysdeps/linux/arm/crt1.S

+ 69 - 138
libc/sysdeps/linux/arm/crt1.S

@@ -1,148 +1,80 @@
-/* When we enter this piece of code, the program stack looks like this:
-        argc            argument counter (integer)
-        argv[0]         program name (pointer)
-        argv[1...N]     program args (pointers)
-        argv[argc-1]    end of args (integer)
-	NULL
-        env[0...N]      environment variables (pointers)
-        NULL
-
-   For uClinux it looks like this:
-
-        argc            argument counter (integer)
-        argv            char *argv[]
-        envp            char *envp[]
-        argv[0]         program name (pointer)
-        argv[1...N]     program args (pointers)
-        argv[argc-1]    end of args (integer)
-	NULL
-        env[0...N]      environment variables (pointers)
-        NULL
-
-   When we are done here, we want
-	a1=argc
-	a2=argv[0]
-	a3=argv[argc+1]
-
-ARM register quick reference:
-
-    Name    Number       ARM Procedure Calling Standard Role
-
-    a1      r0           argument 1 / integer result / scratch register / argc
-    a2      r1           argument 2 / scratch register / argv
-    a3      r2           argument 3 / scratch register / envp
-    a4      r3           argument 4 / scratch register
-    v1      r4           register variable
-    v2      r5           register variable
-    v3      r6           register variable
-    v4      r7           register variable
-    v5      r8           register variable
-    sb/v6   r9           static base / register variable
-    sl/v7   r10          stack limit / stack chunk handle / reg. variable
-    fp      r11          frame pointer
-    ip      r12          scratch register / new-sb in inter-link-unit calls
-    sp      r13          lower end of current stack frame
-    lr      r14          link address / scratch register
-    pc      r15          program counter
+/* Startup code for ARM & ELF
+   Copyright (C) 1995, 1996, 1997, 1998, 2001, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* This is the canonical entry point, usually the first thing in the text
+   segment.
+
+	Note that the code in the .init section has already been run.
+	This includes _init and _libc_init
+
+
+	At this entry point, most registers' values are unspecified, except:
+
+   a1		Contains a function pointer to be registered with `atexit'.
+		This is how the dynamic linker arranges to have DT_FINI
+		functions called for shared libraries that have been loaded
+		before this code runs.
+
+   sp		The stack contains the arguments and environment:
+		0(sp)			argc
+		4(sp)			argv[0]
+		...
+		(4*argc)(sp)		NULL
+		(4*(argc+1))(sp)	envp[0]
+		...
+					NULL
 */
 
-#include <features.h>
+	.text
+	.globl _start
+	.type _start,#function
+_start:
+	/* Fetch address of fini */
+	ldr ip, =_fini
 
-.text
-	.global	    _start
-	.type	    _start,%function
-	.type	    _init,%function
-	.type	    _fini,%function
-	.type	    main,%function
-	.type	    __uClibc_main,%function
+	/* Clear the frame pointer since this is the outermost frame.  */
+	mov fp, #0
 
+	/* Pop argc off the stack and save a pointer to argv */
+	ldr a2, [sp], #4
+	mov a3, sp
 
-.text
-_start:
-	/* Save a copy of rtld_fini before r0 gets nuked */
-	mov     r5, r0
-
-	/* clear the frame pointer */
-	mov     fp, #0
-
-
-	/* Load register r0 with main */
-#ifdef __PIC__
-	adr r8, .L_main
-	ldr r0, .L_main
-	add r0, r0, r8
-#else
-	ldr r0, =main
-#endif
-
-
-#ifdef __ARCH_HAS_MMU__
-
-	/* Load register r1 from the stack to its final resting place */
-	ldr     r1, [sp], #4
-
-	/* Copy argv pointer into r2 -- which its final resting place */
-	mov     r2, sp
-#else
-	/*
-	 * uClinux stacks look a little different from normal
-	 * MMU-full Linux stacks (for no good reason)
-	 */
-	/* pull argc and argv off the stack */
-	ldr r1,[sp, #0]
-	ldr r2,[sp, #4]
-#endif
-
-	/* Store _init and _fini to r3 and r4 */
-#ifdef __PIC__
-	adr r8, .L_init
-	ldr r3, .L_init
-	add r3, r3, r8
-
-	ldr r4, .L_init + 4
-	add r4, r4, r8
-#else
-	ldr r3, =_init
-	ldr r4, =_fini
-#endif
-
-	/* Store _fini(r4), rtld_fini(r5), and stack_end(r2) on the stack */
-	str r2, [sp, #-4]!
-	str r5, [sp, #-4]!
-	str r4, [sp, #-4]!
-
-
-	/* We need to call __uClibc_main which should not return.
-	   __uClibc_main (int (*main) (int, char **, char **), int argc,
-			      char **argv, void (*init) (void), void (*fini) (void),
-			      void (*rtld_fini) (void), void *stack_end)
-	*/
-	bl __uClibc_main
+	/* Push stack limit */
+	str a3, [sp, #-4]!
 
-	/* Crash if somehow `exit' returns anyways.  */
-	bl abort
+	/* Push rtld_fini */
+	str a1, [sp, #-4]!
 
-#ifdef __PIC__
-.L_init:
-	.word _init
-	.word _fini
-.L_main:
-	.word main
-#endif
+	/* Set up the other arguments in registers */
+	ldr a1, =main
+	ldr a4, =_init
 
-/* We need this stuff to make gdb behave itself, otherwise
-   gdb will choke with SIGILL when trying to debug apps.
-*/
-	.section ".note.ABI-tag", "a"
-	.align 4
-	.long 1f - 0f
-	.long 3f - 2f
-	.long  1
-0:	.asciz "GNU"
-1:	.align 4
-2:	.long 0
-	.long 2,0,0
-3:	.align 4
+	/* Push fini */
+	str ip, [sp, #-4]!
+
+	/* __uClibc_main (main, argc, argv, init, fini, rtld_fini, stack_end) */
+
+	/* Let the libc call main and exit with its return code.  */
+	bl __uClibc_main
+
+	/* should never get here....*/
+	bl abort
 
 /* Define a symbol for the first piece of initialized data.  */
 	.data
@@ -151,4 +83,3 @@ __data_start:
 	.long 0
 	.weak data_start
 	data_start = __data_start
-