diff options
Diffstat (limited to 'sysdeps/unix')
-rw-r--r-- | sysdeps/unix/sysv/linux/arm/socket.S | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/arm/sysdep.h | 50 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/netash/ash.h | 20 |
3 files changed, 57 insertions, 15 deletions
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 */ |