about summary refs log tree commit diff
path: root/sysdeps
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1998-04-01 09:15:07 +0000
committerUlrich Drepper <drepper@redhat.com>1998-04-01 09:15:07 +0000
commit652e8a1e1beaaab450f56e5cef67a0c15164a88b (patch)
treeedb1ea55cdddaaf2885d573aeaa725e0d2b703fb /sysdeps
parent1d97d6ac3bf8fa241535793b31acd685ee32d6c2 (diff)
downloadglibc-652e8a1e1beaaab450f56e5cef67a0c15164a88b.tar.gz
glibc-652e8a1e1beaaab450f56e5cef67a0c15164a88b.tar.xz
glibc-652e8a1e1beaaab450f56e5cef67a0c15164a88b.zip
Update.
1998-04-1 16:52  Philip Blundell  <pb@nexus.co.uk>

	* sysdeps/unix/sysv/linux/arm/socket.S: Correct test for error and
	use PLTJMP() rather than explicit (PLT).

	* sysdeps/arm/elf/start.S: Leave most of the initialisation for
	__libc_start_main().

	Based on patch from Pat Beirne:
	* sysdeps/unix/sysv/linux/arm/sysdep.h (SYSCALL_ERROR_HANDLER):
	Always define, not only #ifndef PIC.
	(DO_CALL): Pass fifth argument correctly in R4.
	(PSEUDO): Correct test for error, call syscall_error through PLT
	if PIC.

1998-03-31 10:51  Philip Blundell  <pb@nexus.co.uk>

	* sysdeps/unix/sysv/linux/netash/ash.h: Fix typos and add new
	definitions.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/arm/elf/start.S81
-rw-r--r--sysdeps/unix/sysv/linux/arm/socket.S2
-rw-r--r--sysdeps/unix/sysv/linux/arm/sysdep.h50
-rw-r--r--sysdeps/unix/sysv/linux/netash/ash.h20
4 files changed, 81 insertions, 72 deletions
diff --git a/sysdeps/arm/elf/start.S b/sysdeps/arm/elf/start.S
index e0964a1e38..13b9c780ef 100644
--- a/sysdeps/arm/elf/start.S
+++ b/sysdeps/arm/elf/start.S
@@ -24,19 +24,19 @@
 	This includes _init and _libc_init
 
 
-	At this entry point, most registers' values are unspecified, except for:
+	At this entry point, most registers' values are unspecified, except:
 
-   r0		Contains a function pointer to be registered with `atexit'.
+   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(%esp)			argc
-		4(%esp)			argv[0]
+   		0(sp)			argc
+		4(sp)			argv[0]
 		...
-		(4*argc)(%esp)		NULL
-		(4*(argc+1))(%esp)	envp[0]
+		(4*argc)(sp)		NULL
+		(4*(argc+1))(sp)	envp[0]
 		...
 					NULL
 */
@@ -44,62 +44,29 @@
 	.text
 	.globl _start
 _start:
-	/* Clear the frame pointer.  The Intel ABI suggests this be done,
-		to mark the outermost frame obviously. This seems like a
-		sensible thing to do  */
+	/* Clear the frame pointer since this is the outermost frame.  */
 	mov fp, #0
 
-	/* r0 contains the address of the shared library termination
-	   function, which we will register with `atexit' to be called by
-	   `exit'.  I suspect that on some systems, and when statically
-	   linked, this will not be set by anything to any function
-	   pointer; hopefully it will be zero so we don't try to call
-	   random pointers.  */
-	cmp r0,#0
-	blne atexit(PLT)
-
-	/* Do essential libc initialization.  In statically linked
-	   programs under the GNU Hurd, this is what sets up the
-	   arguments on the stack for the code below. For dyn-link
-	   programs, this has been run already, in the .init code. */
-#ifndef PIC
-	bl __libc_init_first
-
-	/* Extract the arguments and environment as encoded on the stack
-	   and set up the arguments for `main': argc, argv, envp.  */
-	ldr r0,[sp]
-	add r1,sp,#4
-	add r2,r1,r0,lsl #2
-	add r2,r2,#4
-	/* save a copy of envp while we have it */
-	ldr r3,L_environ
-	str r2,[r3]
-
-	/* Call `_init', which is the entry point to our own `.init'
-	   section; and register with `atexit' to have `exit' call
-	   `_fini', which is the entry point to our own `.fini' section.  */
-	bl _init
-	ldr r0,L_fini
-	bl atexit
-	b L_pfini
-
-L_fini:	.word _fini
-L_environ: .word _environ
-L_pfini:
-#endif
-	/* rebuild the arg list for main() */
-	ldr r0,[sp]
-	add r1,sp,#4
-	add r2,r1,r0,lsl #2
-	add r2,r2,#4
-
-	/* Call the user's main function, and exit with its value.  */
-	bl main
-	bl exit
+	/* Pop argc off the stack and save a pointer to argv */
+	ldmfd sp!, {a2}
+	mov a3, sp
+
+	/* Push the last arguments to main() onto the stack */
+	stmfd sp!, {a1}
+	ldr a1, =_fini
+	stmfd sp!, {a1}
+
+	/* Set up the other arguments for main() that go in registers */
+	ldr a1, =main
+	ldr a4, =_init
+
+	/* __libc_start_main (main, argc, argv, init, fini, rtld_fini) */
+
+	/* Let the libc call main and exit with its return code.  */
+	bl __libc_start_main
 	/* should never get here....*/
 	bl abort
 
