summaryrefslogtreecommitdiff
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)
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 */