2.9
[glibc/nacl-glibc.git] / sysdeps / unix / sysv / linux / sh / socket.S
blobc83b0f26017a4a8335ad0d3791f5d1ee7a172138
1 /* Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, write to the Free
16    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17    02111-1307 USA.  */
19 #include <sysdep-cancel.h>
20 #include <socketcall.h>
21 #include <tls.h>
23 #define P(a, b) P2(a, b)
24 #define P2(a, b) a##b
26         .text
27 /* The socket-oriented system calls are handled unusally in Linux.
28    They are all gated through the single `socketcall' system call number.
29    `socketcall' takes two arguments: the first is the subcode, specifying
30    which socket function is being called; and the second is a pointer to
31    the arguments to the specific function.
33    The .S files for the other calls just #define socket and #include this.  */
35 #ifndef __socket
36 #ifndef NO_WEAK_ALIAS
37 #define __socket P(__,socket)
38 #else
39 #define __socket socket
40 #endif
41 #endif
43 #define PUSHARGS_1      mov.l r4,@-r15; \
44                         cfi_adjust_cfa_offset (4); \
45                         cfi_rel_offset (r4, 0)
46 #define PUSHARGS_2      mov.l r5,@-r15; \
47                         cfi_adjust_cfa_offset (4); \
48                         cfi_rel_offset (r5, 0); \
49                         PUSHARGS_1
50 #define PUSHARGS_3      mov.l r6,@-r15; \
51                         cfi_adjust_cfa_offset (4); \
52                         cfi_rel_offset (r6, 0); \
53                         PUSHARGS_2
54 #define PUSHARGS_4      mov.l r7,@-r15; \
55                         cfi_adjust_cfa_offset (4); \
56                         cfi_rel_offset (r7, 0); \
57                         PUSHARGS_3
58 #define PUSHARGS_5      PUSHARGS_4      /* Caller has already pushed arg 5 */
59 #define PUSHARGS_6      PUSHARGS_4      /* Caller has already pushed arg 5,6 */
61 #define POPARGS_1       add #4,r15; cfi_adjust_cfa_offset (-4)
62 #define POPARGS_2       add #8,r15; cfi_adjust_cfa_offset (-8)
63 #define POPARGS_3       add #12,r15; cfi_adjust_cfa_offset (-12)
64 #define POPARGS_4       add #16,r15; cfi_adjust_cfa_offset (-16)
65 #define POPARGS_5       POPARGS_4
66 #define POPARGS_6       POPARGS_4
68 #define ADJUSTCFI_1     cfi_adjust_cfa_offset (4); \
69                         cfi_offset (r4, -4)
70 #define ADJUSTCFI_2     cfi_adjust_cfa_offset (8); \
71                         cfi_offset (r4, -4); \
72                         cfi_offset (r5, -8)
73 #define ADJUSTCFI_3     cfi_adjust_cfa_offset (12); \
74                         cfi_offset (r4, -4); \
75                         cfi_offset (r5, -8); \
76                         cfi_offset (r6, -12)
77 #define ADJUSTCFI_4     cfi_adjust_cfa_offset (16); \
78                         cfi_offset (r4, -4); \
79                         cfi_offset (r5, -8); \
80                         cfi_offset (r6, -12); \
81                         cfi_offset (r7, -16)
82 #define ADJUSTCFI_5     ADJUSTCFI_4
83 #define ADJUSTCFI_6     ADJUSTCFI_4
85 #ifndef NARGS
86 /* If we were called with no wrapper, this is really socket().  */
87 #define NARGS 3
88 #endif
90 .globl __socket
91 ENTRY (__socket)
92         /* This will not work in the case of a socket call being interrupted
93            by a signal.  If the signal handler uses any stack the arguments
94            to socket will be trashed.  The results of a restart of any
95            socket call are then unpredictable.  */
97         /* Push args onto the stack.  */
98         P(PUSHARGS_,NARGS)
100 #if defined NEED_CANCELLATION && defined CENABLE
101         SINGLE_THREAD_P
102         bf .Lsocket_cancel
103 #endif
105         /* Do the system call trap.  */
106         mov #+P(SOCKOP_,socket), r4
107         mov r15, r5
108         mov.l .L1,r3
109         trapa #0x12
111         /* Pop args off the stack */
112         P(POPARGS_,NARGS)
114         mov     r0, r1
115         mov     #-12, r2
116         shad    r2, r1
117         not     r1, r1                  // r1=0 means r0 = -1 to -4095
118         tst     r1, r1                  // i.e. error in linux
119         bf      .Lpseudo_end
120 .Lsyscall_error:
121         SYSCALL_ERROR_HANDLER
122 .Lpseudo_end:
123         /* Successful; return the syscall's value.  */
124         rts
125          nop
127 #if defined NEED_CANCELLATION && defined CENABLE
128 .Lsocket_cancel:
129         /* Enable asynchronous cancellation.  */
130         P(ADJUSTCFI_,NARGS)
131         sts.l pr,@-r15
132         cfi_adjust_cfa_offset (4)
133         cfi_rel_offset (pr, 0)
134         CENABLE
135         lds.l @r15+,pr
136         cfi_adjust_cfa_offset (-4)
137         cfi_restore (pr)
139         /* Do the system call trap.  */
140         mov #+P(SOCKOP_,socket), r4
141         mov r15, r5
142         mov.l .L1,r3
143         trapa #0x12
145         sts.l pr,@-r15
146         cfi_adjust_cfa_offset (4)
147         cfi_rel_offset (pr, 0)
148         mov.l r0,@-r15
149         cfi_adjust_cfa_offset (4)
150         cfi_rel_offset (r0, 0)
151         CDISABLE
152         mov.l @r15+,r0
153         cfi_adjust_cfa_offset (-4)
154         cfi_restore (r0)
155         lds.l @r15+,pr
156         cfi_adjust_cfa_offset (-4)
157         cfi_restore (pr)
159         /* Pop args off the stack */
160         P(POPARGS_,NARGS)
162         mov     r0, r1
163         mov     #-12, r2
164         shad    r2, r1
165         not     r1, r1                  // r1=0 means r0 = -1 to -4095
166         tst     r1, r1                  // i.e. error in linux
167         bf      .Lpseudo_end
168         bra     .Lsyscall_error
169          nop
170 #endif
172         .align 2
173 .L1:
174         .long   SYS_ify(socketcall)
176 PSEUDO_END (__socket)
178 #ifndef NO_WEAK_ALIAS
179 weak_alias (__socket, socket)
180 #endif