-
 /* Define a symbol for the first piece of initialized data.  */
 	.data
 	.globl __data_start
diff --git a/sysdeps/unix/sysv/linux/arm/socket.S b/sysdeps/unix/sysv/linux/arm/socket.S
index 0ff6dd0164..1ebec9ca26 100644
--- a/sysdeps/unix/sysv/linux/arm/socket.S
+++ b/sysdeps/unix/sysv/linux/arm/socket.S
@@ -43,7 +43,7 @@ ENTRY (__socket)
 
 	/* r0 is < 0 if there was an error.  */
 	cmn r0, $124
-	bge syscall_error(PLT)
+	bhs PLTJMP(syscall_error)
 
 	/* Successful; return the syscall's value.  */
 	RETINSTR(mov,pc,r14)
diff --git a/sysdeps/unix/sysv/linux/arm/sysdep.h b/sysdeps/unix/sysv/linux/arm/sysdep.h
index 3b7ffe08d9..dd1b6f4115 100644
--- a/sysdeps/unix/sysv/linux/arm/sysdep.h
+++ b/sysdeps/unix/sysv/linux/arm/sysdep.h
@@ -45,28 +45,64 @@
    is a real error number.  Linus said he will make sure the no syscall
    returns a value in -1 .. -4095 as a valid result so we can savely
    test with -4095.  */
+
 #undef	PSEUDO
 #define	PSEUDO(name, syscall_name, args)				      \
   .text;								      \
+  .type syscall_error,%function						      \
   ENTRY (name)								      \
     DO_CALL (args, syscall_name);					      \
     cmn r0, $4096;							      \
-    bgt syscall_error;
+    bhs PLTJMP(syscall_error);
 
 #undef	PSEUDO_END
 #define	PSEUDO_END(name)						      \
   SYSCALL_ERROR_HANDLER							      \
   END (name)
 
-#ifndef PIC
 #define SYSCALL_ERROR_HANDLER	/* Nothing here; code in sysdep.S is used.  */
-#else
-#error Aiee
-#endif	/* PIC */
+
+/* Linux takes system call args in registers:
+	syscall number	in the SWI instruction
+	arg 1		r0
+	arg 2		r1
+	arg 3		r2
+	arg 4		r3
+	arg 5		r4	(this is different from the APCS convention)
+
+   The compiler is going to form a call by coming here, through PSEUDO, with
+   arguments
+   	syscall number	in the DO_CALL macro
+   	arg 1		r0
+   	arg 2		r1
+   	arg 3		r2
+   	arg 4		r3
+   	arg 5		[sp]
+
+   We need to shuffle values between R4 and the stack so that the caller's
+   R4 is not corrupted, and the kernel sees the right argument there.
+
+*/
 
 #undef	DO_CALL
-#define DO_CALL(args, syscall_name)			      		      \
-    swi SYS_ify (syscall_name);
+#define DO_CALL(args, syscall_name)		\
+    DOARGS_##args				\
+    swi SYS_ify (syscall_name); 		\
+    UNDOARGS_##args
+
+#define DOARGS_0 /* nothing */
+#define DOARGS_1 /* nothing */
+#define DOARGS_2 /* nothing */
+#define DOARGS_3 /* nothing */
+#define DOARGS_4 /* nothing */
+#define DOARGS_5 ldr ip, [sp]; str r4, [sp]; mov r4, ip;
+
+#define UNDOARGS_0 /* nothing */
+#define UNDOARGS_1 /* nothing */
+#define UNDOARGS_2 /* nothing */
+#define UNDOARGS_3 /* nothing */
+#define UNDOARGS_4 /* nothing */
+#define UNDOARGS_5 ldr r4, [sp];
 
 #endif	/* ASSEMBLER */
 
diff --git a/sysdeps/unix/sysv/linux/netash/ash.h b/sysdeps/unix/sysv/linux/netash/ash.h
index e4feec44ab..52bd398149 100644
--- a/sysdeps/unix/sysv/linux/netash/ash.h
+++ b/sysdeps/unix/sysv/linux/netash/ash.h
@@ -17,18 +17,24 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-#ifndef __NETASH_ASH_H
-#define __NETASH_ASH_H	1
+#ifndef _NETASH_ASH_H
+#define _NETASH_ASH_H	1
 
 #include <features.h>
-#include <sys/socket.h>
-#include <sys/types.h>
+#include <bits/sockaddr.h>
 
 struct sockaddr_ash
   {
-    _SOCKADDR_COMMON (sash_);		/* Common data: address family etc.  */
-    int if_index;			/* Interface to use.  */
-    int channel;			/* Realtime or control.  */
+    __SOCKADDR_COMMON (sash_);		/* Common data: address family etc.  */
+    int sash_ifindex;			/* Interface to use.  */
+    unsigned char sash_channel;		/* Realtime or control.  */
+    unsigned int sash_plen;
+    unsigned char sash_prefix[16];
   };
 
+/* Values for `channel' member.  */
+#define ASH_CHANNEL_ANY		0
+#define ASH_CHANNEL_CONTROL	1
+#define ASH_CHANNEL_REALTIME	2
+
 #endif	/* netash/ash.h */