blob: b9bf9d30d2288822c47b70bef1854e0eafddcf5d [file] [log] [blame]
sewardj8e8f4b32002-12-15 01:44:47 +00001
njn9850e162002-11-18 11:14:53 +00002/*--------------------------------------------------------------------*/
3/*--- Intercepts for various libc functions we want to capture ---*/
4/*--- (mostly for threading purposes). vg_intercept.c ---*/
5/*--------------------------------------------------------------------*/
6
sewardjf220ccc2002-10-23 21:53:49 +00007/*
njn9850e162002-11-18 11:14:53 +00008 This file is part of Valgrind, an extensible x86 protected-mode
9 emulator for monitoring program execution on x86-Unixes.
10
11 Copyright (C) 2000-2002 Julian Seward
12 jseward@acm.org
13
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
28
29 The GNU General Public License is contained in the file COPYING.
30*/
31
32
33/* This has some nasty duplication of stuff from vg_libpthread.c */
sewardjf220ccc2002-10-23 21:53:49 +000034
35#include <errno.h>
36#include <sys/types.h>
37
38#include "valgrind.h"
39#include "vg_include.h"
40
41# define strong_alias(name, aliasname) \
42 extern __typeof (name) aliasname __attribute__ ((alias (#name)));
43
44# define weak_alias(name, aliasname) \
45 extern __typeof (name) aliasname __attribute__ ((weak, alias (#name)));
46
47#define WEAK __attribute__((weak))
48
49#include "vg_kerneliface.h"
50
51static
52__inline__
53int is_kerror ( int res )
54{
55 if (res >= -4095 && res <= -1)
56 return 1;
57 else
58 return 0;
59}
60
61
62static inline
63int my_do_syscall5 ( int syscallno,
64 int arg1, int arg2, int arg3, int arg4, int arg5 )
65{
66 int __res;
67 __asm__ volatile ("int $0x80"
68 : "=a" (__res)
69 : "0" (syscallno),
70 "b" (arg1),
71 "c" (arg2),
72 "d" (arg3),
73 "S" (arg4),
74 "D" (arg5));
75 return __res;
76}
77
78/* -------------------------------- msgsnd -------------------------------- */
79#include <asm/ipc.h> /* for ipc_kludge */
80
81static inline int sys_ipc(unsigned call, int first, int second, int third, void *ptr)
82{
83 return my_do_syscall5(__NR_ipc, call, first, second, third, (int)ptr);
84}
85
86WEAK int VGL_(msgsnd)(int msgid, const void *msgp, size_t msgsz, int msgflg)
87{
88 int err = sys_ipc(11, msgid, msgsz, msgflg, (void *)msgp);
89 if (is_kerror(err)) {
90 *(__errno_location()) = -err;
91 return -1;
92 }
93 return 0;
94}
95
96int msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg)
97{
98 return VGL_(msgsnd)(msgid, msgp, msgsz, msgflg);
99}
100
101/* -------------------------------- msgrcv -------------------------------- */
102
103WEAK int VGL_(msgrcv)( int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg )
104{
105 struct ipc_kludge tmp;
106 int err;
107
108 tmp.msgp = msgp;
109 tmp.msgtyp = msgtyp;
110
111 err = sys_ipc(12, msqid, msgsz, msgflg, &tmp );
112
113 if (is_kerror(err)) {
114 *(__errno_location()) = -err;
115 return -1;
116 }
sewardj17c79772003-02-23 03:00:29 +0000117 return err;
sewardjf220ccc2002-10-23 21:53:49 +0000118}
119
120int msgrcv( int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg )
121{
122 return VGL_(msgrcv)( msqid, msgp, msgsz, msgtyp, msgflg );
123}
124
125/* -------------------------------- accept -------------------------------- */
126
127#include <sys/socket.h>
128
129extern
130int __libc_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
131WEAK int VGL_(accept)(int s, struct sockaddr *addr, socklen_t *addrlen)
132{
133 return __libc_accept(s, addr, addrlen);
134}
135
136int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
137{
138 return VGL_(accept)(s, addr, addrlen);
139}
sewardj0c573af92002-10-23 21:55:01 +0000140
141/* -------------------------------- recv -------------------------------- */
142
143extern
144int __libc_recv(int s, void *buf, size_t len, int flags);
145
146WEAK int VGL_(recv)(int s, void *buf, size_t len, int flags)
147{
sewardj7db011a2002-11-13 22:00:20 +0000148 return __libc_recv(s, buf, len, flags);
sewardj0c573af92002-10-23 21:55:01 +0000149}
150
151int recv(int s, void *buf, size_t len, int flags)
152{
sewardj7db011a2002-11-13 22:00:20 +0000153 return VGL_(recv)(s, buf, len, flags);
sewardj0c573af92002-10-23 21:55:01 +0000154}
155
156strong_alias(recv, __recv)
sewardj7db011a2002-11-13 22:00:20 +0000157
158/* -------------------------------- poll -------------------------------- */
159
160static inline
161int my_do_syscall3 ( int syscallno,
162 int arg1, int arg2, int arg3 )
163{
164 int __res;
165 __asm__ volatile ("pushl %%ebx; movl %%esi,%%ebx ; int $0x80 ; popl %%ebx"
166 : "=a" (__res)
167 : "0" (syscallno),
168 "S" (arg1),
169 "c" (arg2),
170 "d" (arg3) );
171 return __res;
172}
173
174#include <sys/poll.h>
175
176#ifndef HAVE_NFDS_T
177typedef unsigned long int nfds_t;
178#endif
179
180
181WEAK int VGL_(poll)(struct pollfd *__fds, nfds_t __nfds, int __timeout)
182{
183 int res = my_do_syscall3(__NR_poll, (int)__fds, __nfds, __timeout);
184
185 if (is_kerror(res)) {
186 * (__errno_location()) = -res;
187 return -1;
188 }
189 return res;
190}
191
192int poll(struct pollfd *__fds, nfds_t __nfds, int __timeout)
193{
194 return VGL_(poll)(__fds, __nfds, __timeout);
195}
196
197strong_alias(poll, __poll)
198
199
200/* -------------------------------- select -------------------------------- */
201
202
203static inline
204int my_do_syscall1 ( int syscallno, int arg1 )
205{
206 int __res;
207 __asm__ volatile ("pushl %%ebx; movl %%edx,%%ebx ; int $0x80 ; popl %%ebx"
208 : "=a" (__res)
209 : "0" (syscallno),
210 "d" (arg1) );
211 return __res;
212}
213
214
215WEAK int VGL_(select)( int n,
216 fd_set* readfds,
217 fd_set* writefds,
218 fd_set* exceptfds,
219 struct timeval * timeout )
220{
221 int res;
222 int args[5];
223 args[0] = n;
224 args[1] = (int)readfds;
225 args[2] = (int)writefds;
226 args[3] = (int)exceptfds;
227 args[4] = (int)timeout;
228 res = my_do_syscall1(__NR_select, (int)(&(args[0])) );
sewardjfd7747b2002-12-01 10:25:53 +0000229
230 if (is_kerror(res)) {
231 *(__errno_location()) = -res;
232 return -1;
233 }
sewardj7db011a2002-11-13 22:00:20 +0000234 return res;
235}
236
237int select ( int n,
238 fd_set *rfds,
239 fd_set *wfds,
240 fd_set *xfds,
241 struct timeval *timeout )
242{
243 return VGL_(select)(n, rfds, wfds, xfds, timeout);
244}
245
246strong_alias(select, __select)
sewardj2a68e7e2002-11-16 11:04:18 +0000247
248/* -------------------------------- readv -------------------------------- */
249
250#include <sys/uio.h>
251
252WEAK int VGL_(readv)(int fd, const struct iovec *iov, int count)
253{
sewardjfd7747b2002-12-01 10:25:53 +0000254 int res = my_do_syscall3(__NR_readv, fd, (unsigned)iov, count);
255
256 if (is_kerror(res)) {
257 *(__errno_location()) = -res;
258 return -1;
259 }
260
261 return res;
sewardj2a68e7e2002-11-16 11:04:18 +0000262}
263
264int readv (int fd, const struct iovec *iov, int count)
265{
266 return VGL_(readv)(fd, iov, count);
267}
268
269strong_alias(readv, __readv)
270
271/* -------------------------------- writev -------------------------------- */
272
273WEAK int VGL_(writev)(int fd, const struct iovec *iov, int count)
274{
sewardjfd7747b2002-12-01 10:25:53 +0000275 int res = my_do_syscall3(__NR_writev, fd, (unsigned)iov, count);
276
277 if (is_kerror(res)) {
278 *(__errno_location()) = -res;
279 return -1;
280 }
281
282 return res;
sewardj2a68e7e2002-11-16 11:04:18 +0000283}
284
285int writev (int fd, const struct iovec *iov, int count)
286{
287 return VGL_(writev)(fd, iov, count);
288}
289
290strong_alias(writev, __writev)
njn9850e162002-11-18 11:14:53 +0000291
292/*--------------------------------------------------------------------*/
293/*--- end vg_intercept.c ---*/
294/*--------------------------------------------------------------------*/
295