blob: 77dcf2189b14d96160052af9842aeb05c85085dc [file] [log] [blame]
sewardjde4a1d02002-03-22 01:27:54 +00001
2/*--------------------------------------------------------------------*/
3/*--- Reimplementation of some C library stuff, to avoid depending ---*/
4/*--- on libc.so. ---*/
5/*--- vg_mylibc.c ---*/
6/*--------------------------------------------------------------------*/
7
8/*
njnc9539842002-10-02 13:26:35 +00009 This file is part of Valgrind, an extensible x86 protected-mode
10 emulator for monitoring program execution on x86-Unixes.
sewardjde4a1d02002-03-22 01:27:54 +000011
nethercotebb1c9912004-01-04 16:43:23 +000012 Copyright (C) 2000-2004 Julian Seward
sewardjde4a1d02002-03-22 01:27:54 +000013 jseward@acm.org
sewardjde4a1d02002-03-22 01:27:54 +000014
15 This program is free software; you can redistribute it and/or
16 modify it under the terms of the GNU General Public License as
17 published by the Free Software Foundation; either version 2 of the
18 License, or (at your option) any later version.
19
20 This program is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 02111-1307, USA.
29
njn25e49d8e72002-09-23 09:36:25 +000030 The GNU General Public License is contained in the file COPYING.
sewardjde4a1d02002-03-22 01:27:54 +000031*/
32
nethercotef1e5e152004-09-01 23:58:16 +000033#include "core.h"
sewardjde4a1d02002-03-22 01:27:54 +000034
sewardjde4a1d02002-03-22 01:27:54 +000035/* ---------------------------------------------------------------------
36 Wrappers around system calls, and other stuff, to do with signals.
37 ------------------------------------------------------------------ */
38
39/* sigemptyset, sigfullset, sigaddset and sigdelset return 0 on
40 success and -1 on error.
41*/
nethercote73b526f2004-10-31 18:48:21 +000042Int VG_(sigfillset)( vki_sigset_t* set )
sewardjde4a1d02002-03-22 01:27:54 +000043{
44 Int i;
45 if (set == NULL)
46 return -1;
nethercote73b526f2004-10-31 18:48:21 +000047 for (i = 0; i < _VKI_NSIG_WORDS; i++)
48 set->sig[i] = 0xFFFFFFFF;
sewardjde4a1d02002-03-22 01:27:54 +000049 return 0;
50}
51
nethercote73b526f2004-10-31 18:48:21 +000052Int VG_(sigemptyset)( vki_sigset_t* set )
sewardjde4a1d02002-03-22 01:27:54 +000053{
54 Int i;
55 if (set == NULL)
56 return -1;
nethercote73b526f2004-10-31 18:48:21 +000057 for (i = 0; i < _VKI_NSIG_WORDS; i++)
58 set->sig[i] = 0x0;
sewardjde4a1d02002-03-22 01:27:54 +000059 return 0;
60}
61
nethercote73b526f2004-10-31 18:48:21 +000062Bool VG_(isemptysigset)( vki_sigset_t* set )
sewardjb48e5002002-05-13 00:16:03 +000063{
64 Int i;
65 vg_assert(set != NULL);
nethercote73b526f2004-10-31 18:48:21 +000066 for (i = 0; i < _VKI_NSIG_WORDS; i++)
67 if (set->sig[i] != 0x0) return False;
sewardjb48e5002002-05-13 00:16:03 +000068 return True;
69}
70
nethercote73b526f2004-10-31 18:48:21 +000071Bool VG_(isfullsigset)( vki_sigset_t* set )
sewardj018f7622002-05-15 21:13:39 +000072{
73 Int i;
74 vg_assert(set != NULL);
nethercote73b526f2004-10-31 18:48:21 +000075 for (i = 0; i < _VKI_NSIG_WORDS; i++)
76 if (set->sig[i] != (UInt)(~0x0)) return False;
sewardj018f7622002-05-15 21:13:39 +000077 return True;
78}
79
80
nethercote73b526f2004-10-31 18:48:21 +000081Int VG_(sigaddset)( vki_sigset_t* set, Int signum )
sewardjde4a1d02002-03-22 01:27:54 +000082{
83 if (set == NULL)
84 return -1;
nethercote73b526f2004-10-31 18:48:21 +000085 if (signum < 1 || signum > _VKI_NSIG)
sewardjde4a1d02002-03-22 01:27:54 +000086 return -1;
87 signum--;
nethercote73b526f2004-10-31 18:48:21 +000088 set->sig[signum / _VKI_NSIG_BPW] |= (1 << (signum % _VKI_NSIG_BPW));
sewardjde4a1d02002-03-22 01:27:54 +000089 return 0;
90}
91
nethercote73b526f2004-10-31 18:48:21 +000092Int VG_(sigdelset)( vki_sigset_t* set, Int signum )
sewardj018f7622002-05-15 21:13:39 +000093{
94 if (set == NULL)
95 return -1;
nethercote73b526f2004-10-31 18:48:21 +000096 if (signum < 1 || signum > _VKI_NSIG)
sewardj018f7622002-05-15 21:13:39 +000097 return -1;
98 signum--;
nethercote73b526f2004-10-31 18:48:21 +000099 set->sig[signum / _VKI_NSIG_BPW] &= ~(1 << (signum % _VKI_NSIG_BPW));
sewardj018f7622002-05-15 21:13:39 +0000100 return 0;
101}
102
nethercote73b526f2004-10-31 18:48:21 +0000103Int VG_(sigismember) ( vki_sigset_t* set, Int signum )
sewardjde4a1d02002-03-22 01:27:54 +0000104{
105 if (set == NULL)
sewardjb48e5002002-05-13 00:16:03 +0000106 return 0;
nethercote73b526f2004-10-31 18:48:21 +0000107 if (signum < 1 || signum > _VKI_NSIG)
sewardjb48e5002002-05-13 00:16:03 +0000108 return 0;
sewardjde4a1d02002-03-22 01:27:54 +0000109 signum--;
nethercote73b526f2004-10-31 18:48:21 +0000110 if (1 & ((set->sig[signum / _VKI_NSIG_BPW]) >> (signum % _VKI_NSIG_BPW)))
sewardjde4a1d02002-03-22 01:27:54 +0000111 return 1;
112 else
113 return 0;
114}
115
116
sewardjb48e5002002-05-13 00:16:03 +0000117/* Add all signals in src to dst. */
nethercote73b526f2004-10-31 18:48:21 +0000118void VG_(sigaddset_from_set)( vki_sigset_t* dst, vki_sigset_t* src )
sewardjb48e5002002-05-13 00:16:03 +0000119{
120 Int i;
121 vg_assert(dst != NULL && src != NULL);
nethercote73b526f2004-10-31 18:48:21 +0000122 for (i = 0; i < _VKI_NSIG_WORDS; i++)
123 dst->sig[i] |= src->sig[i];
sewardjb48e5002002-05-13 00:16:03 +0000124}
125
126/* Remove all signals in src from dst. */
nethercote73b526f2004-10-31 18:48:21 +0000127void VG_(sigdelset_from_set)( vki_sigset_t* dst, vki_sigset_t* src )
sewardjb48e5002002-05-13 00:16:03 +0000128{
129 Int i;
130 vg_assert(dst != NULL && src != NULL);
nethercote73b526f2004-10-31 18:48:21 +0000131 for (i = 0; i < _VKI_NSIG_WORDS; i++)
132 dst->sig[i] &= ~(src->sig[i]);
sewardjb48e5002002-05-13 00:16:03 +0000133}
134
135
sewardjde4a1d02002-03-22 01:27:54 +0000136/* The functions sigaction, sigprocmask, sigpending and sigsuspend
137 return 0 on success and -1 on error.
138*/
nethercote73b526f2004-10-31 18:48:21 +0000139Int VG_(sigprocmask)( Int how,
140 const vki_sigset_t* set,
141 vki_sigset_t* oldset)
sewardjde4a1d02002-03-22 01:27:54 +0000142{
143 Int res
jsgf855d93d2003-10-13 22:26:55 +0000144 = VG_(do_syscall)(__NR_rt_sigprocmask,
145 how, (UInt)set, (UInt)oldset,
nethercote73b526f2004-10-31 18:48:21 +0000146 _VKI_NSIG_WORDS * sizeof(UWord));
sewardjde4a1d02002-03-22 01:27:54 +0000147 return VG_(is_kerror)(res) ? -1 : 0;
148}
149
150
nethercote73b526f2004-10-31 18:48:21 +0000151Int VG_(sigaction) ( Int signum,
152 const struct vki_sigaction* act,
153 struct vki_sigaction* oldact)
sewardjde4a1d02002-03-22 01:27:54 +0000154{
155 Int res
jsgf855d93d2003-10-13 22:26:55 +0000156 = VG_(do_syscall)(__NR_rt_sigaction,
157 signum, (UInt)act, (UInt)oldact,
nethercote73b526f2004-10-31 18:48:21 +0000158 _VKI_NSIG_WORDS * sizeof(UWord));
sewardj018f7622002-05-15 21:13:39 +0000159 /* VG_(printf)("res = %d\n",res); */
sewardjde4a1d02002-03-22 01:27:54 +0000160 return VG_(is_kerror)(res) ? -1 : 0;
161}
162
163
nethercote73b526f2004-10-31 18:48:21 +0000164Int VG_(sigaltstack)( const vki_stack_t* ss, vki_stack_t* oss )
sewardjde4a1d02002-03-22 01:27:54 +0000165{
166 Int res
jsgf855d93d2003-10-13 22:26:55 +0000167 = VG_(do_syscall)(__NR_sigaltstack, (UInt)ss, (UInt)oss);
sewardjde4a1d02002-03-22 01:27:54 +0000168 return VG_(is_kerror)(res) ? -1 : 0;
169}
170
nethercote73b526f2004-10-31 18:48:21 +0000171Int VG_(sigtimedwait)( const vki_sigset_t *set, vki_siginfo_t *info,
jsgf855d93d2003-10-13 22:26:55 +0000172 const struct vki_timespec *timeout )
173{
174 Int res = VG_(do_syscall)(__NR_rt_sigtimedwait, set, info, timeout, sizeof(*set));
175
176 return VG_(is_kerror)(res) ? -1 : res;
177}
sewardjde4a1d02002-03-22 01:27:54 +0000178
nethercote73b526f2004-10-31 18:48:21 +0000179Int VG_(signal)(Int signum, void (*sighandler)(Int))
sewardjde4a1d02002-03-22 01:27:54 +0000180{
181 Int res;
nethercote73b526f2004-10-31 18:48:21 +0000182 struct vki_sigaction sa;
sewardjde4a1d02002-03-22 01:27:54 +0000183 sa.ksa_handler = sighandler;
nethercote73b526f2004-10-31 18:48:21 +0000184 sa.sa_flags = VKI_SA_ONSTACK | VKI_SA_RESTART;
185 sa.sa_restorer = NULL;
186 res = VG_(sigemptyset)( &sa.sa_mask );
sewardjde4a1d02002-03-22 01:27:54 +0000187 vg_assert(res == 0);
jsgf855d93d2003-10-13 22:26:55 +0000188 res = VG_(do_syscall)(__NR_rt_sigaction,
189 signum, (UInt)(&sa), (UInt)NULL,
nethercote73b526f2004-10-31 18:48:21 +0000190 _VKI_NSIG_WORDS * sizeof(UWord));
sewardjde4a1d02002-03-22 01:27:54 +0000191 return VG_(is_kerror)(res) ? -1 : 0;
192}
193
194
nethercote73b526f2004-10-31 18:48:21 +0000195Int VG_(kill)( Int pid, Int signo )
sewardj018f7622002-05-15 21:13:39 +0000196{
jsgf855d93d2003-10-13 22:26:55 +0000197 Int res = VG_(do_syscall)(__NR_kill, pid, signo);
sewardj018f7622002-05-15 21:13:39 +0000198 return VG_(is_kerror)(res) ? -1 : 0;
199}
200
201
nethercote73b526f2004-10-31 18:48:21 +0000202Int VG_(tkill)( Int tid, Int signo )
jsgf855d93d2003-10-13 22:26:55 +0000203{
204 Int ret = -VKI_ENOSYS;
205
thughes848907a2004-10-18 18:56:25 +0000206#ifdef __NR_tgkill
207 ret = VG_(do_syscall)(__NR_tgkill, VG_(main_pid), tid, signo);
208#endif /* __NR_tgkill */
209
jsgf855d93d2003-10-13 22:26:55 +0000210#ifdef __NR_tkill
thughes848907a2004-10-18 18:56:25 +0000211 if (ret == -VKI_ENOSYS)
212 ret = VG_(do_syscall)(__NR_tkill, tid, signo);
jsgf855d93d2003-10-13 22:26:55 +0000213#endif /* __NR_tkill */
214
215 if (ret == -VKI_ENOSYS)
216 ret = VG_(do_syscall)(__NR_kill, tid, signo);
217
218 return VG_(is_kerror)(ret) ? -1 : 0;
219}
220
nethercote73b526f2004-10-31 18:48:21 +0000221Int VG_(sigpending) ( vki_sigset_t* set )
sewardjefbfcdf2002-06-19 17:35:45 +0000222{
jsgf855d93d2003-10-13 22:26:55 +0000223 Int res = VG_(do_syscall)(__NR_sigpending, (UInt)set);
sewardjefbfcdf2002-06-19 17:35:45 +0000224 return VG_(is_kerror)(res) ? -1 : 0;
225}
226
jsgf855d93d2003-10-13 22:26:55 +0000227Int VG_(waitpid)(Int pid, Int *status, Int options)
228{
229 Int ret = VG_(do_syscall)(__NR_wait4, pid, status, options, NULL);
230
231 return VG_(is_kerror)(ret) ? -1 : ret;
232}
233
234Int VG_(gettid)(void)
235{
236 Int ret;
237
238 ret = VG_(do_syscall)(__NR_gettid);
239
thughes8ef6d962004-10-16 10:46:01 +0000240 if (ret == -VKI_ENOSYS) {
241 Char pid[16];
242
243 /*
244 * The gettid system call does not exist. The obvious assumption
245 * to make at this point would be that we are running on an older
246 * system where the getpid system call actually returns the ID of
247 * the current thread.
248 *
249 * Unfortunately it seems that there are some systems with a kernel
250 * where getpid has been changed to return the ID of the thread group
251 * leader but where the gettid system call has not yet been added.
252 *
253 * So instead of calling getpid here we use readlink to see where
254 * the /proc/self link is pointing...
255 */
256 if ((ret = VG_(do_syscall)(__NR_readlink, "/proc/self", pid, sizeof(pid))) >= 0) {
257 pid[ret] = '\0';
258 ret = VG_(atoll)(pid);
259 }
260 }
jsgf855d93d2003-10-13 22:26:55 +0000261
262 return ret;
263}
264
265
sewardjefbfcdf2002-06-19 17:35:45 +0000266
sewardjde4a1d02002-03-22 01:27:54 +0000267/* ---------------------------------------------------------------------
sewardj2e93c502002-04-12 11:12:52 +0000268 mmap/munmap, exit, fcntl
sewardjde4a1d02002-03-22 01:27:54 +0000269 ------------------------------------------------------------------ */
270
fitzhardingeb50068f2004-02-24 23:42:55 +0000271static Int munmap_inner(void *start, UInt length)
272{
273 return VG_(do_syscall)(__NR_munmap, (UInt)start, (UInt)length );
274}
275
nethercote8b5f40c2004-11-02 13:29:50 +0000276static Addr mmap_inner(void *start, SizeT length, UInt prot, UInt flags, UInt fd, UInt offset)
fitzhardingeb50068f2004-02-24 23:42:55 +0000277{
nethercote6456ab12004-10-18 14:47:48 +0000278 Int ret;
279
280 PLATFORM_DO_MMAP(ret, start, length, prot,
281 flags & ~(VKI_MAP_NOSYMS|VKI_MAP_CLIENT),
282 fd, offset);
283 return ret;
fitzhardingeb50068f2004-02-24 23:42:55 +0000284}
285
sewardjde4a1d02002-03-22 01:27:54 +0000286/* Returns -1 on failure. */
nethercote8b5f40c2004-11-02 13:29:50 +0000287void* VG_(mmap)( void* start, SizeT length,
nethercoteb4250ae2004-07-10 16:50:09 +0000288 UInt prot, UInt flags, UInt sf_flags, UInt fd, UInt offset)
sewardjde4a1d02002-03-22 01:27:54 +0000289{
fitzhardinge98abfc72003-12-16 02:05:15 +0000290 Addr res;
fitzhardinge98abfc72003-12-16 02:05:15 +0000291
292 if (!(flags & VKI_MAP_FIXED)) {
293 start = (void *)VG_(find_map_space)((Addr)start, length, !!(flags & VKI_MAP_CLIENT));
fitzhardinge98abfc72003-12-16 02:05:15 +0000294
295 flags |= VKI_MAP_FIXED;
296 }
nethercoteb4250ae2004-07-10 16:50:09 +0000297 if (start == 0)
298 return (void *)-1;
fitzhardinge98abfc72003-12-16 02:05:15 +0000299
fitzhardingeb50068f2004-02-24 23:42:55 +0000300 res = mmap_inner(start, length, prot, flags, fd, offset);
fitzhardinge98abfc72003-12-16 02:05:15 +0000301
nethercoteb4250ae2004-07-10 16:50:09 +0000302 // Check it ended up in the right place.
fitzhardinge98abfc72003-12-16 02:05:15 +0000303 if (!VG_(is_kerror)(res)) {
fitzhardinge98abfc72003-12-16 02:05:15 +0000304 if (flags & VKI_MAP_CLIENT) {
nethercote00600502004-09-11 23:27:09 +0000305 vg_assert(VG_(client_base) <= res && res+length <= VG_(client_end));
fitzhardinge98abfc72003-12-16 02:05:15 +0000306 } else {
nethercotefb583e22004-09-07 23:15:37 +0000307 vg_assert(VG_(valgrind_base) <= res && res+length-1 <= VG_(valgrind_last));
fitzhardinge98abfc72003-12-16 02:05:15 +0000308 }
fitzhardinge98abfc72003-12-16 02:05:15 +0000309
nethercoteb4250ae2004-07-10 16:50:09 +0000310 sf_flags |= SF_MMAP;
311 if ( flags & VKI_MAP_FIXED) sf_flags |= SF_FIXED;
312 if ( flags & VKI_MAP_SHARED) sf_flags |= SF_SHARED;
313 if (!(flags & VKI_MAP_ANONYMOUS)) sf_flags |= SF_FILE;
314 if (!(flags & VKI_MAP_CLIENT)) sf_flags |= SF_VALGRIND;
315 if ( flags & VKI_MAP_NOSYMS) sf_flags |= SF_NOSYMS;
316
317 VG_(map_fd_segment)(res, length, prot, sf_flags, fd, offset, NULL);
318 }
fitzhardinge98abfc72003-12-16 02:05:15 +0000319
sewardjde4a1d02002-03-22 01:27:54 +0000320 return VG_(is_kerror)(res) ? ((void*)(-1)) : (void*)res;
321}
322
323/* Returns -1 on failure. */
nethercote8b5f40c2004-11-02 13:29:50 +0000324Int VG_(munmap)( void* start, SizeT length )
sewardjde4a1d02002-03-22 01:27:54 +0000325{
fitzhardingeb50068f2004-02-24 23:42:55 +0000326 Int res = munmap_inner(start, length);
fitzhardinge920d04e2003-12-20 18:19:50 +0000327 if (!VG_(is_kerror)(res))
fitzhardinge98abfc72003-12-16 02:05:15 +0000328 VG_(unmap_range)((Addr)start, length);
329 return VG_(is_kerror)(res) ? -1 : 0;
330}
331
nethercote8b5f40c2004-11-02 13:29:50 +0000332Int VG_(mprotect)( void *start, SizeT length, UInt prot )
fitzhardinge98abfc72003-12-16 02:05:15 +0000333{
nethercote8b5f40c2004-11-02 13:29:50 +0000334 Int res = VG_(do_syscall)(__NR_mprotect, (UWord)start, length, prot );
fitzhardinge98abfc72003-12-16 02:05:15 +0000335 if (!VG_(is_kerror)(res))
336 VG_(mprotect_range)((Addr)start, length, prot);
sewardjde4a1d02002-03-22 01:27:54 +0000337 return VG_(is_kerror)(res) ? -1 : 0;
338}
339
340void VG_(exit)( Int status )
341{
jsgf855d93d2003-10-13 22:26:55 +0000342 (void)VG_(do_syscall)(__NR_exit_group, (UInt)status );
343 (void)VG_(do_syscall)(__NR_exit, (UInt)status );
sewardjde4a1d02002-03-22 01:27:54 +0000344 /* Why are we still alive here? */
345 /*NOTREACHED*/
jsgf855d93d2003-10-13 22:26:55 +0000346 *(volatile Int *)0 = 'x';
sewardjde4a1d02002-03-22 01:27:54 +0000347 vg_assert(2+2 == 5);
348}
349
sewardj2e93c502002-04-12 11:12:52 +0000350/* Returns -1 on error. */
351Int VG_(fcntl) ( Int fd, Int cmd, Int arg )
352{
jsgf855d93d2003-10-13 22:26:55 +0000353 Int res = VG_(do_syscall)(__NR_fcntl, fd, cmd, arg);
sewardj2e93c502002-04-12 11:12:52 +0000354 return VG_(is_kerror)(res) ? -1 : res;
355}
356
jsgf855d93d2003-10-13 22:26:55 +0000357Int VG_(poll)( struct vki_pollfd *ufds, UInt nfds, Int timeout)
358{
359 Int res = VG_(do_syscall)(__NR_poll, ufds, nfds, timeout);
360
361 return res;
362}
363
sewardj2e93c502002-04-12 11:12:52 +0000364
sewardjde4a1d02002-03-22 01:27:54 +0000365/* ---------------------------------------------------------------------
366 printf implementation. The key function, vg_vprintf(), emits chars
367 into a caller-supplied function. Distantly derived from:
368
369 vprintf replacement for Checker.
370 Copyright 1993, 1994, 1995 Tristan Gingold
371 Written September 1993 Tristan Gingold
372 Tristan Gingold, 8 rue Parmentier, F-91120 PALAISEAU, FRANCE
373
374 (Checker itself was GPL'd.)
375 ------------------------------------------------------------------ */
376
377
378/* Some flags. */
379#define VG_MSG_SIGNED 1 /* The value is signed. */
380#define VG_MSG_ZJUSTIFY 2 /* Must justify with '0'. */
381#define VG_MSG_LJUSTIFY 4 /* Must justify on the left. */
sewardj78e3cd92002-10-22 04:45:48 +0000382#define VG_MSG_PAREN 8 /* Parenthesize if present (for %y) */
njn607adfc2003-09-30 14:15:44 +0000383#define VG_MSG_COMMA 16 /* Add commas to numbers (for %d, %u) */
sewardjde4a1d02002-03-22 01:27:54 +0000384
385/* Copy a string into the buffer. */
sewardj78e3cd92002-10-22 04:45:48 +0000386static UInt
sewardjde4a1d02002-03-22 01:27:54 +0000387myvprintf_str ( void(*send)(Char), Int flags, Int width, Char* str,
388 Bool capitalise )
389{
390# define MAYBE_TOUPPER(ch) (capitalise ? VG_(toupper)(ch) : (ch))
sewardj78e3cd92002-10-22 04:45:48 +0000391 UInt ret = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000392 Int i, extra;
393 Int len = VG_(strlen)(str);
394
395 if (width == 0) {
sewardj78e3cd92002-10-22 04:45:48 +0000396 ret += len;
sewardjde4a1d02002-03-22 01:27:54 +0000397 for (i = 0; i < len; i++)
398 send(MAYBE_TOUPPER(str[i]));
sewardj78e3cd92002-10-22 04:45:48 +0000399 return ret;
sewardjde4a1d02002-03-22 01:27:54 +0000400 }
401
402 if (len > width) {
sewardj78e3cd92002-10-22 04:45:48 +0000403 ret += width;
sewardjde4a1d02002-03-22 01:27:54 +0000404 for (i = 0; i < width; i++)
405 send(MAYBE_TOUPPER(str[i]));
sewardj78e3cd92002-10-22 04:45:48 +0000406 return ret;
sewardjde4a1d02002-03-22 01:27:54 +0000407 }
408
409 extra = width - len;
410 if (flags & VG_MSG_LJUSTIFY) {
sewardj78e3cd92002-10-22 04:45:48 +0000411 ret += extra;
sewardjde4a1d02002-03-22 01:27:54 +0000412 for (i = 0; i < extra; i++)
413 send(' ');
414 }
sewardj78e3cd92002-10-22 04:45:48 +0000415 ret += len;
sewardjde4a1d02002-03-22 01:27:54 +0000416 for (i = 0; i < len; i++)
417 send(MAYBE_TOUPPER(str[i]));
418 if (!(flags & VG_MSG_LJUSTIFY)) {
sewardj78e3cd92002-10-22 04:45:48 +0000419 ret += extra;
sewardjde4a1d02002-03-22 01:27:54 +0000420 for (i = 0; i < extra; i++)
421 send(' ');
422 }
423
424# undef MAYBE_TOUPPER
sewardj78e3cd92002-10-22 04:45:48 +0000425
426 return ret;
sewardjde4a1d02002-03-22 01:27:54 +0000427}
428
429/* Write P into the buffer according to these args:
430 * If SIGN is true, p is a signed.
431 * BASE is the base.
432 * If WITH_ZERO is true, '0' must be added.
433 * WIDTH is the width of the field.
434 */
sewardj78e3cd92002-10-22 04:45:48 +0000435static UInt
sewardjde4a1d02002-03-22 01:27:54 +0000436myvprintf_int64 ( void(*send)(Char), Int flags, Int base, Int width, ULong p)
437{
438 Char buf[40];
439 Int ind = 0;
njn607adfc2003-09-30 14:15:44 +0000440 Int i, nc = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000441 Bool neg = False;
442 Char *digits = "0123456789ABCDEF";
sewardj78e3cd92002-10-22 04:45:48 +0000443 UInt ret = 0;
444
sewardjde4a1d02002-03-22 01:27:54 +0000445 if (base < 2 || base > 16)
sewardj78e3cd92002-10-22 04:45:48 +0000446 return ret;
sewardjde4a1d02002-03-22 01:27:54 +0000447
448 if ((flags & VG_MSG_SIGNED) && (Long)p < 0) {
449 p = - (Long)p;
450 neg = True;
451 }
452
453 if (p == 0)
454 buf[ind++] = '0';
455 else {
456 while (p > 0) {
njn607adfc2003-09-30 14:15:44 +0000457 if (flags & VG_MSG_COMMA && 10 == base &&
458 0 == (ind-nc) % 3 && 0 != ind)
459 {
460 buf[ind++] = ',';
461 nc++;
462 }
sewardjde4a1d02002-03-22 01:27:54 +0000463 buf[ind++] = digits[p % base];
464 p /= base;
njn607adfc2003-09-30 14:15:44 +0000465 }
sewardjde4a1d02002-03-22 01:27:54 +0000466 }
467
468 if (neg)
469 buf[ind++] = '-';
470
471 if (width > 0 && !(flags & VG_MSG_LJUSTIFY)) {
472 for(; ind < width; ind++) {
473 vg_assert(ind < 39);
474 buf[ind] = (flags & VG_MSG_ZJUSTIFY) ? '0': ' ';
475 }
476 }
477
478 /* Reverse copy to buffer. */
sewardj78e3cd92002-10-22 04:45:48 +0000479 ret += ind;
njn607adfc2003-09-30 14:15:44 +0000480 for (i = ind -1; i >= 0; i--) {
sewardjde4a1d02002-03-22 01:27:54 +0000481 send(buf[i]);
njn607adfc2003-09-30 14:15:44 +0000482 }
sewardjde4a1d02002-03-22 01:27:54 +0000483 if (width > 0 && (flags & VG_MSG_LJUSTIFY)) {
sewardj78e3cd92002-10-22 04:45:48 +0000484 for(; ind < width; ind++) {
485 ret++;
njn607adfc2003-09-30 14:15:44 +0000486 send(' '); // Never pad with zeroes on RHS -- changes the value!
sewardj78e3cd92002-10-22 04:45:48 +0000487 }
sewardjde4a1d02002-03-22 01:27:54 +0000488 }
sewardj78e3cd92002-10-22 04:45:48 +0000489 return ret;
sewardjde4a1d02002-03-22 01:27:54 +0000490}
491
492
493/* A simple vprintf(). */
sewardj78e3cd92002-10-22 04:45:48 +0000494UInt
sewardjde4a1d02002-03-22 01:27:54 +0000495VG_(vprintf) ( void(*send)(Char), const Char *format, va_list vargs )
496{
sewardj78e3cd92002-10-22 04:45:48 +0000497 UInt ret = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000498 int i;
499 int flags;
500 int width;
501 Bool is_long;
502
503 /* We assume that vargs has already been initialised by the
504 caller, using va_start, and that the caller will similarly
505 clean up with va_end.
506 */
507
508 for (i = 0; format[i] != 0; i++) {
509 if (format[i] != '%') {
510 send(format[i]);
sewardj78e3cd92002-10-22 04:45:48 +0000511 ret++;
sewardjde4a1d02002-03-22 01:27:54 +0000512 continue;
513 }
514 i++;
515 /* A '%' has been found. Ignore a trailing %. */
516 if (format[i] == 0)
517 break;
518 if (format[i] == '%') {
519 /* `%%' is replaced by `%'. */
520 send('%');
sewardj78e3cd92002-10-22 04:45:48 +0000521 ret++;
sewardjde4a1d02002-03-22 01:27:54 +0000522 continue;
523 }
524 flags = 0;
525 is_long = False;
526 width = 0; /* length of the field. */
sewardj78e3cd92002-10-22 04:45:48 +0000527 if (format[i] == '(') {
528 flags |= VG_MSG_PAREN;
529 i++;
530 }
njn607adfc2003-09-30 14:15:44 +0000531 /* If ',' follows '%', commas will be inserted. */
532 if (format[i] == ',') {
533 flags |= VG_MSG_COMMA;
534 i++;
535 }
sewardjde4a1d02002-03-22 01:27:54 +0000536 /* If '-' follows '%', justify on the left. */
537 if (format[i] == '-') {
538 flags |= VG_MSG_LJUSTIFY;
539 i++;
540 }
541 /* If '0' follows '%', pads will be inserted. */
542 if (format[i] == '0') {
543 flags |= VG_MSG_ZJUSTIFY;
544 i++;
545 }
546 /* Compute the field length. */
547 while (format[i] >= '0' && format[i] <= '9') {
548 width *= 10;
549 width += format[i++] - '0';
550 }
551 while (format[i] == 'l') {
552 i++;
553 is_long = True;
554 }
555
556 switch (format[i]) {
557 case 'd': /* %d */
558 flags |= VG_MSG_SIGNED;
559 if (is_long)
sewardj78e3cd92002-10-22 04:45:48 +0000560 ret += myvprintf_int64(send, flags, 10, width,
561 (ULong)(va_arg (vargs, Long)));
sewardjde4a1d02002-03-22 01:27:54 +0000562 else
sewardj78e3cd92002-10-22 04:45:48 +0000563 ret += myvprintf_int64(send, flags, 10, width,
564 (ULong)(va_arg (vargs, Int)));
sewardjde4a1d02002-03-22 01:27:54 +0000565 break;
566 case 'u': /* %u */
567 if (is_long)
sewardj78e3cd92002-10-22 04:45:48 +0000568 ret += myvprintf_int64(send, flags, 10, width,
569 (ULong)(va_arg (vargs, ULong)));
sewardjde4a1d02002-03-22 01:27:54 +0000570 else
sewardj78e3cd92002-10-22 04:45:48 +0000571 ret += myvprintf_int64(send, flags, 10, width,
572 (ULong)(va_arg (vargs, UInt)));
sewardjde4a1d02002-03-22 01:27:54 +0000573 break;
574 case 'p': /* %p */
sewardj78e3cd92002-10-22 04:45:48 +0000575 ret += 2;
sewardjde4a1d02002-03-22 01:27:54 +0000576 send('0');
577 send('x');
sewardj78e3cd92002-10-22 04:45:48 +0000578 ret += myvprintf_int64(send, flags, 16, width,
579 (ULong)((UInt)va_arg (vargs, void *)));
sewardjde4a1d02002-03-22 01:27:54 +0000580 break;
581 case 'x': /* %x */
582 if (is_long)
sewardj78e3cd92002-10-22 04:45:48 +0000583 ret += myvprintf_int64(send, flags, 16, width,
584 (ULong)(va_arg (vargs, ULong)));
sewardjde4a1d02002-03-22 01:27:54 +0000585 else
sewardj78e3cd92002-10-22 04:45:48 +0000586 ret += myvprintf_int64(send, flags, 16, width,
587 (ULong)(va_arg (vargs, UInt)));
sewardjde4a1d02002-03-22 01:27:54 +0000588 break;
589 case 'c': /* %c */
sewardj78e3cd92002-10-22 04:45:48 +0000590 ret++;
sewardjde4a1d02002-03-22 01:27:54 +0000591 send(va_arg (vargs, int));
592 break;
593 case 's': case 'S': { /* %s */
594 char *str = va_arg (vargs, char *);
595 if (str == (char*) 0) str = "(null)";
sewardj78e3cd92002-10-22 04:45:48 +0000596 ret += myvprintf_str(send, flags, width, str, format[i]=='S');
sewardjde4a1d02002-03-22 01:27:54 +0000597 break;
sewardj78e3cd92002-10-22 04:45:48 +0000598 }
599 case 'y': { /* %y - print symbol */
600 Char buf[100];
601 Char *cp = buf;
602 Addr a = va_arg(vargs, Addr);
603
604 if (flags & VG_MSG_PAREN)
605 *cp++ = '(';
sewardj6e008cb2002-12-15 13:11:39 +0000606 if (VG_(get_fnname_w_offset)(a, cp, sizeof(buf)-4)) {
sewardj78e3cd92002-10-22 04:45:48 +0000607 if (flags & VG_MSG_PAREN) {
608 cp += VG_(strlen)(cp);
609 *cp++ = ')';
610 *cp = '\0';
611 }
612 ret += myvprintf_str(send, flags, width, buf, 0);
613 }
614
615 break;
616 }
sewardjde4a1d02002-03-22 01:27:54 +0000617 default:
618 break;
619 }
620 }
sewardj78e3cd92002-10-22 04:45:48 +0000621 return ret;
sewardjde4a1d02002-03-22 01:27:54 +0000622}
623
624
625/* A general replacement for printf(). Note that only low-level
626 debugging info should be sent via here. The official route is to
627 to use vg_message(). This interface is deprecated.
628*/
629static char myprintf_buf[100];
630static int n_myprintf_buf;
631
632static void add_to_myprintf_buf ( Char c )
633{
634 if (n_myprintf_buf >= 100-10 /*paranoia*/ ) {
nethercotef8548672004-06-21 12:42:35 +0000635 if (VG_(clo_log_fd) >= 0) {
sewardj570f8902002-11-03 11:44:36 +0000636 VG_(send_bytes_to_logging_sink)(
637 myprintf_buf, VG_(strlen)(myprintf_buf) );
sewardj73cf3bc2002-11-03 03:20:15 +0000638 }
sewardjde4a1d02002-03-22 01:27:54 +0000639 n_myprintf_buf = 0;
640 myprintf_buf[n_myprintf_buf] = 0;
641 }
642 myprintf_buf[n_myprintf_buf++] = c;
643 myprintf_buf[n_myprintf_buf] = 0;
644}
645
sewardj78e3cd92002-10-22 04:45:48 +0000646UInt VG_(printf) ( const char *format, ... )
sewardjde4a1d02002-03-22 01:27:54 +0000647{
sewardj78e3cd92002-10-22 04:45:48 +0000648 UInt ret;
sewardjde4a1d02002-03-22 01:27:54 +0000649 va_list vargs;
650 va_start(vargs,format);
651
652 n_myprintf_buf = 0;
653 myprintf_buf[n_myprintf_buf] = 0;
sewardj78e3cd92002-10-22 04:45:48 +0000654 ret = VG_(vprintf) ( add_to_myprintf_buf, format, vargs );
sewardjde4a1d02002-03-22 01:27:54 +0000655
nethercotef8548672004-06-21 12:42:35 +0000656 if (n_myprintf_buf > 0 && VG_(clo_log_fd) >= 0) {
sewardj570f8902002-11-03 11:44:36 +0000657 VG_(send_bytes_to_logging_sink)( myprintf_buf, n_myprintf_buf );
sewardj73cf3bc2002-11-03 03:20:15 +0000658 }
sewardjde4a1d02002-03-22 01:27:54 +0000659
660 va_end(vargs);
sewardj78e3cd92002-10-22 04:45:48 +0000661
662 return ret;
sewardjde4a1d02002-03-22 01:27:54 +0000663}
664
sewardjde4a1d02002-03-22 01:27:54 +0000665/* A general replacement for sprintf(). */
thughes4ad52d02004-06-27 17:37:21 +0000666
667static Char *vg_sprintf_ptr;
668
669static void add_to_vg_sprintf_buf ( Char c )
670{
671 *vg_sprintf_ptr++ = c;
672}
673
sewardj78e3cd92002-10-22 04:45:48 +0000674UInt VG_(sprintf) ( Char* buf, Char *format, ... )
sewardjde4a1d02002-03-22 01:27:54 +0000675{
sewardj05bcdcb2003-05-18 10:05:38 +0000676 Int ret;
sewardjde4a1d02002-03-22 01:27:54 +0000677 va_list vargs;
thughes4ad52d02004-06-27 17:37:21 +0000678
679 vg_sprintf_ptr = buf;
680
sewardjde4a1d02002-03-22 01:27:54 +0000681 va_start(vargs,format);
682
sewardj78e3cd92002-10-22 04:45:48 +0000683 ret = VG_(vprintf) ( add_to_vg_sprintf_buf, format, vargs );
sewardjde4a1d02002-03-22 01:27:54 +0000684 add_to_vg_sprintf_buf(0);
685
686 va_end(vargs);
sewardj78e3cd92002-10-22 04:45:48 +0000687
688 vg_assert(VG_(strlen)(buf) == ret);
689 return ret;
sewardjde4a1d02002-03-22 01:27:54 +0000690}
691
692
693/* ---------------------------------------------------------------------
694 Misc str* functions.
695 ------------------------------------------------------------------ */
696
697Bool VG_(isspace) ( Char c )
698{
699 return (c == ' ' || c == '\n' || c == '\t' || c == 0);
700}
701
njn7cf0bd32002-06-08 13:36:03 +0000702Bool VG_(isdigit) ( Char c )
703{
704 return (c >= '0' && c <= '9');
705}
sewardjde4a1d02002-03-22 01:27:54 +0000706
707Int VG_(strlen) ( const Char* str )
708{
709 Int i = 0;
710 while (str[i] != 0) i++;
711 return i;
712}
713
714
715Long VG_(atoll) ( Char* str )
716{
717 Bool neg = False;
718 Long n = 0;
719 if (*str == '-') { str++; neg = True; };
720 while (*str >= '0' && *str <= '9') {
721 n = 10*n + (Long)(*str - '0');
722 str++;
723 }
724 if (neg) n = -n;
725 return n;
726}
727
728
njn25e49d8e72002-09-23 09:36:25 +0000729Long VG_(atoll16) ( Char* str )
sewardja70ca3f2002-05-30 01:22:20 +0000730{
731 Bool neg = False;
732 Long n = 0;
733 if (*str == '-') { str++; neg = True; };
734 while (True) {
735 if (*str >= '0' && *str <= '9') {
njn25e49d8e72002-09-23 09:36:25 +0000736 n = 16*n + (Long)(*str - '0');
sewardja70ca3f2002-05-30 01:22:20 +0000737 }
738 else
njn25e49d8e72002-09-23 09:36:25 +0000739 if (*str >= 'A' && *str <= 'F') {
740 n = 16*n + (Long)((*str - 'A') + 10);
sewardja70ca3f2002-05-30 01:22:20 +0000741 }
742 else
njn25e49d8e72002-09-23 09:36:25 +0000743 if (*str >= 'a' && *str <= 'f') {
744 n = 16*n + (Long)((*str - 'a') + 10);
745 }
746 else {
747 break;
748 }
749 str++;
750 }
751 if (neg) n = -n;
752 return n;
753}
754
755Long VG_(atoll36) ( UInt base, Char* str )
756{
757 Bool neg = False;
758 Long n = 0;
759 vg_assert(base >= 2 && base <= 36);
760 if (*str == '-') { str++; neg = True; };
761 while (True) {
sewardj05bcdcb2003-05-18 10:05:38 +0000762 if (*str >= '0'
763 && *str <= (Char)('9' - (10 - base))) {
njn25e49d8e72002-09-23 09:36:25 +0000764 n = base*n + (Long)(*str - '0');
765 }
766 else
sewardj05bcdcb2003-05-18 10:05:38 +0000767 if (base > 10 && *str >= 'A'
768 && *str <= (Char)('Z' - (36 - base))) {
njn25e49d8e72002-09-23 09:36:25 +0000769 n = base*n + (Long)((*str - 'A') + 10);
770 }
771 else
sewardj05bcdcb2003-05-18 10:05:38 +0000772 if (base > 10 && *str >= 'a'
773 && *str <= (Char)('z' - (36 - base))) {
njn25e49d8e72002-09-23 09:36:25 +0000774 n = base*n + (Long)((*str - 'a') + 10);
sewardja70ca3f2002-05-30 01:22:20 +0000775 }
776 else {
777 break;
778 }
779 str++;
780 }
781 if (neg) n = -n;
782 return n;
783}
784
785
sewardjde4a1d02002-03-22 01:27:54 +0000786Char* VG_(strcat) ( Char* dest, const Char* src )
787{
788 Char* dest_orig = dest;
789 while (*dest) dest++;
790 while (*src) *dest++ = *src++;
791 *dest = 0;
792 return dest_orig;
793}
794
795
796Char* VG_(strncat) ( Char* dest, const Char* src, Int n )
797{
798 Char* dest_orig = dest;
799 while (*dest) dest++;
800 while (*src && n > 0) { *dest++ = *src++; n--; }
801 *dest = 0;
802 return dest_orig;
803}
804
805
806Char* VG_(strpbrk) ( const Char* s, const Char* accept )
807{
808 const Char* a;
809 while (*s) {
810 a = accept;
811 while (*a)
812 if (*a++ == *s)
813 return (Char *) s;
814 s++;
815 }
816 return NULL;
817}
818
819
820Char* VG_(strcpy) ( Char* dest, const Char* src )
821{
822 Char* dest_orig = dest;
823 while (*src) *dest++ = *src++;
824 *dest = 0;
825 return dest_orig;
826}
827
828
829/* Copy bytes, not overrunning the end of dest and always ensuring
830 zero termination. */
831void VG_(strncpy_safely) ( Char* dest, const Char* src, Int ndest )
832{
833 Int i;
834 vg_assert(ndest > 0);
835 i = 0;
836 dest[i] = 0;
837 while (True) {
838 if (src[i] == 0) return;
839 if (i >= ndest-1) return;
840 dest[i] = src[i];
841 i++;
842 dest[i] = 0;
843 }
844}
845
846
njn25e49d8e72002-09-23 09:36:25 +0000847Char* VG_(strncpy) ( Char* dest, const Char* src, Int ndest )
sewardjde4a1d02002-03-22 01:27:54 +0000848{
njn25e49d8e72002-09-23 09:36:25 +0000849 Int i = 0;
850 while (True) {
851 if (i >= ndest) return dest; /* reached limit */
852 dest[i] = src[i];
853 if (src[i++] == 0) {
854 /* reached NUL; pad rest with zeroes as required */
855 while (i < ndest) dest[i++] = 0;
856 return dest;
857 }
858 }
sewardjde4a1d02002-03-22 01:27:54 +0000859}
860
861
862Int VG_(strcmp) ( const Char* s1, const Char* s2 )
863{
864 while (True) {
865 if (*s1 == 0 && *s2 == 0) return 0;
866 if (*s1 == 0) return -1;
867 if (*s2 == 0) return 1;
868
869 if (*(UChar*)s1 < *(UChar*)s2) return -1;
870 if (*(UChar*)s1 > *(UChar*)s2) return 1;
871
872 s1++; s2++;
873 }
874}
875
876
877Int VG_(strcmp_ws) ( const Char* s1, const Char* s2 )
878{
879 while (True) {
880 if (VG_(isspace)(*s1) && VG_(isspace)(*s2)) return 0;
881 if (VG_(isspace)(*s1)) return -1;
882 if (VG_(isspace)(*s2)) return 1;
883
884 if (*(UChar*)s1 < *(UChar*)s2) return -1;
885 if (*(UChar*)s1 > *(UChar*)s2) return 1;
886
887 s1++; s2++;
888 }
889}
890
891
892Int VG_(strncmp) ( const Char* s1, const Char* s2, Int nmax )
893{
894 Int n = 0;
895 while (True) {
896 if (n >= nmax) return 0;
897 if (*s1 == 0 && *s2 == 0) return 0;
898 if (*s1 == 0) return -1;
899 if (*s2 == 0) return 1;
900
901 if (*(UChar*)s1 < *(UChar*)s2) return -1;
902 if (*(UChar*)s1 > *(UChar*)s2) return 1;
903
904 s1++; s2++; n++;
905 }
906}
907
908
909Int VG_(strncmp_ws) ( const Char* s1, const Char* s2, Int nmax )
910{
911 Int n = 0;
912 while (True) {
913 if (n >= nmax) return 0;
914 if (VG_(isspace)(*s1) && VG_(isspace)(*s2)) return 0;
915 if (VG_(isspace)(*s1)) return -1;
916 if (VG_(isspace)(*s2)) return 1;
917
918 if (*(UChar*)s1 < *(UChar*)s2) return -1;
919 if (*(UChar*)s1 > *(UChar*)s2) return 1;
920
921 s1++; s2++; n++;
922 }
923}
924
925
926Char* VG_(strstr) ( const Char* haystack, Char* needle )
927{
sewardj3984b852002-05-12 03:00:17 +0000928 Int n;
929 if (haystack == NULL)
930 return NULL;
931 n = VG_(strlen)(needle);
sewardjde4a1d02002-03-22 01:27:54 +0000932 while (True) {
933 if (haystack[0] == 0)
934 return NULL;
935 if (VG_(strncmp)(haystack, needle, n) == 0)
936 return (Char*)haystack;
937 haystack++;
938 }
939}
940
941
942Char* VG_(strchr) ( const Char* s, Char c )
943{
944 while (True) {
945 if (*s == c) return (Char*)s;
946 if (*s == 0) return NULL;
947 s++;
948 }
949}
950
951
thughesc0b63de2004-06-13 09:55:22 +0000952Char* VG_(strrchr) ( const Char* s, Char c )
953{
954 Int n = VG_(strlen)(s);
955 while (--n > 0) {
956 if (s[n] == c) return (Char*)s + n;
957 }
958 return NULL;
959}
960
961
sewardj7ab2aca2002-10-20 19:40:32 +0000962void* VG_(memcpy) ( void *dest, const void *src, Int sz )
963{
964 const Char *s = (const Char *)src;
965 Char *d = (Char *)dest;
966 vg_assert(sz >= 0);
967
968 while (sz--)
969 *d++ = *s++;
970
971 return dest;
972}
973
974
975void* VG_(memset) ( void *dest, Int c, Int sz )
976{
977 Char *d = (Char *)dest;
978 vg_assert(sz >= 0);
979
980 while (sz--)
981 *d++ = c;
982
983 return dest;
984}
985
njn6d68e792003-02-24 10:49:08 +0000986Int VG_(memcmp) ( const void* s1, const void* s2, Int n )
987{
988 Int res;
njnfa4690b2003-02-24 21:43:05 +0000989 UChar a0;
990 UChar b0;
njn6d68e792003-02-24 10:49:08 +0000991 vg_assert(n >= 0);
992
993 while (n != 0) {
njnfa4690b2003-02-24 21:43:05 +0000994 a0 = ((UChar *) s1)[0];
995 b0 = ((UChar *) s2)[0];
njn6d68e792003-02-24 10:49:08 +0000996 s1 += 1;
997 s2 += 1;
998 res = a0 - b0;
999 if (res != 0)
1000 return res;
1001 n -= 1;
1002 }
1003 return 0;
1004}
sewardj7ab2aca2002-10-20 19:40:32 +00001005
sewardjde4a1d02002-03-22 01:27:54 +00001006Char VG_(toupper) ( Char c )
1007{
1008 if (c >= 'a' && c <= 'z')
1009 return c + ('A' - 'a');
1010 else
1011 return c;
1012}
1013
1014
njn25e49d8e72002-09-23 09:36:25 +00001015/* Inline just for the wrapper VG_(strdup) below */
1016__inline__ Char* VG_(arena_strdup) ( ArenaId aid, const Char* s )
sewardjde4a1d02002-03-22 01:27:54 +00001017{
njn25e49d8e72002-09-23 09:36:25 +00001018 Int i;
fitzhardingea7728472003-12-16 01:48:38 +00001019 Int len;
1020 Char* res;
1021
1022 if (s == NULL)
1023 return NULL;
1024
1025 len = VG_(strlen)(s) + 1;
1026 res = VG_(arena_malloc) (aid, len);
1027
njn25e49d8e72002-09-23 09:36:25 +00001028 for (i = 0; i < len; i++)
1029 res[i] = s[i];
1030 return res;
sewardjde4a1d02002-03-22 01:27:54 +00001031}
1032
nethercote7cc9c232004-01-21 15:08:04 +00001033/* Wrapper to avoid exposing tools to ArenaId's */
njn25e49d8e72002-09-23 09:36:25 +00001034Char* VG_(strdup) ( const Char* s )
1035{
nethercote60f5b822004-01-26 17:24:42 +00001036 return VG_(arena_strdup) ( VG_AR_TOOL, s );
njn25e49d8e72002-09-23 09:36:25 +00001037}
sewardjde4a1d02002-03-22 01:27:54 +00001038
1039/* ---------------------------------------------------------------------
1040 A simple string matching routine, purloined from Hugs98.
1041 `*' matches any sequence of zero or more characters
1042 `?' matches any single character exactly
1043 `\c' matches the character c only (ignoring special chars)
1044 c matches the character c only
1045 ------------------------------------------------------------------ */
1046
1047/* Keep track of recursion depth. */
1048static Int recDepth;
1049
fitzhardinge98abfc72003-12-16 02:05:15 +00001050static Bool string_match_wrk ( const Char* pat, const Char* str )
sewardjde4a1d02002-03-22 01:27:54 +00001051{
sewardje54b69d2003-07-06 01:14:42 +00001052 vg_assert(recDepth >= 0 && recDepth < 500);
sewardjde4a1d02002-03-22 01:27:54 +00001053 recDepth++;
1054 for (;;) {
1055 switch (*pat) {
1056 case '\0' : return (*str=='\0');
1057 case '*' : do {
njn4ba5a792002-09-30 10:23:54 +00001058 if (string_match_wrk(pat+1,str)) {
sewardjde4a1d02002-03-22 01:27:54 +00001059 recDepth--;
1060 return True;
1061 }
1062 } while (*str++);
1063 recDepth--;
1064 return False;
1065 case '?' : if (*str++=='\0') {
1066 recDepth--;
1067 return False;
1068 }
1069 pat++;
1070 break;
1071 case '\\' : if (*++pat == '\0') {
1072 recDepth--;
1073 return False; /* spurious trailing \ in pattern */
1074 }
1075 /* falls through to ... */
1076 default : if (*pat++ != *str++) {
1077 recDepth--;
1078 return False;
1079 }
1080 break;
1081 }
1082 }
1083}
1084
fitzhardinge98abfc72003-12-16 02:05:15 +00001085Bool VG_(string_match) ( const Char* pat, const Char* str )
sewardjde4a1d02002-03-22 01:27:54 +00001086{
1087 Bool b;
1088 recDepth = 0;
njn4ba5a792002-09-30 10:23:54 +00001089 b = string_match_wrk ( pat, str );
sewardjde4a1d02002-03-22 01:27:54 +00001090 /*
1091 VG_(printf)("%s %s %s\n",
1092 b?"TRUE ":"FALSE", pat, str);
1093 */
1094 return b;
1095}
1096
1097
1098/* ---------------------------------------------------------------------
1099 Assertery.
1100 ------------------------------------------------------------------ */
1101
jsgf855d93d2003-10-13 22:26:55 +00001102/* Fake up an ExeContext which is of our actual real CPU state, so we
1103 can print a stack trace. This isn't terribly useful in the case
1104 where we were killed by a signal, since we just get a backtrace
1105 into the signal handler. Also, it could be somewhat risky if we
1106 actully got the panic/exception within the execontext/stack
1107 dump/symtab code. But it's better than nothing. */
1108static inline ExeContext *get_real_execontext(Addr ret)
1109{
1110 ExeContext *ec;
nethercote856e5872004-10-25 20:44:09 +00001111 Addr sp, fp;
nethercote759dda32004-08-07 18:16:56 +00001112 Addr stacktop, sigstack_low, sigstack_high;
jsgf855d93d2003-10-13 22:26:55 +00001113
nethercote856e5872004-10-25 20:44:09 +00001114 ARCH_GET_REAL_STACK_PTR(sp);
1115 ARCH_GET_REAL_FRAME_PTR(fp);
nethercote820bd8c2004-09-07 23:04:49 +00001116 stacktop = VG_(valgrind_last);
nethercote759dda32004-08-07 18:16:56 +00001117 VG_(get_sigstack_bounds)( &sigstack_low, &sigstack_high );
nethercote856e5872004-10-25 20:44:09 +00001118 if (sp >= sigstack_low && sp < sigstack_high)
nethercote759dda32004-08-07 18:16:56 +00001119 stacktop = sigstack_high;
jsgf855d93d2003-10-13 22:26:55 +00001120
nethercote856e5872004-10-25 20:44:09 +00001121 ec = VG_(get_ExeContext2)(ret, fp, sp, stacktop);
jsgf855d93d2003-10-13 22:26:55 +00001122
1123 return ec;
1124}
1125
njne427a662002-10-02 11:08:25 +00001126__attribute__ ((noreturn))
thughes5876d552004-09-26 18:44:06 +00001127static void report_and_quit ( const Char* report, ExeContext *ec )
njne427a662002-10-02 11:08:25 +00001128{
thughes5876d552004-09-26 18:44:06 +00001129 if (ec == NULL)
1130 ec = get_real_execontext((Addr)__builtin_return_address(0));
1131
jsgf855d93d2003-10-13 22:26:55 +00001132 VG_(pp_ExeContext)(ec);
1133
njne427a662002-10-02 11:08:25 +00001134 VG_(pp_sched_status)();
sewardj366ee1e2003-04-26 22:36:42 +00001135 VG_(printf)("\n");
1136 VG_(printf)("Note: see also the FAQ.txt in the source distribution.\n");
1137 VG_(printf)("It contains workarounds to several common problems.\n");
1138 VG_(printf)("\n");
1139 VG_(printf)("If that doesn't help, please report this bug to: %s\n\n",
1140 report);
1141 VG_(printf)("In the bug report, send all the above text, the valgrind\n");
sewardj96330bd2003-04-27 23:46:21 +00001142 VG_(printf)("version, and what Linux distro you are using. Thanks.\n\n");
njne427a662002-10-02 11:08:25 +00001143 VG_(exit)(1);
1144}
1145
1146__attribute__ ((noreturn))
daywalker3222e0a2003-09-18 01:39:50 +00001147static void assert_fail ( const Char* expr, const Char* name, const Char* report,
1148 const Char* file, Int line, const Char* fn )
sewardjde4a1d02002-03-22 01:27:54 +00001149{
sewardj018f7622002-05-15 21:13:39 +00001150 static Bool entered = False;
1151 if (entered)
1152 VG_(exit)(2);
1153 entered = True;
sewardjde4a1d02002-03-22 01:27:54 +00001154 VG_(printf)("\n%s: %s:%d (%s): Assertion `%s' failed.\n",
njne427a662002-10-02 11:08:25 +00001155 name, file, line, fn, expr );
thughes5876d552004-09-26 18:44:06 +00001156 report_and_quit(report, NULL);
sewardjde4a1d02002-03-22 01:27:54 +00001157}
1158
daywalker3222e0a2003-09-18 01:39:50 +00001159void VG_(skin_assert_fail) ( const Char* expr, const Char* file, Int line, const Char* fn )
sewardjde4a1d02002-03-22 01:27:54 +00001160{
njnd04b7c62002-10-03 14:05:52 +00001161 assert_fail(expr, VG_(details).name, VG_(details).bug_reports_to,
njne427a662002-10-02 11:08:25 +00001162 file, line, fn);
1163}
1164
daywalker3222e0a2003-09-18 01:39:50 +00001165void VG_(core_assert_fail) ( const Char* expr, const Char* file, Int line, const Char* fn )
njne427a662002-10-02 11:08:25 +00001166{
nethercote421281e2003-11-20 16:20:55 +00001167 assert_fail(expr, "valgrind", VG_BUGS_TO, file, line, fn);
njne427a662002-10-02 11:08:25 +00001168}
1169
1170__attribute__ ((noreturn))
thughes671ce382004-09-27 18:57:08 +00001171static void panic ( Char* name, Char* report, Char* str, ExeContext *ec )
njne427a662002-10-02 11:08:25 +00001172{
1173 VG_(printf)("\n%s: the `impossible' happened:\n %s\n", name, str);
sewardjde4a1d02002-03-22 01:27:54 +00001174 VG_(printf)("Basic block ctr is approximately %llu\n", VG_(bbs_done) );
thughes671ce382004-09-27 18:57:08 +00001175 report_and_quit(report, ec);
sewardjde4a1d02002-03-22 01:27:54 +00001176}
1177
njne427a662002-10-02 11:08:25 +00001178void VG_(core_panic) ( Char* str )
njn25e49d8e72002-09-23 09:36:25 +00001179{
thughes5876d552004-09-26 18:44:06 +00001180 panic("valgrind", VG_BUGS_TO, str, NULL);
1181}
1182
1183void VG_(core_panic_at) ( Char* str, ExeContext *ec )
1184{
1185 panic("valgrind", VG_BUGS_TO, str, ec);
njn25e49d8e72002-09-23 09:36:25 +00001186}
1187
njne427a662002-10-02 11:08:25 +00001188void VG_(skin_panic) ( Char* str )
1189{
thughes5876d552004-09-26 18:44:06 +00001190 panic(VG_(details).name, VG_(details).bug_reports_to, str, NULL);
njne427a662002-10-02 11:08:25 +00001191}
sewardjde4a1d02002-03-22 01:27:54 +00001192
njn13f02932003-04-30 20:23:58 +00001193
sewardjde4a1d02002-03-22 01:27:54 +00001194/* ---------------------------------------------------------------------
1195 Primitive support for reading files.
1196 ------------------------------------------------------------------ */
1197
jsgf855d93d2003-10-13 22:26:55 +00001198static inline Bool fd_exists(Int fd)
1199{
1200 struct vki_stat st;
1201
1202 return VG_(fstat)(fd, &st) == 0;
1203}
1204
1205/* Move an fd into the Valgrind-safe range */
1206Int VG_(safe_fd)(Int oldfd)
1207{
1208 Int newfd;
1209
thughesad1c9562004-06-26 11:27:52 +00001210 vg_assert(VG_(fd_hard_limit) != -1);
fitzhardingeb791a192003-12-18 07:22:44 +00001211
thughesad1c9562004-06-26 11:27:52 +00001212 newfd = VG_(fcntl)(oldfd, VKI_F_DUPFD, VG_(fd_hard_limit));
jsgf855d93d2003-10-13 22:26:55 +00001213 if (newfd != -1)
1214 VG_(close)(oldfd);
1215
1216 VG_(fcntl)(newfd, VKI_F_SETFD, VKI_FD_CLOEXEC);
1217
thughesad1c9562004-06-26 11:27:52 +00001218 vg_assert(newfd >= VG_(fd_hard_limit));
jsgf855d93d2003-10-13 22:26:55 +00001219 return newfd;
1220}
1221
1222
1223
sewardjde4a1d02002-03-22 01:27:54 +00001224/* Returns -1 on failure. */
njn25e49d8e72002-09-23 09:36:25 +00001225Int VG_(open) ( const Char* pathname, Int flags, Int mode )
1226{
sewardjde4a1d02002-03-22 01:27:54 +00001227 Int fd;
sewardjde4a1d02002-03-22 01:27:54 +00001228
njn25e49d8e72002-09-23 09:36:25 +00001229 /* (old comment, not sure if it still applies NJN 2002-sep-09) */
sewardjde4a1d02002-03-22 01:27:54 +00001230 /* This gets a segmentation fault if pathname isn't a valid file.
1231 I don't know why. It seems like the call to open is getting
1232 intercepted and messed with by glibc ... */
1233 /* fd = open( pathname, O_RDONLY ); */
1234 /* ... so we go direct to the horse's mouth, which seems to work
1235 ok: */
jsgf855d93d2003-10-13 22:26:55 +00001236 fd = VG_(do_syscall)(__NR_open, (UInt)pathname, flags, mode);
njn4f9c9342002-04-29 16:03:24 +00001237 /* VG_(printf)("result = %d\n", fd); */
jsgff3c3f1a2003-10-14 22:13:28 +00001238 /* return -ve error code */
njn4f9c9342002-04-29 16:03:24 +00001239 return fd;
1240}
sewardjde4a1d02002-03-22 01:27:54 +00001241
jsgf855d93d2003-10-13 22:26:55 +00001242Int VG_(pipe) ( Int fd[2] )
1243{
1244 Int ret = VG_(do_syscall)(__NR_pipe, fd);
1245 return VG_(is_kerror)(ret) ? -1 : 0;
1246}
1247
sewardjde4a1d02002-03-22 01:27:54 +00001248void VG_(close) ( Int fd )
1249{
jsgf855d93d2003-10-13 22:26:55 +00001250 VG_(do_syscall)(__NR_close, fd);
sewardjde4a1d02002-03-22 01:27:54 +00001251}
1252
1253
1254Int VG_(read) ( Int fd, void* buf, Int count)
1255{
1256 Int res;
1257 /* res = read( fd, buf, count ); */
jsgf855d93d2003-10-13 22:26:55 +00001258 res = VG_(do_syscall)(__NR_read, fd, (UInt)buf, count);
1259 /* return -ERRNO on error */
sewardjde4a1d02002-03-22 01:27:54 +00001260 return res;
1261}
1262
jsgf855d93d2003-10-13 22:26:55 +00001263Int VG_(write) ( Int fd, const void* buf, Int count)
sewardjde4a1d02002-03-22 01:27:54 +00001264{
1265 Int res;
1266 /* res = write( fd, buf, count ); */
jsgf855d93d2003-10-13 22:26:55 +00001267 res = VG_(do_syscall)(__NR_write, fd, (UInt)buf, count);
1268 /* return -ERRNO on error */
sewardjde4a1d02002-03-22 01:27:54 +00001269 return res;
1270}
1271
rjwalshf5f536f2003-11-17 17:45:00 +00001272Int VG_(lseek) ( Int fd, Long offset, Int whence)
1273{
1274 Int res;
1275 /* res = lseek( fd, offset, whence ); */
1276 res = VG_(do_syscall)(__NR_lseek, fd, (UInt)offset, whence);
1277 if (VG_(is_kerror)(res)) res = -1;
1278 return res;
1279}
1280
sewardjb3586202002-05-09 17:38:13 +00001281Int VG_(stat) ( Char* file_name, struct vki_stat* buf )
1282{
1283 Int res;
jsgf855d93d2003-10-13 22:26:55 +00001284 res = VG_(do_syscall)(__NR_stat, (UInt)file_name, (UInt)buf);
fitzhardingee1c06d82003-10-30 07:21:44 +00001285 return res; /* return -ve error */
njn41557122002-10-14 09:25:37 +00001286}
1287
jsgf855d93d2003-10-13 22:26:55 +00001288Int VG_(fstat) ( Int fd, struct vki_stat* buf )
1289{
1290 Int res;
1291 res = VG_(do_syscall)(__NR_fstat, (UInt)fd, (UInt)buf);
1292 return VG_(is_kerror)(res) ? (-1) : 0;
1293}
1294
1295Int VG_(dup2) ( Int oldfd, Int newfd )
1296{
1297 Int res;
1298 res = VG_(do_syscall)(__NR_dup2, (UInt)oldfd, (UInt)newfd);
1299 return VG_(is_kerror)(res) ? (-1) : res;
1300}
1301
njn41557122002-10-14 09:25:37 +00001302Int VG_(rename) ( Char* old_name, Char* new_name )
1303{
1304 Int res;
jsgf855d93d2003-10-13 22:26:55 +00001305 res = VG_(do_syscall)(__NR_rename, (UInt)old_name, (UInt)new_name);
njn41557122002-10-14 09:25:37 +00001306 return VG_(is_kerror)(res) ? (-1) : 0;
sewardjb3586202002-05-09 17:38:13 +00001307}
1308
njn4aca2d22002-10-04 10:29:38 +00001309Int VG_(unlink) ( Char* file_name )
1310{
1311 Int res;
jsgf855d93d2003-10-13 22:26:55 +00001312 res = VG_(do_syscall)(__NR_unlink, (UInt)file_name);
njn41557122002-10-14 09:25:37 +00001313 return VG_(is_kerror)(res) ? (-1) : 0;
njn4aca2d22002-10-04 10:29:38 +00001314}
1315
njn13f02932003-04-30 20:23:58 +00001316/* Nb: we do not allow the Linux extension which malloc()s memory for the
1317 buffer if buf==NULL, because we don't want Linux calling malloc() */
1318Char* VG_(getcwd) ( Char* buf, Int size )
1319{
1320 Int res;
1321 vg_assert(buf != NULL);
jsgf855d93d2003-10-13 22:26:55 +00001322 res = VG_(do_syscall)(__NR_getcwd, (UInt)buf, (UInt)size);
njn13f02932003-04-30 20:23:58 +00001323 return VG_(is_kerror)(res) ? ((Char*)NULL) : (Char*)res;
1324}
1325
njn99ccf082003-09-30 13:51:23 +00001326/* Alternative version that does allocate the memory. Easier to use. */
1327Bool VG_(getcwd_alloc) ( Char** out )
1328{
1329 UInt size = 4;
1330
1331 *out = NULL;
1332 while (True) {
1333 *out = VG_(malloc)(size);
1334 if (NULL == VG_(getcwd)(*out, size)) {
1335 VG_(free)(*out);
1336 if (size > 65535)
1337 return False;
1338 size *= 2;
1339 } else {
1340 return True;
1341 }
1342 }
1343}
1344
njn13f02932003-04-30 20:23:58 +00001345
1346/* ---------------------------------------------------------------------
1347 Misc functions looking for a proper home.
1348 ------------------------------------------------------------------ */
sewardjde4a1d02002-03-22 01:27:54 +00001349
nethercoteff9721d2004-01-26 17:10:01 +00001350/* clone the environment */
nethercote85cdd342004-08-01 22:36:40 +00001351static Char **env_clone ( Char **oldenv )
nethercoteff9721d2004-01-26 17:10:01 +00001352{
1353 Char **oldenvp;
1354 Char **newenvp;
1355 Char **newenv;
1356 Int envlen;
1357
1358 for (oldenvp = oldenv; oldenvp && *oldenvp; oldenvp++);
1359
1360 envlen = oldenvp - oldenv + 1;
1361
1362 newenv = VG_(arena_malloc)(VG_AR_CORE, envlen * sizeof(Char **));
1363
1364 oldenvp = oldenv;
1365 newenvp = newenv;
1366
1367 while (oldenvp && *oldenvp) {
1368 *newenvp++ = *oldenvp++;
1369 }
1370
1371 *newenvp = *oldenvp;
1372
1373 return newenv;
1374}
1375
fitzhardinge98abfc72003-12-16 02:05:15 +00001376void VG_(env_unsetenv) ( Char **env, const Char *varname )
1377{
1378 Char **from;
1379 Char **to = NULL;
1380 Int len = VG_(strlen)(varname);
1381
1382 for(from = to = env; from && *from; from++) {
1383 if (!(VG_(strncmp)(varname, *from, len) == 0 && (*from)[len] == '=')) {
1384 *to = *from;
1385 to++;
1386 }
1387 }
1388 *to = *from;
1389}
1390
1391/* set the environment; returns the old env if a new one was allocated */
1392Char **VG_(env_setenv) ( Char ***envp, const Char* varname, const Char *val )
1393{
1394 Char **env = (*envp);
1395 Char **cpp;
1396 Int len = VG_(strlen)(varname);
1397 Char *valstr = VG_(arena_malloc)(VG_AR_CORE, len + VG_(strlen)(val) + 2);
1398 Char **oldenv = NULL;
1399
1400 VG_(sprintf)(valstr, "%s=%s", varname, val);
1401
1402 for(cpp = env; cpp && *cpp; cpp++) {
1403 if (VG_(strncmp)(varname, *cpp, len) == 0 && (*cpp)[len] == '=') {
1404 *cpp = valstr;
1405 return oldenv;
1406 }
1407 }
1408
1409 if (env == NULL) {
1410 env = VG_(arena_malloc)(VG_AR_CORE, sizeof(Char **) * 2);
1411 env[0] = valstr;
1412 env[1] = NULL;
1413
1414 *envp = env;
1415
1416 } else {
1417 Int envlen = (cpp-env) + 2;
1418 Char **newenv = VG_(arena_malloc)(VG_AR_CORE, envlen * sizeof(Char **));
1419
1420 for(cpp = newenv; *env; )
1421 *cpp++ = *env++;
1422 *cpp++ = valstr;
1423 *cpp++ = NULL;
1424
1425 oldenv = *envp;
1426
1427 *envp = newenv;
1428 }
1429
1430 return oldenv;
1431}
1432
nethercote85cdd342004-08-01 22:36:40 +00001433/* We do getenv without libc's help by snooping around in
1434 VG_(client_envp) as determined at startup time. */
1435Char *VG_(getenv)(Char *varname)
sewardjde4a1d02002-03-22 01:27:54 +00001436{
1437 Int i, n;
1438 n = VG_(strlen)(varname);
nethercote85cdd342004-08-01 22:36:40 +00001439 for (i = 0; VG_(client_envp)[i] != NULL; i++) {
1440 Char* s = VG_(client_envp)[i];
sewardjde4a1d02002-03-22 01:27:54 +00001441 if (VG_(strncmp)(varname, s, n) == 0 && s[n] == '=') {
1442 return & s[n+1];
1443 }
1444 }
1445 return NULL;
1446}
1447
rjwalshf5f536f2003-11-17 17:45:00 +00001448/* Support for getrlimit. */
1449Int VG_(getrlimit) (Int resource, struct vki_rlimit *rlim)
1450{
1451 Int res;
1452 /* res = getrlimit( resource, rlim ); */
1453 res = VG_(do_syscall)(__NR_getrlimit, (UInt)resource, (UInt)rlim);
1454 if(VG_(is_kerror)(res)) res = -1;
1455 return res;
1456}
1457
1458
fitzhardingef0046f22003-12-18 02:39:22 +00001459/* Support for setrlimit. */
1460Int VG_(setrlimit) (Int resource, struct vki_rlimit *rlim)
1461{
1462 Int res;
1463 /* res = setrlimit( resource, rlim ); */
1464 res = VG_(do_syscall)(__NR_setrlimit, (UInt)resource, (UInt)rlim);
1465 if(VG_(is_kerror)(res)) res = -1;
1466 return res;
1467}
1468
1469
rjwalshf5f536f2003-11-17 17:45:00 +00001470/* Support for getdents. */
1471Int VG_(getdents) (UInt fd, struct vki_dirent *dirp, UInt count)
1472{
1473 Int res;
1474 /* res = getdents( fd, dirp, count ); */
1475 res = VG_(do_syscall)(__NR_getdents, fd, (UInt)dirp, count);
1476 if (VG_(is_kerror)(res)) res = -1;
1477 return res;
1478}
1479
1480/* Support for a readlink. */
1481Int VG_(readlink) (Char* path, Char* buf, UInt bufsiz)
1482{
1483 Int res;
1484 /* res = readlink( path, buf, bufsiz ); */
1485 res = VG_(do_syscall)(__NR_readlink, (UInt)path, (UInt)buf, bufsiz);
1486 if (VG_(is_kerror)(res)) res = -1;
1487 return res;
1488}
1489
sewardjde4a1d02002-03-22 01:27:54 +00001490/* You'd be amazed how many places need to know the current pid. */
1491Int VG_(getpid) ( void )
1492{
1493 Int res;
1494 /* res = getpid(); */
jsgf855d93d2003-10-13 22:26:55 +00001495 res = VG_(do_syscall)(__NR_getpid);
1496 return res;
1497}
1498
1499Int VG_(getpgrp) ( void )
1500{
1501 Int res;
1502 /* res = getpgid(); */
1503 res = VG_(do_syscall)(__NR_getpgrp);
sewardjde4a1d02002-03-22 01:27:54 +00001504 return res;
1505}
1506
sewardj4cf05692002-10-27 20:28:29 +00001507Int VG_(getppid) ( void )
1508{
1509 Int res;
jsgf855d93d2003-10-13 22:26:55 +00001510 res = VG_(do_syscall)(__NR_getppid);
sewardj4cf05692002-10-27 20:28:29 +00001511 return res;
1512}
1513
jsgf855d93d2003-10-13 22:26:55 +00001514Int VG_(setpgid) ( Int pid, Int pgrp )
1515{
1516 return VG_(do_syscall)(__NR_setpgid, pid, pgrp);
1517}
sewardj4cf05692002-10-27 20:28:29 +00001518
nethercote60a96c52004-08-03 13:08:31 +00001519/* Walk through a colon-separated environment variable, and remove the
1520 entries which match remove_pattern. It slides everything down over
1521 the removed entries, and pads the remaining space with '\0'. It
1522 modifies the entries in place (in the client address space), but it
1523 shouldn't matter too much, since we only do this just before an
1524 execve().
1525
1526 This is also careful to mop up any excess ':'s, since empty strings
1527 delimited by ':' are considered to be '.' in a path.
1528*/
1529static void mash_colon_env(Char *varp, const Char *remove_pattern)
1530{
1531 Char *const start = varp;
1532 Char *entry_start = varp;
1533 Char *output = varp;
1534
1535 if (varp == NULL)
1536 return;
1537
1538 while(*varp) {
1539 if (*varp == ':') {
1540 Char prev;
1541 Bool match;
1542
1543 /* This is a bit subtle: we want to match against the entry
1544 we just copied, because it may have overlapped with
1545 itself, junking the original. */
1546
1547 prev = *output;
1548 *output = '\0';
1549
1550 match = VG_(string_match)(remove_pattern, entry_start);
1551
1552 *output = prev;
1553
1554 if (match) {
1555 output = entry_start;
1556 varp++; /* skip ':' after removed entry */
1557 } else
1558 entry_start = output+1; /* entry starts after ':' */
1559 }
1560
1561 *output++ = *varp++;
1562 }
1563
1564 /* match against the last entry */
1565 if (VG_(string_match)(remove_pattern, entry_start)) {
1566 output = entry_start;
1567 if (output > start) {
1568 /* remove trailing ':' */
1569 output--;
1570 vg_assert(*output == ':');
1571 }
1572 }
1573
1574 /* pad out the left-overs with '\0' */
1575 while(output < varp)
1576 *output++ = '\0';
1577}
1578
1579
1580// Removes all the Valgrind-added stuff from the passed environment. Used
1581// when starting child processes, so they don't see that added stuff.
1582void VG_(env_remove_valgrind_env_stuff)(Char** envp)
1583{
1584 Int i;
1585 Char* ld_preload_str = NULL;
1586 Char* ld_library_path_str = NULL;
1587 Char* buf;
1588
1589 // Find LD_* variables
1590 for (i = 0; envp[i] != NULL; i++) {
1591 if (VG_(strncmp)(envp[i], "LD_PRELOAD=", 11) == 0)
1592 ld_preload_str = &envp[i][11];
1593 if (VG_(strncmp)(envp[i], "LD_LIBRARY_PATH=", 16) == 0)
1594 ld_library_path_str = &envp[i][16];
1595 }
1596
1597 buf = VG_(arena_malloc)(VG_AR_CORE, VG_(strlen)(VG_(libdir)) + 20);
1598
1599 // Remove Valgrind-specific entries from LD_*.
1600 VG_(sprintf)(buf, "%s*/vg_inject.so", VG_(libdir));
1601 mash_colon_env(ld_preload_str, buf);
1602 VG_(sprintf)(buf, "%s*/vgpreload_*.so", VG_(libdir));
1603 mash_colon_env(ld_preload_str, buf);
1604 VG_(sprintf)(buf, "%s*", VG_(libdir));
1605 mash_colon_env(ld_library_path_str, buf);
1606
1607 // Remove VALGRIND_CLO variable.
1608 VG_(env_unsetenv)(envp, VALGRINDCLO);
1609
1610 // XXX if variable becomes empty, remove it completely?
1611
1612 VG_(arena_free)(VG_AR_CORE, buf);
1613}
1614
sewardje6a25242002-04-21 22:03:07 +00001615/* Return -1 if error, else 0. NOTE does not indicate return code of
1616 child! */
1617Int VG_(system) ( Char* cmd )
1618{
1619 Int pid, res;
sewardje6a25242002-04-21 22:03:07 +00001620 if (cmd == NULL)
1621 return 1;
jsgf855d93d2003-10-13 22:26:55 +00001622 pid = VG_(do_syscall)(__NR_fork);
sewardje6a25242002-04-21 22:03:07 +00001623 if (VG_(is_kerror)(pid))
1624 return -1;
1625 if (pid == 0) {
1626 /* child */
nethercoteff9721d2004-01-26 17:10:01 +00001627 static Char** envp = NULL;
sewardje6a25242002-04-21 22:03:07 +00001628 Char* argv[4];
nethercoteff9721d2004-01-26 17:10:01 +00001629
fitzhardingeb50068f2004-02-24 23:42:55 +00001630 /* restore the DATA rlimit for the child */
1631 VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
1632
nethercote60a96c52004-08-03 13:08:31 +00001633 envp = env_clone(VG_(client_envp));
1634 VG_(env_remove_valgrind_env_stuff)( envp );
nethercoteff9721d2004-01-26 17:10:01 +00001635
sewardje6a25242002-04-21 22:03:07 +00001636 argv[0] = "/bin/sh";
1637 argv[1] = "-c";
1638 argv[2] = cmd;
1639 argv[3] = 0;
nethercoteff9721d2004-01-26 17:10:01 +00001640
jsgf855d93d2003-10-13 22:26:55 +00001641 (void)VG_(do_syscall)(__NR_execve,
nethercoteff9721d2004-01-26 17:10:01 +00001642 (UInt)"/bin/sh", (UInt)argv, (UInt)envp);
1643
sewardje6a25242002-04-21 22:03:07 +00001644 /* If we're still alive here, execve failed. */
fitzhardingeabab8392004-03-02 21:38:51 +00001645 VG_(exit)(1);
sewardje6a25242002-04-21 22:03:07 +00001646 } else {
1647 /* parent */
fitzhardingeabab8392004-03-02 21:38:51 +00001648 res = VG_(waitpid)(pid, NULL, 0);
sewardje6a25242002-04-21 22:03:07 +00001649 if (VG_(is_kerror)(res)) {
1650 return -1;
1651 } else {
fitzhardingeabab8392004-03-02 21:38:51 +00001652 return 0;
sewardje6a25242002-04-21 22:03:07 +00001653 }
1654 }
1655}
1656
1657
sewardjde4a1d02002-03-22 01:27:54 +00001658/* ---------------------------------------------------------------------
fitzhardinge66871692004-01-25 03:32:58 +00001659 Support for a millisecond-granularity timer.
sewardj5f07b662002-04-23 16:52:51 +00001660 ------------------------------------------------------------------ */
1661
sewardj5f07b662002-04-23 16:52:51 +00001662UInt VG_(read_millisecond_timer) ( void )
1663{
fitzhardinge426f9e62004-01-25 03:44:18 +00001664 static ULong base = 0;
fitzhardinge66871692004-01-25 03:32:58 +00001665 struct vki_timeval tv_now;
1666 ULong now;
sewardj5f07b662002-04-23 16:52:51 +00001667 Int res;
sewardj5f07b662002-04-23 16:52:51 +00001668
fitzhardinge66871692004-01-25 03:32:58 +00001669 res = VG_(do_syscall)(__NR_gettimeofday, (UInt)&tv_now,
1670 (UInt)NULL);
sewardj5f07b662002-04-23 16:52:51 +00001671
fitzhardinge66871692004-01-25 03:32:58 +00001672 now = tv_now.tv_sec * 1000000ULL + tv_now.tv_usec;
1673
1674 if (base == 0)
1675 base = now;
sewardj5f07b662002-04-23 16:52:51 +00001676
fitzhardinge66871692004-01-25 03:32:58 +00001677 return (now - base) / 1000;
sewardj5f07b662002-04-23 16:52:51 +00001678}
1679
1680
sewardj5f07b662002-04-23 16:52:51 +00001681/* ---------------------------------------------------------------------
sewardjde4a1d02002-03-22 01:27:54 +00001682 Primitive support for bagging memory via mmap.
1683 ------------------------------------------------------------------ */
1684
nethercote8b5f40c2004-11-02 13:29:50 +00001685void* VG_(get_memory_from_mmap) ( SizeT nBytes, Char* who )
sewardjde4a1d02002-03-22 01:27:54 +00001686{
nethercote8b5f40c2004-11-02 13:29:50 +00001687 static SizeT tot_alloc = 0;
sewardj7c2020b2002-09-30 22:56:03 +00001688 void* p;
nethercotec314eba2004-07-15 12:59:41 +00001689 p = VG_(mmap)(0, nBytes,
1690 VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC,
1691 VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS, 0, -1, 0);
fitzhardinge98abfc72003-12-16 02:05:15 +00001692
sewardjde4a1d02002-03-22 01:27:54 +00001693 if (p != ((void*)(-1))) {
nethercotefb583e22004-09-07 23:15:37 +00001694 vg_assert((void*)VG_(valgrind_base) <= p && p <= (void*)VG_(valgrind_last));
sewardjde4a1d02002-03-22 01:27:54 +00001695 tot_alloc += (UInt)nBytes;
1696 if (0)
sewardje9047952002-06-05 20:28:33 +00001697 VG_(printf)(
nethercote8b5f40c2004-11-02 13:29:50 +00001698 "get_memory_from_mmap: %llu tot, %llu req = %p .. %p, caller %s\n",
1699 (ULong)tot_alloc, (ULong)nBytes, p, ((char*)p) + nBytes - 1, who );
sewardjde4a1d02002-03-22 01:27:54 +00001700 return p;
1701 }
sewardj7c2020b2002-09-30 22:56:03 +00001702
njn25e49d8e72002-09-23 09:36:25 +00001703 VG_(printf)("\n");
nethercote8b5f40c2004-11-02 13:29:50 +00001704 VG_(printf)("VG_(get_memory_from_mmap): %s's request for %llu bytes failed.\n",
1705 who, (ULong)nBytes);
1706 VG_(printf)("VG_(get_memory_from_mmap): %llu bytes already allocated.\n",
1707 (ULong)tot_alloc);
njn25e49d8e72002-09-23 09:36:25 +00001708 VG_(printf)("\n");
nethercotee757d6e2004-07-10 16:17:52 +00001709 VG_(printf)("Sorry. You could try using a tool that uses less memory;\n");
1710 VG_(printf)("eg. addrcheck instead of memcheck.\n");
njn25e49d8e72002-09-23 09:36:25 +00001711 VG_(printf)("\n");
1712 VG_(exit)(1);
sewardjde4a1d02002-03-22 01:27:54 +00001713}
1714
njn25e49d8e72002-09-23 09:36:25 +00001715/* ---------------------------------------------------------------------
1716 Generally useful...
1717 ------------------------------------------------------------------ */
1718
1719Int VG_(log2) ( Int x )
1720{
1721 Int i;
1722 /* Any more than 32 and we overflow anyway... */
1723 for (i = 0; i < 32; i++) {
1724 if (1 << i == x) return i;
1725 }
1726 return -1;
1727}
1728
1729
njnd3b0c5f2003-09-30 14:43:54 +00001730// Generic shell sort. Like stdlib.h's qsort().
1731void VG_(ssort)( void* base, UInt nmemb, UInt size,
1732 Int (*compar)(void*, void*) )
1733{
1734 Int incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
1735 9841, 29524, 88573, 265720,
1736 797161, 2391484 };
1737 Int lo = 0;
1738 Int hi = nmemb-1;
1739 Int i, j, h, bigN, hp;
1740
1741 bigN = hi - lo + 1; if (bigN < 2) return;
1742 hp = 0; while (hp < 14 && incs[hp] < bigN) hp++; hp--;
1743 vg_assert(0 <= hp && hp < 14);
1744
1745 #define SORT \
1746 for ( ; hp >= 0; hp--) { \
1747 h = incs[hp]; \
njn92c54362003-10-15 14:00:35 +00001748 for (i = lo + h; i <= hi; i++) { \
njnd3b0c5f2003-09-30 14:43:54 +00001749 ASSIGN(v,0, a,i); \
1750 j = i; \
njn92c54362003-10-15 14:00:35 +00001751 while (COMPAR(a,(j-h), v,0) > 0) { \
njnd3b0c5f2003-09-30 14:43:54 +00001752 ASSIGN(a,j, a,(j-h)); \
1753 j = j - h; \
1754 if (j <= (lo + h - 1)) break; \
1755 } \
1756 ASSIGN(a,j, v,0); \
njnd3b0c5f2003-09-30 14:43:54 +00001757 } \
1758 }
1759
1760 // Specialised cases
1761 if (sizeof(UInt) == size) {
1762
1763 #define ASSIGN(dst, dsti, src, srci) \
1764 (dst)[(dsti)] = (src)[(srci)];
1765
1766 #define COMPAR(dst, dsti, src, srci) \
1767 compar( (void*)(& (dst)[(dsti)]), (void*)(& (src)[(srci)]) )
1768
1769 UInt* a = (UInt*)base;
1770 UInt v[1];
1771
1772 SORT;
1773
1774 } else if (sizeof(UShort) == size) {
1775 UShort* a = (UShort*)base;
1776 UShort v[1];
1777
1778 SORT;
1779
1780 } else if (sizeof(UChar) == size) {
1781 UChar* a = (UChar*)base;
1782 UChar v[1];
1783
1784 SORT;
1785
1786 #undef ASSIGN
1787 #undef COMPAR
1788
1789 // General case
1790 } else {
njn92c54362003-10-15 14:00:35 +00001791 char* a = base;
1792 char v[size]; // will be at least 'size' bytes
njnd3b0c5f2003-09-30 14:43:54 +00001793
1794 #define ASSIGN(dst, dsti, src, srci) \
njn92c54362003-10-15 14:00:35 +00001795 VG_(memcpy)( &dst[size*(dsti)], &src[size*(srci)], size );
njnd3b0c5f2003-09-30 14:43:54 +00001796
1797 #define COMPAR(dst, dsti, src, srci) \
njn92c54362003-10-15 14:00:35 +00001798 compar( &dst[size*(dsti)], &src[size*(srci)] )
njnd3b0c5f2003-09-30 14:43:54 +00001799
1800 SORT;
1801
1802 #undef ASSIGN
1803 #undef COMPAR
1804 }
1805 #undef SORT
1806}
1807
sewardj73cf3bc2002-11-03 03:20:15 +00001808/* ---------------------------------------------------------------------
1809 Gruesome hackery for connecting to a logging server over the network.
1810 This is all very Linux-kernel specific.
1811 ------------------------------------------------------------------ */
1812
sewardj73cf3bc2002-11-03 03:20:15 +00001813static
1814Int parse_inet_addr_and_port ( UChar* str, UInt* ip_addr, UShort* port );
1815
1816static
1817Int my_socket ( Int domain, Int type, Int protocol );
1818
1819static
1820Int my_connect ( Int sockfd, struct vki_sockaddr_in* serv_addr,
1821 Int addrlen );
1822
1823static
1824UInt my_htonl ( UInt x )
1825{
1826 return
1827 (((x >> 24) & 0xFF) << 0) | (((x >> 16) & 0xFF) << 8)
1828 | (((x >> 8) & 0xFF) << 16) | (((x >> 0) & 0xFF) << 24);
1829}
1830
1831static
1832UShort my_htons ( UShort x )
1833{
1834 return
1835 (((x >> 8) & 0xFF) << 0) | (((x >> 0) & 0xFF) << 8);
1836}
1837
1838
1839/* The main function.
1840
1841 Supplied string contains either an ip address "192.168.0.1" or
1842 an ip address and port pair, "192.168.0.1:1500". Parse these,
1843 and return:
1844 -1 if there is a parse error
1845 -2 if no parse error, but specified host:port cannot be opened
1846 the relevant file (socket) descriptor, otherwise.
sewardj4f094a72002-11-05 23:37:35 +00001847 is used.
sewardj73cf3bc2002-11-03 03:20:15 +00001848*/
1849Int VG_(connect_via_socket)( UChar* str )
1850{
1851 Int sd, res;
1852 struct vki_sockaddr_in servAddr;
1853 UInt ip = 0;
sewardj4f094a72002-11-05 23:37:35 +00001854 UShort port = VG_CLO_DEFAULT_LOGPORT;
sewardj73cf3bc2002-11-03 03:20:15 +00001855 Bool ok = parse_inet_addr_and_port(str, &ip, &port);
1856 if (!ok)
1857 return -1;
1858
1859 if (0)
1860 VG_(printf)("ip = %d.%d.%d.%d, port %d\n",
1861 (ip >> 24) & 0xFF, (ip >> 16) & 0xFF,
1862 (ip >> 8) & 0xFF, ip & 0xFF,
1863 (UInt)port );
1864
nethercote73b526f2004-10-31 18:48:21 +00001865 servAddr.sin_family = VKI_AF_INET;
sewardj73cf3bc2002-11-03 03:20:15 +00001866 servAddr.sin_addr.s_addr = my_htonl(ip);
1867 servAddr.sin_port = my_htons(port);
1868
1869 /* create socket */
nethercote73b526f2004-10-31 18:48:21 +00001870 sd = my_socket(VKI_AF_INET, VKI_SOCK_STREAM, 0 /* IPPROTO_IP ? */);
sewardj73cf3bc2002-11-03 03:20:15 +00001871 if (sd < 0) {
1872 /* this shouldn't happen ... nevertheless */
1873 return -2;
1874 }
1875
1876 /* connect to server */
1877 res = my_connect(sd, (struct vki_sockaddr_in *) &servAddr,
1878 sizeof(servAddr));
1879 if (res < 0) {
1880 /* connection failed */
1881 return -2;
1882 }
1883
1884 return sd;
1885}
1886
1887
1888/* Let d = one or more digits. Accept either:
1889 d.d.d.d or d.d.d.d:d
1890*/
1891Int parse_inet_addr_and_port ( UChar* str, UInt* ip_addr, UShort* port )
1892{
1893# define GET_CH ((*str) ? (*str++) : 0)
1894 UInt ipa, i, j, c, any;
1895 ipa = 0;
1896 for (i = 0; i < 4; i++) {
1897 j = 0;
1898 any = 0;
1899 while (1) {
1900 c = GET_CH;
1901 if (c < '0' || c > '9') break;
1902 j = 10 * j + (int)(c - '0');
1903 any = 1;
1904 }
1905 if (any == 0 || j > 255) goto syntaxerr;
1906 ipa = (ipa << 8) + j;
1907 if (i <= 2 && c != '.') goto syntaxerr;
1908 }
1909 if (c == 0 || c == ':')
1910 *ip_addr = ipa;
1911 if (c == 0) goto ok;
1912 if (c != ':') goto syntaxerr;
1913 j = 0;
1914 any = 0;
1915 while (1) {
1916 c = GET_CH;
1917 if (c < '0' || c > '9') break;
1918 j = j * 10 + (int)(c - '0');
1919 any = 1;
1920 if (j > 65535) goto syntaxerr;
1921 }
1922 if (any == 0 || c != 0) goto syntaxerr;
sewardjd2220672002-11-13 19:41:41 +00001923 if (j < 1024) goto syntaxerr;
sewardj73cf3bc2002-11-03 03:20:15 +00001924 *port = (UShort)j;
1925 ok:
1926 return 1;
1927 syntaxerr:
1928 return 0;
1929# undef GET_CH
1930}
1931
1932
1933static
1934Int my_socket ( Int domain, Int type, Int protocol )
1935{
1936 Int res;
1937 UInt args[3];
1938 args[0] = domain;
1939 args[1] = type;
1940 args[2] = protocol;
nethercote73b526f2004-10-31 18:48:21 +00001941 res = VG_(do_syscall)(__NR_socketcall, VKI_SYS_SOCKET, (UInt)&args);
sewardj73cf3bc2002-11-03 03:20:15 +00001942 if (VG_(is_kerror)(res))
1943 res = -1;
1944 return res;
1945}
1946
1947static
1948Int my_connect ( Int sockfd, struct vki_sockaddr_in* serv_addr,
1949 Int addrlen )
1950{
1951 Int res;
1952 UInt args[3];
1953 args[0] = sockfd;
1954 args[1] = (UInt)serv_addr;
1955 args[2] = addrlen;
nethercote73b526f2004-10-31 18:48:21 +00001956 res = VG_(do_syscall)(__NR_socketcall, VKI_SYS_CONNECT, (UInt)&args);
sewardj73cf3bc2002-11-03 03:20:15 +00001957 if (VG_(is_kerror)(res))
1958 res = -1;
1959 return res;
1960}
1961
1962Int VG_(write_socket)( Int sd, void *msg, Int count )
1963{
1964 /* This is actually send(). */
sewardj570f8902002-11-03 11:44:36 +00001965
1966 /* Requests not to send SIGPIPE on errors on stream oriented
1967 sockets when the other end breaks the connection. The EPIPE
1968 error is still returned. */
nethercote73b526f2004-10-31 18:48:21 +00001969 Int flags = VKI_MSG_NOSIGNAL;
sewardj570f8902002-11-03 11:44:36 +00001970
sewardj73cf3bc2002-11-03 03:20:15 +00001971 Int res;
1972 UInt args[4];
1973 args[0] = sd;
1974 args[1] = (UInt)msg;
1975 args[2] = count;
1976 args[3] = flags;
nethercote73b526f2004-10-31 18:48:21 +00001977 res = VG_(do_syscall)(__NR_socketcall, VKI_SYS_SEND, (UInt)&args);
sewardj73cf3bc2002-11-03 03:20:15 +00001978 if (VG_(is_kerror)(res))
1979 res = -1;
1980 return res;
1981}
1982
rjwalshf5f536f2003-11-17 17:45:00 +00001983Int VG_(getsockname) ( Int sd, struct vki_sockaddr *name, Int *namelen)
1984{
1985 Int res;
1986 UInt args[3];
1987 args[0] = sd;
1988 args[1] = (UInt)name;
1989 args[2] = (UInt)namelen;
nethercote73b526f2004-10-31 18:48:21 +00001990 res = VG_(do_syscall)(__NR_socketcall, VKI_SYS_GETSOCKNAME, (UInt)&args);
rjwalshf5f536f2003-11-17 17:45:00 +00001991 if(VG_(is_kerror)(res))
1992 res = -1;
1993 return res;
1994}
1995
1996Int VG_(getpeername) ( Int sd, struct vki_sockaddr *name, Int *namelen)
1997{
1998 Int res;
1999 UInt args[3];
2000 args[0] = sd;
2001 args[1] = (UInt)name;
2002 args[2] = (UInt)namelen;
nethercote73b526f2004-10-31 18:48:21 +00002003 res = VG_(do_syscall)(__NR_socketcall, VKI_SYS_GETPEERNAME, (UInt)&args);
rjwalshf5f536f2003-11-17 17:45:00 +00002004 if(VG_(is_kerror)(res))
2005 res = -1;
2006 return res;
2007}
2008
2009Int VG_(getsockopt) ( Int sd, Int level, Int optname, void *optval,
2010 Int *optlen)
2011{
2012 Int res;
2013 UInt args[5];
2014 args[0] = sd;
2015 args[1] = (UInt)level;
2016 args[2] = (UInt)optname;
2017 args[3] = (UInt)optval;
2018 args[4] = (UInt)optlen;
nethercote73b526f2004-10-31 18:48:21 +00002019 res = VG_(do_syscall)(__NR_socketcall, VKI_SYS_GETSOCKOPT, (UInt)&args);
rjwalshf5f536f2003-11-17 17:45:00 +00002020 if(VG_(is_kerror)(res))
2021 res = -1;
2022 return res;
2023}
2024
sewardjde4a1d02002-03-22 01:27:54 +00002025
2026/*--------------------------------------------------------------------*/
2027/*--- end vg_mylibc.c ---*/
2028/*--------------------------------------------------------------------*/