blob: a728f4239969b619a6272c949cbfd54e45edffcc [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/*
9 This file is part of Valgrind, an x86 protected-mode emulator
10 designed for debugging and profiling binaries on x86-Unixes.
11
12 Copyright (C) 2000-2002 Julian Seward
13 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
30 The GNU General Public License is contained in the file LICENSE.
31*/
32
33#include "vg_include.h"
34
35
36
37/* ---------------------------------------------------------------------
38 Really Actually DO system calls.
39 ------------------------------------------------------------------ */
40
41/* Ripped off from /usr/include/asm/unistd.h. */
42
43static
44UInt vg_do_syscall0 ( UInt syscallno )
45{
46 UInt __res;
47 __asm__ volatile ("int $0x80"
48 : "=a" (__res)
49 : "0" (syscallno) );
50 return __res;
51}
52
53
54static
55UInt vg_do_syscall1 ( UInt syscallno, UInt arg1 )
56{
57 UInt __res;
58 __asm__ volatile ("int $0x80"
59 : "=a" (__res)
60 : "0" (syscallno),
61 "b" (arg1) );
62 return __res;
63}
64
65
66static
67UInt vg_do_syscall2 ( UInt syscallno,
68 UInt arg1, UInt arg2 )
69{
70 UInt __res;
71 __asm__ volatile ("int $0x80"
72 : "=a" (__res)
73 : "0" (syscallno),
74 "b" (arg1),
75 "c" (arg2) );
76 return __res;
77}
78
79
80static
81UInt vg_do_syscall3 ( UInt syscallno,
82 UInt arg1, UInt arg2, UInt arg3 )
83{
84 UInt __res;
85 __asm__ volatile ("int $0x80"
86 : "=a" (__res)
87 : "0" (syscallno),
88 "b" (arg1),
89 "c" (arg2),
90 "d" (arg3) );
91 return __res;
92}
93
94
95static
96UInt vg_do_syscall4 ( UInt syscallno,
97 UInt arg1, UInt arg2, UInt arg3, UInt arg4 )
98{
99 UInt __res;
100 __asm__ volatile ("int $0x80"
101 : "=a" (__res)
102 : "0" (syscallno),
103 "b" (arg1),
104 "c" (arg2),
105 "d" (arg3),
106 "S" (arg4) );
107 return __res;
108}
109
110
111#if 0
112static
113UInt vg_do_syscall5 ( UInt syscallno,
114 UInt arg1, UInt arg2, UInt arg3, UInt arg4,
115 UInt arg5 )
116{
117 UInt __res;
118 __asm__ volatile ("int $0x80"
119 : "=a" (__res)
120 : "0" (syscallno),
121 "b" (arg1),
122 "c" (arg2),
123 "d" (arg3),
124 "S" (arg4),
125 "D" (arg5) );
126 return __res;
127}
128#endif
129
130/* ---------------------------------------------------------------------
131 Wrappers around system calls, and other stuff, to do with signals.
132 ------------------------------------------------------------------ */
133
134/* sigemptyset, sigfullset, sigaddset and sigdelset return 0 on
135 success and -1 on error.
136*/
137Int VG_(ksigfillset)( vki_ksigset_t* set )
138{
139 Int i;
140 if (set == NULL)
141 return -1;
142 for (i = 0; i < VKI_KNSIG_WORDS; i++)
143 set->ws[i] = 0xFFFFFFFF;
144 return 0;
145}
146
147Int VG_(ksigemptyset)( vki_ksigset_t* set )
148{
149 Int i;
150 if (set == NULL)
151 return -1;
152 for (i = 0; i < VKI_KNSIG_WORDS; i++)
153 set->ws[i] = 0x0;
154 return 0;
155}
156
157Int VG_(ksigaddset)( vki_ksigset_t* set, Int signum )
158{
159 if (set == NULL)
160 return -1;
161 if (signum < 1 && signum > VKI_KNSIG)
162 return -1;
163 signum--;
164 set->ws[signum / VKI_KNSIG_BPW] |= (1 << (signum % VKI_KNSIG_BPW));
165 return 0;
166}
167
168Int VG_(ksigismember) ( vki_ksigset_t* set, Int signum )
169{
170 if (set == NULL)
171 return -1;
172 if (signum < 1 && signum > VKI_KNSIG)
173 return -1;
174 signum--;
175 if (1 & ((set->ws[signum / VKI_KNSIG_BPW]) >> (signum % VKI_KNSIG_BPW)))
176 return 1;
177 else
178 return 0;
179}
180
181
182/* The functions sigaction, sigprocmask, sigpending and sigsuspend
183 return 0 on success and -1 on error.
184*/
185Int VG_(ksigprocmask)( Int how,
186 const vki_ksigset_t* set,
187 vki_ksigset_t* oldset)
188{
189 Int res
190 = vg_do_syscall4(__NR_rt_sigprocmask,
191 how, (UInt)set, (UInt)oldset,
192 VKI_KNSIG_WORDS * VKI_BYTES_PER_WORD);
193 return VG_(is_kerror)(res) ? -1 : 0;
194}
195
196
197Int VG_(ksigaction) ( Int signum,
198 const vki_ksigaction* act,
199 vki_ksigaction* oldact)
200{
201 Int res
202 = vg_do_syscall4(__NR_rt_sigaction,
203 signum, (UInt)act, (UInt)oldact,
204 VKI_KNSIG_WORDS * VKI_BYTES_PER_WORD);
205 return VG_(is_kerror)(res) ? -1 : 0;
206}
207
208
209Int VG_(ksigaltstack)( const vki_kstack_t* ss, vki_kstack_t* oss )
210{
211 Int res
212 = vg_do_syscall2(__NR_sigaltstack, (UInt)ss, (UInt)oss);
213 return VG_(is_kerror)(res) ? -1 : 0;
214}
215
216
217Int VG_(ksignal)(Int signum, void (*sighandler)(Int))
218{
219 Int res;
220 vki_ksigaction sa;
221 sa.ksa_handler = sighandler;
222 sa.ksa_flags = VKI_SA_ONSTACK | VKI_SA_RESTART;
223 sa.ksa_restorer = NULL;
224 res = VG_(ksigemptyset)( &sa.ksa_mask );
225 vg_assert(res == 0);
226 res = vg_do_syscall4(__NR_rt_sigaction,
227 signum, (UInt)(&sa), (UInt)NULL,
228 VKI_KNSIG_WORDS * VKI_BYTES_PER_WORD);
229 return VG_(is_kerror)(res) ? -1 : 0;
230}
231
232
233/* ---------------------------------------------------------------------
sewardj2e93c502002-04-12 11:12:52 +0000234 mmap/munmap, exit, fcntl
sewardjde4a1d02002-03-22 01:27:54 +0000235 ------------------------------------------------------------------ */
236
237/* Returns -1 on failure. */
238void* VG_(mmap)( void* start, UInt length,
239 UInt prot, UInt flags, UInt fd, UInt offset)
240{
241 Int res;
242 UInt args[6];
243 args[0] = (UInt)start;
244 args[1] = length;
245 args[2] = prot;
246 args[3] = flags;
247 args[4] = fd;
248 args[5] = offset;
249 res = vg_do_syscall1(__NR_mmap, (UInt)(&(args[0])) );
250 return VG_(is_kerror)(res) ? ((void*)(-1)) : (void*)res;
251}
252
253/* Returns -1 on failure. */
254Int VG_(munmap)( void* start, Int length )
255{
256 Int res = vg_do_syscall2(__NR_munmap, (UInt)start, (UInt)length );
257 return VG_(is_kerror)(res) ? -1 : 0;
258}
259
260void VG_(exit)( Int status )
261{
262 (void)vg_do_syscall1(__NR_exit, (UInt)status );
263 /* Why are we still alive here? */
264 /*NOTREACHED*/
265 vg_assert(2+2 == 5);
266}
267
sewardj2e93c502002-04-12 11:12:52 +0000268/* Returns -1 on error. */
269Int VG_(fcntl) ( Int fd, Int cmd, Int arg )
270{
271 Int res = vg_do_syscall3(__NR_fcntl, fd, cmd, arg);
272 return VG_(is_kerror)(res) ? -1 : res;
273}
274
275/* Returns -1 on error. */
276Int VG_(select)( Int n,
277 vki_fd_set* readfds,
278 vki_fd_set* writefds,
279 vki_fd_set* exceptfds,
280 struct vki_timeval * timeout )
281{
282 Int res;
283 UInt args[5];
284 args[0] = n;
285 args[1] = (UInt)readfds;
286 args[2] = (UInt)writefds;
287 args[3] = (UInt)exceptfds;
288 args[4] = (UInt)timeout;
289 res = vg_do_syscall1(__NR_select, (UInt)(&(args[0])) );
290 return VG_(is_kerror)(res) ? -1 : res;
291 return res;
292}
293
294/* Returns -1 on error, but 0 if ok or interrupted. */
295Int VG_(nanosleep)( const struct vki_timespec *req,
296 struct vki_timespec *rem )
297{
298 Int res;
299 res = vg_do_syscall2(__NR_nanosleep, (UInt)req, (UInt)rem);
300 if (res == -VKI_EINVAL) return -1;
301 return 0;
302}
303
304
sewardjde4a1d02002-03-22 01:27:54 +0000305/* ---------------------------------------------------------------------
306 printf implementation. The key function, vg_vprintf(), emits chars
307 into a caller-supplied function. Distantly derived from:
308
309 vprintf replacement for Checker.
310 Copyright 1993, 1994, 1995 Tristan Gingold
311 Written September 1993 Tristan Gingold
312 Tristan Gingold, 8 rue Parmentier, F-91120 PALAISEAU, FRANCE
313
314 (Checker itself was GPL'd.)
315 ------------------------------------------------------------------ */
316
317
318/* Some flags. */
319#define VG_MSG_SIGNED 1 /* The value is signed. */
320#define VG_MSG_ZJUSTIFY 2 /* Must justify with '0'. */
321#define VG_MSG_LJUSTIFY 4 /* Must justify on the left. */
322
323
324/* Copy a string into the buffer. */
325static void
326myvprintf_str ( void(*send)(Char), Int flags, Int width, Char* str,
327 Bool capitalise )
328{
329# define MAYBE_TOUPPER(ch) (capitalise ? VG_(toupper)(ch) : (ch))
330
331 Int i, extra;
332 Int len = VG_(strlen)(str);
333
334 if (width == 0) {
335 for (i = 0; i < len; i++)
336 send(MAYBE_TOUPPER(str[i]));
337 return;
338 }
339
340 if (len > width) {
341 for (i = 0; i < width; i++)
342 send(MAYBE_TOUPPER(str[i]));
343 return;
344 }
345
346 extra = width - len;
347 if (flags & VG_MSG_LJUSTIFY) {
348 for (i = 0; i < extra; i++)
349 send(' ');
350 }
351 for (i = 0; i < len; i++)
352 send(MAYBE_TOUPPER(str[i]));
353 if (!(flags & VG_MSG_LJUSTIFY)) {
354 for (i = 0; i < extra; i++)
355 send(' ');
356 }
357
358# undef MAYBE_TOUPPER
359}
360
361/* Write P into the buffer according to these args:
362 * If SIGN is true, p is a signed.
363 * BASE is the base.
364 * If WITH_ZERO is true, '0' must be added.
365 * WIDTH is the width of the field.
366 */
367static void
368myvprintf_int64 ( void(*send)(Char), Int flags, Int base, Int width, ULong p)
369{
370 Char buf[40];
371 Int ind = 0;
372 Int i;
373 Bool neg = False;
374 Char *digits = "0123456789ABCDEF";
375
376 if (base < 2 || base > 16)
377 return;
378
379 if ((flags & VG_MSG_SIGNED) && (Long)p < 0) {
380 p = - (Long)p;
381 neg = True;
382 }
383
384 if (p == 0)
385 buf[ind++] = '0';
386 else {
387 while (p > 0) {
388 buf[ind++] = digits[p % base];
389 p /= base;
390 }
391 }
392
393 if (neg)
394 buf[ind++] = '-';
395
396 if (width > 0 && !(flags & VG_MSG_LJUSTIFY)) {
397 for(; ind < width; ind++) {
398 vg_assert(ind < 39);
399 buf[ind] = (flags & VG_MSG_ZJUSTIFY) ? '0': ' ';
400 }
401 }
402
403 /* Reverse copy to buffer. */
404 for (i = ind -1; i >= 0; i--)
405 send(buf[i]);
406
407 if (width > 0 && (flags & VG_MSG_LJUSTIFY)) {
408 for(; ind < width; ind++)
409 send((flags & VG_MSG_ZJUSTIFY) ? '0': ' ');
410 }
411}
412
413
414/* A simple vprintf(). */
415void
416VG_(vprintf) ( void(*send)(Char), const Char *format, va_list vargs )
417{
418 int i;
419 int flags;
420 int width;
421 Bool is_long;
422
423 /* We assume that vargs has already been initialised by the
424 caller, using va_start, and that the caller will similarly
425 clean up with va_end.
426 */
427
428 for (i = 0; format[i] != 0; i++) {
429 if (format[i] != '%') {
430 send(format[i]);
431 continue;
432 }
433 i++;
434 /* A '%' has been found. Ignore a trailing %. */
435 if (format[i] == 0)
436 break;
437 if (format[i] == '%') {
438 /* `%%' is replaced by `%'. */
439 send('%');
440 continue;
441 }
442 flags = 0;
443 is_long = False;
444 width = 0; /* length of the field. */
445 /* If '-' follows '%', justify on the left. */
446 if (format[i] == '-') {
447 flags |= VG_MSG_LJUSTIFY;
448 i++;
449 }
450 /* If '0' follows '%', pads will be inserted. */
451 if (format[i] == '0') {
452 flags |= VG_MSG_ZJUSTIFY;
453 i++;
454 }
455 /* Compute the field length. */
456 while (format[i] >= '0' && format[i] <= '9') {
457 width *= 10;
458 width += format[i++] - '0';
459 }
460 while (format[i] == 'l') {
461 i++;
462 is_long = True;
463 }
464
465 switch (format[i]) {
466 case 'd': /* %d */
467 flags |= VG_MSG_SIGNED;
468 if (is_long)
469 myvprintf_int64(send, flags, 10, width,
470 (ULong)(va_arg (vargs, Long)));
471 else
472 myvprintf_int64(send, flags, 10, width,
473 (ULong)(va_arg (vargs, Int)));
474 break;
475 case 'u': /* %u */
476 if (is_long)
477 myvprintf_int64(send, flags, 10, width,
478 (ULong)(va_arg (vargs, ULong)));
479 else
480 myvprintf_int64(send, flags, 10, width,
481 (ULong)(va_arg (vargs, UInt)));
482 break;
483 case 'p': /* %p */
484 send('0');
485 send('x');
486 myvprintf_int64(send, flags, 16, width,
487 (ULong)((UInt)va_arg (vargs, void *)));
488 break;
489 case 'x': /* %x */
490 if (is_long)
491 myvprintf_int64(send, flags, 16, width,
492 (ULong)(va_arg (vargs, ULong)));
493 else
494 myvprintf_int64(send, flags, 16, width,
495 (ULong)(va_arg (vargs, UInt)));
496 break;
497 case 'c': /* %c */
498 send(va_arg (vargs, int));
499 break;
500 case 's': case 'S': { /* %s */
501 char *str = va_arg (vargs, char *);
502 if (str == (char*) 0) str = "(null)";
503 myvprintf_str(send, flags, width, str, format[i]=='S');
504 break;
505 }
506 default:
507 break;
508 }
509 }
510}
511
512
513/* A general replacement for printf(). Note that only low-level
514 debugging info should be sent via here. The official route is to
515 to use vg_message(). This interface is deprecated.
516*/
517static char myprintf_buf[100];
518static int n_myprintf_buf;
519
520static void add_to_myprintf_buf ( Char c )
521{
522 if (n_myprintf_buf >= 100-10 /*paranoia*/ ) {
523 if (VG_(clo_logfile_fd) >= 0)
524 VG_(write)
525 (VG_(clo_logfile_fd), myprintf_buf, VG_(strlen)(myprintf_buf));
526 n_myprintf_buf = 0;
527 myprintf_buf[n_myprintf_buf] = 0;
528 }
529 myprintf_buf[n_myprintf_buf++] = c;
530 myprintf_buf[n_myprintf_buf] = 0;
531}
532
533void VG_(printf) ( const char *format, ... )
534{
535 va_list vargs;
536 va_start(vargs,format);
537
538 n_myprintf_buf = 0;
539 myprintf_buf[n_myprintf_buf] = 0;
540 VG_(vprintf) ( add_to_myprintf_buf, format, vargs );
541
542 if (n_myprintf_buf > 0 && VG_(clo_logfile_fd) >= 0)
543 VG_(write)
544 ( VG_(clo_logfile_fd), myprintf_buf, VG_(strlen)(myprintf_buf));
545
546 va_end(vargs);
547}
548
549
550/* A general replacement for sprintf(). */
551static Char* vg_sprintf_ptr;
552
553static void add_to_vg_sprintf_buf ( Char c )
554{
555 *vg_sprintf_ptr++ = c;
556}
557
558void VG_(sprintf) ( Char* buf, Char *format, ... )
559{
560 va_list vargs;
561 va_start(vargs,format);
562
563 vg_sprintf_ptr = buf;
564 VG_(vprintf) ( add_to_vg_sprintf_buf, format, vargs );
565 add_to_vg_sprintf_buf(0);
566
567 va_end(vargs);
568}
569
570
571/* ---------------------------------------------------------------------
572 Misc str* functions.
573 ------------------------------------------------------------------ */
574
575Bool VG_(isspace) ( Char c )
576{
577 return (c == ' ' || c == '\n' || c == '\t' || c == 0);
578}
579
580
581Int VG_(strlen) ( const Char* str )
582{
583 Int i = 0;
584 while (str[i] != 0) i++;
585 return i;
586}
587
588
589Long VG_(atoll) ( Char* str )
590{
591 Bool neg = False;
592 Long n = 0;
593 if (*str == '-') { str++; neg = True; };
594 while (*str >= '0' && *str <= '9') {
595 n = 10*n + (Long)(*str - '0');
596 str++;
597 }
598 if (neg) n = -n;
599 return n;
600}
601
602
603Char* VG_(strcat) ( Char* dest, const Char* src )
604{
605 Char* dest_orig = dest;
606 while (*dest) dest++;
607 while (*src) *dest++ = *src++;
608 *dest = 0;
609 return dest_orig;
610}
611
612
613Char* VG_(strncat) ( Char* dest, const Char* src, Int n )
614{
615 Char* dest_orig = dest;
616 while (*dest) dest++;
617 while (*src && n > 0) { *dest++ = *src++; n--; }
618 *dest = 0;
619 return dest_orig;
620}
621
622
623Char* VG_(strpbrk) ( const Char* s, const Char* accept )
624{
625 const Char* a;
626 while (*s) {
627 a = accept;
628 while (*a)
629 if (*a++ == *s)
630 return (Char *) s;
631 s++;
632 }
633 return NULL;
634}
635
636
637Char* VG_(strcpy) ( Char* dest, const Char* src )
638{
639 Char* dest_orig = dest;
640 while (*src) *dest++ = *src++;
641 *dest = 0;
642 return dest_orig;
643}
644
645
646/* Copy bytes, not overrunning the end of dest and always ensuring
647 zero termination. */
648void VG_(strncpy_safely) ( Char* dest, const Char* src, Int ndest )
649{
650 Int i;
651 vg_assert(ndest > 0);
652 i = 0;
653 dest[i] = 0;
654 while (True) {
655 if (src[i] == 0) return;
656 if (i >= ndest-1) return;
657 dest[i] = src[i];
658 i++;
659 dest[i] = 0;
660 }
661}
662
663
664void VG_(strncpy) ( Char* dest, const Char* src, Int ndest )
665{
666 VG_(strncpy_safely)( dest, src, ndest+1 );
667}
668
669
670Int VG_(strcmp) ( const Char* s1, const Char* s2 )
671{
672 while (True) {
673 if (*s1 == 0 && *s2 == 0) return 0;
674 if (*s1 == 0) return -1;
675 if (*s2 == 0) return 1;
676
677 if (*(UChar*)s1 < *(UChar*)s2) return -1;
678 if (*(UChar*)s1 > *(UChar*)s2) return 1;
679
680 s1++; s2++;
681 }
682}
683
684
685Int VG_(strcmp_ws) ( const Char* s1, const Char* s2 )
686{
687 while (True) {
688 if (VG_(isspace)(*s1) && VG_(isspace)(*s2)) return 0;
689 if (VG_(isspace)(*s1)) return -1;
690 if (VG_(isspace)(*s2)) return 1;
691
692 if (*(UChar*)s1 < *(UChar*)s2) return -1;
693 if (*(UChar*)s1 > *(UChar*)s2) return 1;
694
695 s1++; s2++;
696 }
697}
698
699
700Int VG_(strncmp) ( const Char* s1, const Char* s2, Int nmax )
701{
702 Int n = 0;
703 while (True) {
704 if (n >= nmax) return 0;
705 if (*s1 == 0 && *s2 == 0) return 0;
706 if (*s1 == 0) return -1;
707 if (*s2 == 0) return 1;
708
709 if (*(UChar*)s1 < *(UChar*)s2) return -1;
710 if (*(UChar*)s1 > *(UChar*)s2) return 1;
711
712 s1++; s2++; n++;
713 }
714}
715
716
717Int VG_(strncmp_ws) ( const Char* s1, const Char* s2, Int nmax )
718{
719 Int n = 0;
720 while (True) {
721 if (n >= nmax) return 0;
722 if (VG_(isspace)(*s1) && VG_(isspace)(*s2)) return 0;
723 if (VG_(isspace)(*s1)) return -1;
724 if (VG_(isspace)(*s2)) return 1;
725
726 if (*(UChar*)s1 < *(UChar*)s2) return -1;
727 if (*(UChar*)s1 > *(UChar*)s2) return 1;
728
729 s1++; s2++; n++;
730 }
731}
732
733
734Char* VG_(strstr) ( const Char* haystack, Char* needle )
735{
736 Int n = VG_(strlen)(needle);
737 while (True) {
738 if (haystack[0] == 0)
739 return NULL;
740 if (VG_(strncmp)(haystack, needle, n) == 0)
741 return (Char*)haystack;
742 haystack++;
743 }
744}
745
746
747Char* VG_(strchr) ( const Char* s, Char c )
748{
749 while (True) {
750 if (*s == c) return (Char*)s;
751 if (*s == 0) return NULL;
752 s++;
753 }
754}
755
756
757Char VG_(toupper) ( Char c )
758{
759 if (c >= 'a' && c <= 'z')
760 return c + ('A' - 'a');
761 else
762 return c;
763}
764
765
766Char* VG_(strdup) ( ArenaId aid, const Char* s )
767{
768 Int i;
769 Int len = VG_(strlen)(s) + 1;
770 Char* res = VG_(malloc) (aid, len);
771 for (i = 0; i < len; i++)
772 res[i] = s[i];
773 return res;
774}
775
776
777/* ---------------------------------------------------------------------
778 A simple string matching routine, purloined from Hugs98.
779 `*' matches any sequence of zero or more characters
780 `?' matches any single character exactly
781 `\c' matches the character c only (ignoring special chars)
782 c matches the character c only
783 ------------------------------------------------------------------ */
784
785/* Keep track of recursion depth. */
786static Int recDepth;
787
788static Bool stringMatch_wrk ( Char* pat, Char* str )
789{
790 vg_assert(recDepth >= 0 && recDepth < 500);
791 recDepth++;
792 for (;;) {
793 switch (*pat) {
794 case '\0' : return (*str=='\0');
795 case '*' : do {
796 if (stringMatch_wrk(pat+1,str)) {
797 recDepth--;
798 return True;
799 }
800 } while (*str++);
801 recDepth--;
802 return False;
803 case '?' : if (*str++=='\0') {
804 recDepth--;
805 return False;
806 }
807 pat++;
808 break;
809 case '\\' : if (*++pat == '\0') {
810 recDepth--;
811 return False; /* spurious trailing \ in pattern */
812 }
813 /* falls through to ... */
814 default : if (*pat++ != *str++) {
815 recDepth--;
816 return False;
817 }
818 break;
819 }
820 }
821}
822
823Bool VG_(stringMatch) ( Char* pat, Char* str )
824{
825 Bool b;
826 recDepth = 0;
827 b = stringMatch_wrk ( pat, str );
828 /*
829 VG_(printf)("%s %s %s\n",
830 b?"TRUE ":"FALSE", pat, str);
831 */
832 return b;
833}
834
835
836/* ---------------------------------------------------------------------
837 Assertery.
838 ------------------------------------------------------------------ */
839
840#define EMAIL_ADDR "jseward@acm.org"
841
842void VG_(assert_fail) ( Char* expr, Char* file, Int line, Char* fn )
843{
844 VG_(printf)("\n%s: %s:%d (%s): Assertion `%s' failed.\n",
845 "valgrind", file, line, fn, expr );
sewardj15a43e12002-04-17 19:35:12 +0000846 VG_(pp_sched_status)();
sewardjde4a1d02002-03-22 01:27:54 +0000847 VG_(printf)("Please report this bug to me at: %s\n\n", EMAIL_ADDR);
848 VG_(shutdown_logging)();
sewardjde4a1d02002-03-22 01:27:54 +0000849 VG_(exit)(1);
850}
851
852void VG_(panic) ( Char* str )
853{
854 VG_(printf)("\nvalgrind: the `impossible' happened:\n %s\n", str);
855 VG_(printf)("Basic block ctr is approximately %llu\n", VG_(bbs_done) );
sewardj15a43e12002-04-17 19:35:12 +0000856 VG_(pp_sched_status)();
sewardjde4a1d02002-03-22 01:27:54 +0000857 VG_(printf)("Please report this bug to me at: %s\n\n", EMAIL_ADDR);
858 VG_(shutdown_logging)();
sewardjde4a1d02002-03-22 01:27:54 +0000859 VG_(exit)(1);
860}
861
862#undef EMAIL_ADDR
863
864
865/* ---------------------------------------------------------------------
866 Primitive support for reading files.
867 ------------------------------------------------------------------ */
868
869/* Returns -1 on failure. */
870Int VG_(open_read) ( Char* pathname )
871{
872 Int fd;
873 /* VG_(printf)("vg_open_read %s\n", pathname ); */
874
875 /* This gets a segmentation fault if pathname isn't a valid file.
876 I don't know why. It seems like the call to open is getting
877 intercepted and messed with by glibc ... */
878 /* fd = open( pathname, O_RDONLY ); */
879 /* ... so we go direct to the horse's mouth, which seems to work
880 ok: */
881 const int O_RDONLY = 0; /* See /usr/include/bits/fcntl.h */
882 fd = vg_do_syscall3(__NR_open, (UInt)pathname, O_RDONLY, 0);
883 /* VG_(printf)("result = %d\n", fd); */
884 if (VG_(is_kerror)(fd)) fd = -1;
885 return fd;
886}
887
888
889void VG_(close) ( Int fd )
890{
891 vg_do_syscall1(__NR_close, fd);
892}
893
894
895Int VG_(read) ( Int fd, void* buf, Int count)
896{
897 Int res;
898 /* res = read( fd, buf, count ); */
899 res = vg_do_syscall3(__NR_read, fd, (UInt)buf, count);
900 if (VG_(is_kerror)(res)) res = -1;
901 return res;
902}
903
904Int VG_(write) ( Int fd, void* buf, Int count)
905{
906 Int res;
907 /* res = write( fd, buf, count ); */
908 res = vg_do_syscall3(__NR_write, fd, (UInt)buf, count);
909 if (VG_(is_kerror)(res)) res = -1;
910 return res;
911}
912
913/* Misc functions looking for a proper home. */
914
915/* We do getenv without libc's help by snooping around in
916 VG_(client_env) as determined at startup time. */
917Char* VG_(getenv) ( Char* varname )
918{
919 Int i, n;
920 n = VG_(strlen)(varname);
921 for (i = 0; VG_(client_envp)[i] != NULL; i++) {
922 Char* s = VG_(client_envp)[i];
923 if (VG_(strncmp)(varname, s, n) == 0 && s[n] == '=') {
924 return & s[n+1];
925 }
926 }
927 return NULL;
928}
929
930/* You'd be amazed how many places need to know the current pid. */
931Int VG_(getpid) ( void )
932{
933 Int res;
934 /* res = getpid(); */
935 res = vg_do_syscall0(__NR_getpid);
936 return res;
937}
938
sewardj2e93c502002-04-12 11:12:52 +0000939/* Read a notional elapsed (wallclock-time) timer, giving a 64-bit
940 microseconds count. */
941ULong VG_(read_microsecond_timer)( void )
942{
943 Int res;
944 struct vki_timeval tv;
945 res = vg_do_syscall2(__NR_gettimeofday, (UInt)&tv, (UInt)NULL);
946 vg_assert(!VG_(is_kerror)(res));
947 return (1000000ULL * (ULong)(tv.tv_sec)) + (ULong)(tv.tv_usec);
948}
sewardjde4a1d02002-03-22 01:27:54 +0000949
sewardje6a25242002-04-21 22:03:07 +0000950/* Return -1 if error, else 0. NOTE does not indicate return code of
951 child! */
952Int VG_(system) ( Char* cmd )
953{
954 Int pid, res;
955 void* environ[1] = { NULL };
956 if (cmd == NULL)
957 return 1;
958 pid = vg_do_syscall0(__NR_fork);
959 if (VG_(is_kerror)(pid))
960 return -1;
961 if (pid == 0) {
962 /* child */
963 Char* argv[4];
964 argv[0] = "/bin/sh";
965 argv[1] = "-c";
966 argv[2] = cmd;
967 argv[3] = 0;
968 (void)vg_do_syscall3(__NR_execve,
969 (UInt)"/bin/sh", (UInt)argv, (UInt)&environ);
970 /* If we're still alive here, execve failed. */
971 return -1;
972 } else {
973 /* parent */
974 res = vg_do_syscall3(__NR_waitpid, pid, (UInt)NULL, 0);
975 if (VG_(is_kerror)(res)) {
976 return -1;
977 } else {
978 return 0;
979 }
980 }
981}
982
983
sewardjde4a1d02002-03-22 01:27:54 +0000984/* ---------------------------------------------------------------------
985 Primitive support for bagging memory via mmap.
986 ------------------------------------------------------------------ */
987
988void* VG_(get_memory_from_mmap) ( Int nBytes )
989{
990 static UInt tot_alloc = 0;
991 void* p = VG_(mmap)( 0, nBytes,
992 VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC,
993 VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS, -1, 0 );
994 if (p != ((void*)(-1))) {
995 tot_alloc += (UInt)nBytes;
996 if (0)
997 VG_(printf)("get_memory_from_mmap: %d tot, %d req\n",
998 tot_alloc, nBytes);
999 return p;
1000 }
1001 VG_(printf)("vg_get_memory_from_mmap failed on request of %d\n",
1002 nBytes);
1003 VG_(panic)("vg_get_memory_from_mmap: out of memory! Fatal! Bye!\n");
1004}
1005
1006
1007/*--------------------------------------------------------------------*/
1008/*--- end vg_mylibc.c ---*/
1009/*--------------------------------------------------------------------*/