[uClibc-cvs] svn commit: trunk/uClibc/libc/sysdeps/linux/arm

andersen at uclibc.org andersen at uclibc.org
Fri Jun 10 23:22:23 UTC 2005


Author: andersen
Date: 2005-06-10 17:22:23 -0600 (Fri, 10 Jun 2005)
New Revision: 10506

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


Modified:
   trunk/uClibc/libc/sysdeps/linux/arm/crt1.S


Changeset:
Modified: trunk/uClibc/libc/sysdeps/linux/arm/crt1.S
===================================================================
--- trunk/uClibc/libc/sysdeps/linux/arm/crt1.S	2005-06-10 21:03:18 UTC (rev 10505)
+++ trunk/uClibc/libc/sysdeps/linux/arm/crt1.S	2005-06-10 23:22:23 UTC (rev 10506)
@@ -1,149 +1,81 @@
-/* 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
+/* 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.
 
-   For uClinux it looks like this:
+   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.
 
-        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
+   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.
 
-   When we are done here, we want
-	a1=argc
-	a2=argv[0]
-	a3=argv[argc+1]
+   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.  */
 
-ARM register quick reference:
+/* This is the canonical entry point, usually the first thing in the text
+   segment.
 
-    Name    Number       ARM Procedure Calling Standard Role
+	Note that the code in the .init section has already been run.
+	This includes _init and _libc_init
 
-    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
-*/
 
-#include <features.h>
+	At this entry point, most registers' values are unspecified, except:
 
-.text
-	.global	    _start
-	.type	    _start,%function
-	.type	    _init,%function
-	.type	    _fini,%function
-	.type	    main,%function
-	.type	    __uClibc_main,%function
+   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
+*/
 
-.text
+	.text
+	.globl _start
+	.type _start,#function
 _start:
-	/* Save a copy of rtld_fini before r0 gets nuked */
-	mov     r5, r0
+	/* Fetch address of fini */
+	ldr ip, =_fini
 
-	/* clear the frame pointer */
-	mov     fp, #0
+	/* 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
 
-	/* Load register r0 with main */
-#ifdef __PIC__
-	adr r8, .L_main
-	ldr r0, .L_main
-	add r0, r0, r8
-#else
-	ldr r0, =main
-#endif
+	/* Push stack limit */
+	str a3, [sp, #-4]!
 
+	/* Push rtld_fini */
+	str a1, [sp, #-4]!
 
-#ifdef __ARCH_HAS_MMU__
+	/* Set up the other arguments in registers */
+	ldr a1, =main
+	ldr a4, =_init
 
-	/* Load register r1 from the stack to its final resting place */
-	ldr     r1, [sp], #4
+	/* Push fini */
+	str ip, [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
+	/* __uClibc_main (main, argc, argv, init, fini, rtld_fini, stack_end) */
 
-	/* 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)
-	*/
+	/* Let the libc call main and exit with its return code.  */
 	bl __uClibc_main
 
-	/* Crash if somehow `exit' returns anyways.  */
+	/* should never get here....*/
 	bl abort
 
-#ifdef __PIC__
-.L_init:
-	.word _init
-	.word _fini
-.L_main:
-	.word main
-#endif
-
-/* 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
-
 /* Define a symbol for the first piece of initialized data.  */
 	.data
 	.globl __data_start
@@ -151,4 +83,3 @@
 	.long 0
 	.weak data_start
 	data_start = __data_start
-




More information about the uClibc-cvs mailing list