diff options
Diffstat (limited to 'sysdeps/unix/sysv/linux')
-rw-r--r-- | sysdeps/unix/sysv/linux/arm/clone.S | 33 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/arm/socket.S | 49 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/arm/syscall.S | 47 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/arm/sysdep.h | 73 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/if_index.c | 140 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/m68k/syscalls.list | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/net/if.h | 19 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/netinet/in.h | 12 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/clone.S | 42 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/socket.S | 24 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/syscall.S | 12 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/sysdep.h | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/shmdt.c | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/statfsbuf.h | 2 |
14 files changed, 415 insertions, 44 deletions
diff --git a/sysdeps/unix/sysv/linux/arm/clone.S b/sysdeps/unix/sysv/linux/arm/clone.S new file mode 100644 index 0000000000..c7e7aed9c8 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/clone.S @@ -0,0 +1,33 @@ +/* Copyright (C) 1996, 1997 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* clone() is even more special than fork() as it mucks with stacks + and invokes a function in the right context after its all over. */ + +#include <sysdep.h> +#define _ERRNO_H 1 +#include <errnos.h> + +/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */ + + .text +ENTRY(__clone) + /* Somebody needs to write this. */ +PSEUDO_END (__clone) + +weak_alias (__clone, clone) diff --git a/sysdeps/unix/sysv/linux/arm/socket.S b/sysdeps/unix/sysv/linux/arm/socket.S new file mode 100644 index 0000000000..e8db072971 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/socket.S @@ -0,0 +1,49 @@ +/* Copyright (C) 1995, 1996, 1997 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <sysdep.h> +#include <sys/socketcall.h> + +#define P(a, b) P2(a, b) +#define P2(a, b) a##b + + .text +/* The socket-oriented system calls are handled unusally in Linux. + They are all gated through the single `socketcall' system call number. + `socketcall' takes two arguments: the first is the subcode, specifying + which socket function is being called; and the second is a pointer to + the arguments to the specific function. + + The .S files for the other calls just #define socket and #include this. */ + +.globl P(__,socket) +ENTRY (P(__,socket)) + + /* Do the system call trap. */ + swi SYS_ify(socketcall) + + /* %eax is < 0 if there was an error. */ + cmn r0, $124 + bge syscall_error + + /* Successful; return the syscall's value. */ + RETINSTR(mov,pc,r14) + +PSEUDO_END (P(__,socket)) + +weak_alias (P(__,socket), socket) diff --git a/sysdeps/unix/sysv/linux/arm/syscall.S b/sysdeps/unix/sysv/linux/arm/syscall.S new file mode 100644 index 0000000000..7a87278303 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/syscall.S @@ -0,0 +1,47 @@ +/* Copyright (C) 1995, 1996 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <sysdep.h> + +/* Please consult the file sysdeps/unix/sysv/linux/arm/sysdep.h for + more information about the value -4095 used below.*/ + + .text +ENTRY (syscall) + + /* Normally encoding the system call number in the instruction is + good. But we pay the price here. */ + + sub sp, sp, $0xc @ get 3 words on the stack + orr r0, r0, $0xef000000 @ make up a SWI instruction + orr r0, r0, $SWI_BASE + str r0, [sp] + ldr r0, _reti + str r0, [sp, $4] + adr r0, _ret + str r0, [sp, $8] + mov r0, r1 + mov r1, r2 + mov r2, r3 + mov pc, sp +_ret: add sp, sp, $0xc + RETINSTR(mov, pc, r14) + +_reti: .word 0xe51ff004 @ ldr pc, [pc, $4] + +PSEUDO_END (syscall) diff --git a/sysdeps/unix/sysv/linux/arm/sysdep.h b/sysdeps/unix/sysv/linux/arm/sysdep.h new file mode 100644 index 0000000000..6478a5d182 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/sysdep.h @@ -0,0 +1,73 @@ +/* Copyright (C) 1992, 93, 95, 96, 97 Free Software Foundation, Inc. +This file is part of the GNU C Library. +Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>, August 1995. +ARM changes by Philip Blundell, <pjb27@cam.ac.uk>, May 1997. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _LINUX_ARM_SYSDEP_H +#define _LINUX_ARM_SYSDEP_H 1 + +/* There is some commonality. */ +#include <sysdeps/unix/arm/sysdep.h> + +/* For Linux we can use the system call table in the header file + /usr/include/asm/unistd.h + of the kernel. But these symbols do not follow the SYS_* syntax + so we have to redefine the `SYS_ify' macro here. */ +#undef SYS_ify +#define SWI_BASE (9 << 20) +#define SYS_ify(syscall_name) (SWI_BASE + __NR_##syscall_name) + + +#ifdef ASSEMBLER + +/* Linux uses a negative return value to indicate syscall errors, + unlike most Unices, which use the condition codes' carry flag. + + Since version 2.1 the return value of a system call might be + negative even if the call succeeded. E.g., the `lseek' system call + might return a large offset. Therefore we must not anymore test + for < 0, but test for a real error by making sure the value in %eax + 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; \ + ENTRY (name) \ + DO_CALL (args, syscall_name); \ + cmn r0, $4096; \ + bge 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 */ + +#undef DO_CALL +#define DO_CALL(args, syscall_name) \ + swi SYS_ify (syscall_name); + +#endif /* ASSEMBLER */ + +#endif /* linux/arm/sysdep.h */ diff --git a/sysdeps/unix/sysv/linux/if_index.c b/sysdeps/unix/sysv/linux/if_index.c new file mode 100644 index 0000000000..3f5a890a9c --- /dev/null +++ b/sysdeps/unix/sysv/linux/if_index.c @@ -0,0 +1,140 @@ +/* Copyright (C) 1997 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <net/if.h> + +#define IF_INET6_FILENAME "/proc/net/if_inet6" + +/* /proc/net/if_inet6 contains lines that look like this: + * + * fe8000000000000000000000836fc168 0b 00 20 80 sit7 + * + * | | | | | | + * address --' | | | | | + * index --------' | | | | + * prefix length ---' | | | + * scope --------------' | | + * flags -----------------' | + * name -------------------------' + * + */ + +static int get_one_interface(FILE *fd, char *interface, int iflen, unsigned int *index) +{ + char buffer[80]; + static char seps[] = " \012"; + char *c = buffer; + char *sp; + if (!fgets(buffer, 80, fd)) + return 1; + if (strtok_r(buffer, seps, &sp) == NULL) return 1; + if (c = strtok_r(NULL, seps, &sp), c == NULL) return 1; + *index = strtoul(c, NULL, 16); + if (strtok_r(NULL, seps, &sp) == NULL) return 1; + if (strtok_r(NULL, seps, &sp) == NULL) return 1; + if (strtok_r(NULL, seps, &sp) == NULL) return 1; + if (c = strtok_r(NULL, seps, &sp), c == NULL) return 1; + strncpy(interface, c, iflen); + return 0; +} + +unsigned int if_nametoindex(const char *ifname) +{ + FILE *fd = fopen(IF_INET6_FILENAME, "r"); + char this_ifname[IFNAMSIZ]; + unsigned int this_index; + if (!fd) return 0; + while (get_one_interface(fd, this_ifname, IFNAMSIZ, &this_index) == 0) { + if (!strcmp(this_ifname, ifname)) { + fclose(fd); + return this_index; + } + } + fclose(fd); + return 0; +} + +char *if_indextoname(unsigned int ifindex, char *ifname) +{ + FILE *fd = fopen(IF_INET6_FILENAME, "r"); + unsigned int this_index; + if (!fd) return NULL; + while (get_one_interface(fd, ifname, IFNAMSIZ, &this_index) == 0) { + if (this_index == ifindex) { + fclose(fd); + return ifname; + } + } + fclose(fd); + return NULL; +} + +void if_freenameindex(struct if_nameindex *ifn) +{ + struct if_nameindex *ptr = ifn; + while (ptr->if_name || ptr->if_index) + { + if (ptr->if_name) + free(ptr->if_name); + ptr++; + } + free(ifn); +} + +struct if_nameindex *if_nameindex(void) +{ + FILE *fd = fopen(IF_INET6_FILENAME, "r"); + struct if_nameindex *ifn = NULL; + int nifs = 0; + if (!fd) return NULL; + do + { + struct if_nameindex *newifn; + nifs++; + newifn = realloc(ifn, nifs*sizeof(struct if_nameindex)); + if (!newifn) + { + /* We ran out of memory. */ + if (--nifs) + { + free(ifn[nifs-1].if_name); + ifn[nifs-1].if_name = 0; + ifn[nifs-1].if_index = 0; + if_freenameindex(ifn); + } + return NULL; + } + ifn = newifn; + ifn[nifs-1].if_index = 0; + ifn[nifs-1].if_name = malloc(IFNAMSIZ); + if (ifn[nifs-1].if_name == NULL) + { + if_freenameindex(ifn); + return NULL; + } + } + while (get_one_interface(fd, ifn[nifs-1].if_name, IFNAMSIZ, + &ifn[nifs-1].if_index) == 0); + free(ifn[nifs-1].if_name); + ifn[nifs-1].if_name = NULL; + fclose(fd); + return ifn; +} diff --git a/sysdeps/unix/sysv/linux/m68k/syscalls.list b/sysdeps/unix/sysv/linux/m68k/syscalls.list index 9a3e4d0e58..473c2ec5b2 100644 --- a/sysdeps/unix/sysv/linux/m68k/syscalls.list +++ b/sysdeps/unix/sysv/linux/m68k/syscalls.list @@ -1,5 +1,7 @@ # File name Caller Syscall name # args Strong name Weak names +cacheflush EXTRA cacheflush 4 __cacheflush cacheflush + s_getgroups getgroups getgroups 2 __syscall_getgroups s_llseek llseek _llseek 5 __sys_llseek s_setgroups setgroups setgroups 2 __syscall_setgroups diff --git a/sysdeps/unix/sysv/linux/net/if.h b/sysdeps/unix/sysv/linux/net/if.h index db86d20f23..01e9f00943 100644 --- a/sysdeps/unix/sysv/linux/net/if.h +++ b/sysdeps/unix/sysv/linux/net/if.h @@ -144,4 +144,23 @@ struct ifconf #define ifc_buf ifc_ifcu.ifcu_buf /* Buffer address. */ #define ifc_req ifc_ifcu.ifcu_req /* Array of structures. */ + +/* Convert an interface name to an index, and vice versa. */ + +unsigned int if_nametoindex(const char *ifname); +char *if_indextoname(unsigned int ifindex, char *ifname); + +/* Return a list of all interfaces and their indices. */ + +struct if_nameindex { + unsigned int if_index; /* 1, 2, ... */ + char *if_name; /* null terminated name: "eth0", ... */ +}; + +struct if_nameindex *if_nameindex(void); + +/* Free the data returned from if_nameindex. */ + +void if_freenameindex(struct if_nameindex *ptr); + #endif /* net/if.h */ diff --git a/sysdeps/unix/sysv/linux/netinet/in.h b/sysdeps/unix/sysv/linux/netinet/in.h index bbc625435c..451f8f5a20 100644 --- a/sysdeps/unix/sysv/linux/netinet/in.h +++ b/sysdeps/unix/sysv/linux/netinet/in.h @@ -259,7 +259,7 @@ extern u_int16_t htons __P ((u_int16_t __hostshort)); /* IPV6 socket options. */ #define IPV6_ADDRFORM 1 -#define IPV6_RXINFO 2 +#define IPV6_PKTINFO 2 #define IPV6_RXHOPOPTS 3 #define IPV6_RXDSTOPTS 4 #define IPV6_RXSRCRT 5 @@ -267,8 +267,6 @@ extern u_int16_t htons __P ((u_int16_t __hostshort)); #define IPV6_CHECKSUM 7 #define IPV6_HOPLIMIT 8 -#define IPV6_TXINFO IPV6_RXINFO -#define SCM_SRCINFO IPV6_TXINFO #define SCM_SRCRT IPV6_RXSRCRT #define IPV6_UNICAST_HOPS 16 @@ -306,6 +304,14 @@ extern u_int16_t htons __P ((u_int16_t __hostshort)); /* Bind socket to a priviledged IP port. */ extern int bindresvport __P ((int __sockfd, struct sockaddr_in *__sin)); + +/* IPv6 packet information. */ +struct in6_pktinfo + { + struct in6_addr ipi6_addr; /* src/dst IPv6 address */ + int ipi6_ifindex; /* send/recv interface index */ + }; + __END_DECLS #endif /* netinet/in.h */ diff --git a/sysdeps/unix/sysv/linux/powerpc/clone.S b/sysdeps/unix/sysv/linux/powerpc/clone.S index d255abfe0f..068b14c538 100644 --- a/sysdeps/unix/sysv/linux/powerpc/clone.S +++ b/sysdeps/unix/sysv/linux/powerpc/clone.S @@ -29,45 +29,45 @@ ENTRY(__clone) /* Set up stack frame, save registers. */ - stwu 1,-32(1) - stw 31,16(1) - stw 30,20(1) + stwu %r1,-32(%r1) + stw %r31,16(%r1) + stw %r30,20(%r1) /* Check for child_stack == NULL || fn == NULL. */ - cmpwi 0,4,0 - cmpwi 1,3,0 - cror 2+0*4,2+0*4,2+1*4 - beq- 0,badargs + cmpwi %cr0,%r4,0 + beq- %cr0,badargs + cmpwi %cr1,%r3,0 + beq- %cr1,badargs /* Set up stack frame for child. */ - addi 4,4,-16 - clrrwi 4,4,4 - li 0,0 - stw 0,0(4) + addi %r4,%r4,-16 + clrrwi %r4,%r4,4 + li %r0,0 + stw %r0,0(%r4) /* Save new stack, fn, args across syscall. */ - mr 30,3 /* Function in r30. */ - mr 31,6 /* Arguments in r31. */ + mr %r30,%r3 /* Function in r30. */ + mr %r31,%r6 /* Arguments in r31. */ /* 'flags' argument is first parameter to clone syscall. (The other argument is the stack pointer, already in r4.) */ - mr 3,5 + mr %r3,%r5 /* Do the call. */ DO_CALL(SYS_ify(clone)) - bso- error - beq child + bso- error + beq child /* Parent. Restore registers & return. */ - lwz 31,16(1) - lwz 30,20(1) - addi 1,1,32 + lwz %r31,16(%r1) + lwz %r30,20(%r1) + addi %r1,%r1,32 blr child: /* Call procedure. */ - mtlr 30 - mr 3,31 + mtlr %r30 + mr %r3,%r31 blrl /* Call _exit with result from procedure. */ #ifdef PIC diff --git a/sysdeps/unix/sysv/linux/powerpc/socket.S b/sysdeps/unix/sysv/linux/powerpc/socket.S index 12417faac6..305aba9281 100644 --- a/sysdeps/unix/sysv/linux/powerpc/socket.S +++ b/sysdeps/unix/sysv/linux/powerpc/socket.S @@ -43,38 +43,38 @@ .text ENTRY(P(__,socket)) - stwu 1,-48(1) + stwu %r1,-48(%r1) #if NARGS >= 1 - stw 3,stackblock(1) + stw %r3,stackblock(%r1) #endif #if NARGS >= 2 - stw 4,4+stackblock(1) + stw %r4,4+stackblock(%r1) #endif #if NARGS >= 3 - stw 5,8+stackblock(1) + stw %r5,8+stackblock(%r1) #endif #if NARGS >= 4 - stw 6,12+stackblock(1) + stw %r6,12+stackblock(%r1) #endif #if NARGS >= 5 - stw 7,16+stackblock(1) + stw %r7,16+stackblock(%r1) #endif #if NARGS >= 6 - stw 8,20+stackblock(1) + stw %r8,20+stackblock(%r1) #endif #if NARGS >= 7 - stw 9,24+stackblock(1) + stw %r9,24+stackblock(%r1) #endif #if NARGS >= 8 - stw 10,28+stackblock(1) + stw %r10,28+stackblock(%r1) #endif #if NARGS >= 9 #error too many arguments! #endif - li 3,P(SOCKOP_,socket) - addi 4,1,stackblock + li %r3,P(SOCKOP_,socket) + addi %r4,%r1,stackblock DO_CALL(SYS_ify(socketcall)) - addi 1,1,48 + addi %r1,%r1,48 bnslr #ifdef PIC b __syscall_error@plt diff --git a/sysdeps/unix/sysv/linux/powerpc/syscall.S b/sysdeps/unix/sysv/linux/powerpc/syscall.S index 441dd5d433..2cb548245b 100644 --- a/sysdeps/unix/sysv/linux/powerpc/syscall.S +++ b/sysdeps/unix/sysv/linux/powerpc/syscall.S @@ -20,12 +20,12 @@ .text ENTRY (syscall) - mr 0,3 - mr 3,4 - mr 4,5 - mr 5,6 - mr 6,7 - mr 7,8 + mr %r0,%r3 + mr %r3,%r4 + mr %r4,%r5 + mr %r5,%r6 + mr %r6,%r7 + mr %r7,%r8 sc bnslr #ifdef PIC diff --git a/sysdeps/unix/sysv/linux/powerpc/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/sysdep.h index 6cad9ae087..577809acb8 100644 --- a/sysdeps/unix/sysv/linux/powerpc/sysdep.h +++ b/sysdeps/unix/sysv/linux/powerpc/sysdep.h @@ -50,7 +50,7 @@ b __syscall_error@plt #else #define PSEUDO(name, syscall_name, args) \ - .text; \ + .section ".text"; \ ENTRY (name) \ DO_CALL (SYS_ify (syscall_name)); \ bnslr; \ diff --git a/sysdeps/unix/sysv/linux/shmdt.c b/sysdeps/unix/sysv/linux/shmdt.c index dcda701e45..70526e6ae0 100644 --- a/sysdeps/unix/sysv/linux/shmdt.c +++ b/sysdeps/unix/sysv/linux/shmdt.c @@ -26,5 +26,5 @@ int shmdt (shmaddr) const void *shmaddr; { - return __ipc (IPCOP_shmdt, 0, 0, 0, shmaddr); + return __ipc (IPCOP_shmdt, 0, 0, 0, (void *) shmaddr); } diff --git a/sysdeps/unix/sysv/linux/statfsbuf.h b/sysdeps/unix/sysv/linux/statfsbuf.h index 1d1bbdae0d..7e1aa55334 100644 --- a/sysdeps/unix/sysv/linux/statfsbuf.h +++ b/sysdeps/unix/sysv/linux/statfsbuf.h @@ -19,6 +19,8 @@ #ifndef _STATFSBUF_H #define _STATFSBUF_H +#include <gnu/types.h> /* for __fsid_t */ + struct statfs { int f_type; |