• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*--------------------------------------------------------------------*/
3 /*--- Process-related libc stuff.                     m_libcproc.c ---*/
4 /*--------------------------------------------------------------------*/
5 
6 /*
7    This file is part of Valgrind, a dynamic binary instrumentation
8    framework.
9 
10    Copyright (C) 2000-2010 Julian Seward
11       jseward@acm.org
12 
13    This program is free software; you can redistribute it and/or
14    modify it under the terms of the GNU General Public License as
15    published by the Free Software Foundation; either version 2 of the
16    License, or (at your option) any later version.
17 
18    This program is distributed in the hope that it will be useful, but
19    WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    General Public License for more details.
22 
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26    02111-1307, USA.
27 
28    The GNU General Public License is contained in the file COPYING.
29 */
30 
31 #include "pub_core_basics.h"
32 #include "pub_core_vki.h"
33 #include "pub_core_vkiscnums.h"
34 #include "pub_core_libcbase.h"
35 #include "pub_core_libcassert.h"
36 #include "pub_core_libcfile.h"
37 #include "pub_core_libcprint.h"
38 #include "pub_core_libcproc.h"
39 #include "pub_core_libcsignal.h"
40 #include "pub_core_tooliface.h"
41 #include "pub_core_options.h"
42 #include "pub_core_seqmatch.h"
43 #include "pub_core_mallocfree.h"
44 #include "pub_core_syscall.h"
45 #include "pub_core_xarray.h"
46 #include "pub_core_clientstate.h"
47 
48 #if defined(VGO_darwin)
49 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
50 #include <mach/mach.h>   /* mach_thread_self */
51 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
52 #endif
53 
54 /* IMPORTANT: on Darwin it is essential to use the _nocancel versions
55    of syscalls rather than the vanilla version, if a _nocancel version
56    is available.  See docs/internals/Darwin-notes.txt for the reason
57    why. */
58 
59 /* ---------------------------------------------------------------------
60    Command line and environment stuff
61    ------------------------------------------------------------------ */
62 
63 /* As deduced from sp_at_startup, the client's argc, argv[] and
64    envp[] as extracted from the client's stack at startup-time. */
65 Char** VG_(client_envp) = NULL;
66 
67 /* Path to library directory */
68 const Char *VG_(libdir) = VG_LIBDIR;
69 
70 const Char *VG_(LD_PRELOAD_var_name) =
71 #if defined(VGO_linux) || defined(VGO_aix5)
72    "LD_PRELOAD";
73 #elif defined(VGO_darwin)
74    "DYLD_INSERT_LIBRARIES";
75 #else
76 #  error Unknown OS
77 #endif
78 
79 /* We do getenv without libc's help by snooping around in
80    VG_(client_envp) as determined at startup time. */
VG_(getenv)81 Char *VG_(getenv)(Char *varname)
82 {
83    Int i, n;
84    vg_assert( VG_(client_envp) );
85    n = VG_(strlen)(varname);
86    for (i = 0; VG_(client_envp)[i] != NULL; i++) {
87       Char* s = VG_(client_envp)[i];
88       if (VG_(strncmp)(varname, s, n) == 0 && s[n] == '=') {
89          return & s[n+1];
90       }
91    }
92    return NULL;
93 }
94 
VG_(env_unsetenv)95 void  VG_(env_unsetenv) ( Char **env, const Char *varname )
96 {
97    Char **from;
98    Char **to = NULL;
99    Int len = VG_(strlen)(varname);
100 
101    for (from = to = env; from && *from; from++) {
102       if (!(VG_(strncmp)(varname, *from, len) == 0 && (*from)[len] == '=')) {
103 	 *to = *from;
104 	 to++;
105       }
106    }
107    *to = *from;
108 }
109 
110 /* set the environment; returns the old env if a new one was allocated */
VG_(env_setenv)111 Char **VG_(env_setenv) ( Char ***envp, const Char* varname, const Char *val )
112 {
113    Char **env = (*envp);
114    Char **cpp;
115    Int len = VG_(strlen)(varname);
116    Char *valstr = VG_(arena_malloc)(VG_AR_CORE, "libcproc.es.1",
117                                     len + VG_(strlen)(val) + 2);
118    Char **oldenv = NULL;
119 
120    VG_(sprintf)(valstr, "%s=%s", varname, val);
121 
122    for (cpp = env; cpp && *cpp; cpp++) {
123       if (VG_(strncmp)(varname, *cpp, len) == 0 && (*cpp)[len] == '=') {
124 	 *cpp = valstr;
125 	 return oldenv;
126       }
127    }
128 
129    if (env == NULL) {
130       env = VG_(arena_malloc)(VG_AR_CORE, "libcproc.es.2", sizeof(Char **) * 2);
131       env[0] = valstr;
132       env[1] = NULL;
133 
134       *envp = env;
135 
136    }  else {
137       Int envlen = (cpp-env) + 2;
138       Char **newenv = VG_(arena_malloc)(VG_AR_CORE, "libcproc.es.3",
139                                         envlen * sizeof(Char **));
140 
141       for (cpp = newenv; *env; )
142 	 *cpp++ = *env++;
143       *cpp++ = valstr;
144       *cpp++ = NULL;
145 
146       oldenv = *envp;
147 
148       *envp = newenv;
149    }
150 
151    return oldenv;
152 }
153 
154 
155 /* Walk through a colon-separated environment variable, and remove the
156    entries which match remove_pattern.  It slides everything down over
157    the removed entries, and pads the remaining space with '\0'.  It
158    modifies the entries in place (in the client address space), but it
159    shouldn't matter too much, since we only do this just before an
160    execve().
161 
162    This is also careful to mop up any excess ':'s, since empty strings
163    delimited by ':' are considered to be '.' in a path.
164 */
mash_colon_env(Char * varp,const Char * remove_pattern)165 static void mash_colon_env(Char *varp, const Char *remove_pattern)
166 {
167    Char *const start = varp;
168    Char *entry_start = varp;
169    Char *output = varp;
170 
171    if (varp == NULL)
172       return;
173 
174    while(*varp) {
175       if (*varp == ':') {
176 	 Char prev;
177 	 Bool match;
178 
179 	 /* This is a bit subtle: we want to match against the entry
180 	    we just copied, because it may have overlapped with
181 	    itself, junking the original. */
182 
183 	 prev = *output;
184 	 *output = '\0';
185 
186 	 match = VG_(string_match)(remove_pattern, entry_start);
187 
188 	 *output = prev;
189 
190 	 if (match) {
191 	    output = entry_start;
192 	    varp++;			/* skip ':' after removed entry */
193 	 } else
194 	    entry_start = output+1;	/* entry starts after ':' */
195       }
196 
197       if (*varp)
198          *output++ = *varp++;
199    }
200 
201    /* make sure last entry is nul terminated */
202    *output = '\0';
203 
204    /* match against the last entry */
205    if (VG_(string_match)(remove_pattern, entry_start)) {
206       output = entry_start;
207       if (output > start) {
208 	 /* remove trailing ':' */
209 	 output--;
210 	 vg_assert(*output == ':');
211       }
212    }
213 
214    /* pad out the left-overs with '\0' */
215    while(output < varp)
216       *output++ = '\0';
217 }
218 
219 
220 // Removes all the Valgrind-added stuff from the passed environment.  Used
221 // when starting child processes, so they don't see that added stuff.
VG_(env_remove_valgrind_env_stuff)222 void VG_(env_remove_valgrind_env_stuff)(Char** envp)
223 {
224 
225 #if defined(VGO_darwin)
226 
227    // Environment cleanup is also handled during parent launch
228    // in vg_preloaded.c:vg_cleanup_env().
229 
230 #endif
231 
232    Int i;
233    Char* ld_preload_str = NULL;
234    Char* ld_library_path_str = NULL;
235    Char* dyld_insert_libraries_str = NULL;
236    Char* buf;
237 
238    // Find LD_* variables
239    // DDD: should probably conditionally compiled some of this:
240    // - LD_LIBRARY_PATH is universal?
241    // - LD_PRELOAD is on Linux, not on Darwin, not sure about AIX
242    // - DYLD_INSERT_LIBRARIES and DYLD_SHARED_REGION are Darwin-only
243    for (i = 0; envp[i] != NULL; i++) {
244       if (VG_(strncmp)(envp[i], "LD_PRELOAD=", 11) == 0)
245          ld_preload_str = &envp[i][11];
246       if (VG_(strncmp)(envp[i], "LD_LIBRARY_PATH=", 16) == 0)
247          ld_library_path_str = &envp[i][16];
248       if (VG_(strncmp)(envp[i], "DYLD_INSERT_LIBRARIES=", 22) == 0)
249          dyld_insert_libraries_str = &envp[i][22];
250    }
251 
252    buf = VG_(arena_malloc)(VG_AR_CORE, "libcproc.erves.1",
253                            VG_(strlen)(VG_(libdir)) + 20);
254 
255    // Remove Valgrind-specific entries from LD_*.
256    VG_(sprintf)(buf, "%s*/vgpreload_*.so", VG_(libdir));
257    mash_colon_env(ld_preload_str, buf);
258    mash_colon_env(dyld_insert_libraries_str, buf);
259    VG_(sprintf)(buf, "%s*", VG_(libdir));
260    mash_colon_env(ld_library_path_str, buf);
261 
262    // Remove VALGRIND_LAUNCHER variable.
263    VG_(env_unsetenv)(envp, VALGRIND_LAUNCHER);
264 
265    // Remove DYLD_SHARED_REGION variable.
266    VG_(env_unsetenv)(envp, "DYLD_SHARED_REGION");
267 
268    // XXX if variable becomes empty, remove it completely?
269 
270    VG_(arena_free)(VG_AR_CORE, buf);
271 }
272 
273 /* ---------------------------------------------------------------------
274    Various important syscall wrappers
275    ------------------------------------------------------------------ */
276 
VG_(waitpid)277 Int VG_(waitpid)(Int pid, Int *status, Int options)
278 {
279 #  if defined(VGO_linux)
280    SysRes res = VG_(do_syscall4)(__NR_wait4,
281                                  pid, (UWord)status, options, 0);
282    return sr_isError(res) ? -1 : sr_Res(res);
283 #  elif defined(VGO_darwin)
284    SysRes res = VG_(do_syscall4)(__NR_wait4_nocancel,
285                                  pid, (UWord)status, options, 0);
286    return sr_isError(res) ? -1 : sr_Res(res);
287 #  elif defined(VGO_aix5)
288    /* magic number 4 obtained by truss-ing a C program doing
289       'waitpid'.  Note status and pid args opposite way round from
290       POSIX. */
291    SysRes res = VG_(do_syscall5)(__NR_AIX5_kwaitpid,
292                                  (UWord)status, pid, 4 | options,0,0);
293    if (0) VG_(printf)("waitpid: got 0x%lx 0x%lx\n", sr_Res(res), res.err);
294    return sr_isError(res) ? -1 : sr_Res(res);
295 #  else
296 #    error Unknown OS
297 #  endif
298 }
299 
300 /* clone the environment */
VG_(env_clone)301 Char **VG_(env_clone) ( Char **oldenv )
302 {
303    Char **oldenvp;
304    Char **newenvp;
305    Char **newenv;
306    Int  envlen;
307 
308    for (oldenvp = oldenv; oldenvp && *oldenvp; oldenvp++);
309 
310    envlen = oldenvp - oldenv + 1;
311 
312    newenv = VG_(arena_malloc)(VG_AR_CORE, "libcproc.ec.1",
313                               envlen * sizeof(Char **));
314 
315    oldenvp = oldenv;
316    newenvp = newenv;
317 
318    while (oldenvp && *oldenvp) {
319       *newenvp++ = *oldenvp++;
320    }
321 
322    *newenvp = *oldenvp;
323 
324    return newenv;
325 }
326 
VG_(execv)327 void VG_(execv) ( Char* filename, Char** argv )
328 {
329    Char** envp;
330    SysRes res;
331 
332    /* restore the DATA rlimit for the child */
333    VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
334 
335    envp = VG_(env_clone)(VG_(client_envp));
336    VG_(env_remove_valgrind_env_stuff)( envp );
337 
338    res = VG_(do_syscall3)(__NR_execve,
339                           (UWord)filename, (UWord)argv, (UWord)envp);
340 
341    VG_(printf)("EXEC failed, errno = %lld\n", (Long)sr_Err(res));
342 }
343 
344 /* Return -1 if error, else 0.  NOTE does not indicate return code of
345    child! */
VG_(system)346 Int VG_(system) ( Char* cmd )
347 {
348    Int pid;
349    if (cmd == NULL)
350       return 1;
351    pid = VG_(fork)();
352    if (pid < 0)
353       return -1;
354    if (pid == 0) {
355       /* child */
356       Char* argv[4] = { "/bin/sh", "-c", cmd, 0 };
357       VG_(execv)(argv[0], argv);
358 
359       /* If we're still alive here, execve failed. */
360       VG_(exit)(1);
361    } else {
362       /* parent */
363       /* We have to set SIGCHLD to its default behaviour in order that
364          VG_(waitpid) works (at least on AIX).  According to the Linux
365          man page for waitpid:
366 
367          POSIX.1-2001 specifies that if the disposition of SIGCHLD is
368          set to SIG_IGN or the SA_NOCLDWAIT flag is set for SIGCHLD
369          (see sigaction(2)), then children that terminate do not
370          become zombies and a call to wait() or waitpid() will block
371          until all children have terminated, and then fail with errno
372          set to ECHILD.  (The original POSIX standard left the
373          behaviour of setting SIGCHLD to SIG_IGN unspecified.)
374       */
375       Int ir, zzz;
376       vki_sigaction_toK_t sa, sa2;
377       vki_sigaction_fromK_t saved_sa;
378       VG_(memset)( &sa, 0, sizeof(sa) );
379       VG_(sigemptyset)(&sa.sa_mask);
380       sa.ksa_handler = VKI_SIG_DFL;
381       sa.sa_flags    = 0;
382       ir = VG_(sigaction)(VKI_SIGCHLD, &sa, &saved_sa);
383       vg_assert(ir == 0);
384 
385       zzz = VG_(waitpid)(pid, NULL, 0);
386 
387       VG_(convert_sigaction_fromK_to_toK)( &saved_sa, &sa2 );
388       ir = VG_(sigaction)(VKI_SIGCHLD, &sa2, NULL);
389       vg_assert(ir == 0);
390       return zzz == -1 ? -1 : 0;
391    }
392 }
393 
394 /* ---------------------------------------------------------------------
395    Resource limits
396    ------------------------------------------------------------------ */
397 
398 /* Support for getrlimit. */
VG_(getrlimit)399 Int VG_(getrlimit) (Int resource, struct vki_rlimit *rlim)
400 {
401    SysRes res = VG_(mk_SysRes_Error)(VKI_ENOSYS);
402    /* res = getrlimit( resource, rlim ); */
403 #  ifdef __NR_ugetrlimit
404    res = VG_(do_syscall2)(__NR_ugetrlimit, resource, (UWord)rlim);
405 #  endif
406    if (sr_isError(res) && sr_Err(res) == VKI_ENOSYS)
407       res = VG_(do_syscall2)(__NR_getrlimit, resource, (UWord)rlim);
408    return sr_isError(res) ? -1 : sr_Res(res);
409 }
410 
411 
412 /* Support for setrlimit. */
VG_(setrlimit)413 Int VG_(setrlimit) (Int resource, const struct vki_rlimit *rlim)
414 {
415    SysRes res;
416    /* res = setrlimit( resource, rlim ); */
417    res = VG_(do_syscall2)(__NR_setrlimit, resource, (UWord)rlim);
418    return sr_isError(res) ? -1 : sr_Res(res);
419 }
420 
421 /* ---------------------------------------------------------------------
422    pids, etc
423    ------------------------------------------------------------------ */
424 
VG_(gettid)425 Int VG_(gettid)(void)
426 {
427 #  if defined(VGO_linux)
428    SysRes res = VG_(do_syscall0)(__NR_gettid);
429 
430    if (sr_isError(res) && sr_Res(res) == VKI_ENOSYS) {
431       Char pid[16];
432       /*
433        * The gettid system call does not exist. The obvious assumption
434        * to make at this point would be that we are running on an older
435        * system where the getpid system call actually returns the ID of
436        * the current thread.
437        *
438        * Unfortunately it seems that there are some systems with a kernel
439        * where getpid has been changed to return the ID of the thread group
440        * leader but where the gettid system call has not yet been added.
441        *
442        * So instead of calling getpid here we use readlink to see where
443        * the /proc/self link is pointing...
444        */
445 
446       res = VG_(do_syscall3)(__NR_readlink, (UWord)"/proc/self",
447                              (UWord)pid, sizeof(pid));
448       if (!sr_isError(res) && sr_Res(res) > 0) {
449          Char* s;
450          pid[sr_Res(res)] = '\0';
451          res = VG_(mk_SysRes_Success)(  VG_(strtoll10)(pid, &s) );
452          if (*s != '\0') {
453             VG_(message)(Vg_DebugMsg,
454                "Warning: invalid file name linked to by /proc/self: %s\n",
455                pid);
456          }
457       }
458    }
459 
460    return sr_Res(res);
461 
462 #  elif defined(VGO_aix5)
463    SysRes res;
464    Int    r;
465    vg_assert(__NR_AIX5__thread_self != __NR_AIX5_UNKNOWN);
466    res = VG_(do_syscall0)(__NR_AIX5__thread_self);
467    r = sr_Res(res);
468    return r;
469 
470 #  elif defined(VGO_darwin)
471    // Darwin's gettid syscall is something else.
472    // Use Mach thread ports for lwpid instead.
473    return mach_thread_self();
474 
475 #  else
476 #    error "Unknown OS"
477 #  endif
478 }
479 
480 /* You'd be amazed how many places need to know the current pid. */
VG_(getpid)481 Int VG_(getpid) ( void )
482 {
483    /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
484    return sr_Res( VG_(do_syscall0)(__NR_getpid) );
485 }
486 
VG_(getpgrp)487 Int VG_(getpgrp) ( void )
488 {
489    /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
490    return sr_Res( VG_(do_syscall0)(__NR_getpgrp) );
491 }
492 
VG_(getppid)493 Int VG_(getppid) ( void )
494 {
495    /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
496    return sr_Res( VG_(do_syscall0)(__NR_getppid) );
497 }
498 
VG_(geteuid)499 Int VG_(geteuid) ( void )
500 {
501    /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
502 #  if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
503    return sr_Res( VG_(do_syscall1)(__NR_AIX5_getuidx, 1) );
504 #  elif defined(__NR_geteuid32)
505    // We use the 32-bit version if it's supported.  Otherwise, IDs greater
506    // than 65536 cause problems, as bug #151209 showed.
507    return sr_Res( VG_(do_syscall0)(__NR_geteuid32) );
508 #  else
509    return sr_Res( VG_(do_syscall0)(__NR_geteuid) );
510 #  endif
511 }
512 
VG_(getegid)513 Int VG_(getegid) ( void )
514 {
515    /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
516 #  if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
517    return sr_Res( VG_(do_syscall1)(__NR_AIX5_getgidx, 1) );
518 #  elif defined(__NR_getegid32)
519    // We use the 32-bit version if it's supported.  Otherwise, IDs greater
520    // than 65536 cause problems, as bug #151209 showed.
521    return sr_Res( VG_(do_syscall0)(__NR_getegid32) );
522 #  else
523    return sr_Res( VG_(do_syscall0)(__NR_getegid) );
524 #  endif
525 }
526 
527 /* Get supplementary groups into list[0 .. size-1].  Returns the
528    number of groups written, or -1 if error.  Note that in order to be
529    portable, the groups are 32-bit unsigned ints regardless of the
530    platform. */
VG_(getgroups)531 Int VG_(getgroups)( Int size, UInt* list )
532 {
533 #  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux)
534    Int    i;
535    SysRes sres;
536    UShort list16[64];
537    if (size < 0) return -1;
538    if (size > 64) size = 64;
539    sres = VG_(do_syscall2)(__NR_getgroups, size, (Addr)list16);
540    if (sr_isError(sres))
541       return -1;
542    if (sr_Res(sres) > size)
543       return -1;
544    for (i = 0; i < sr_Res(sres); i++)
545       list[i] = (UInt)list16[i];
546    return sr_Res(sres);
547 
548 #  elif defined(VGP_amd64_linux) || defined(VGP_ppc64_linux)  \
549         || defined(VGP_arm_linux)                             \
550         || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) \
551         || defined(VGO_darwin)
552    SysRes sres;
553    sres = VG_(do_syscall2)(__NR_getgroups, size, (Addr)list);
554    if (sr_isError(sres))
555       return -1;
556    return sr_Res(sres);
557 
558 #  else
559 #     error "VG_(getgroups): needs implementation on this platform"
560 #  endif
561 }
562 
563 /* ---------------------------------------------------------------------
564    Process tracing
565    ------------------------------------------------------------------ */
566 
VG_(ptrace)567 Int VG_(ptrace) ( Int request, Int pid, void *addr, void *data )
568 {
569    SysRes res;
570    res = VG_(do_syscall4)(__NR_ptrace, request, pid, (UWord)addr, (UWord)data);
571    if (sr_isError(res))
572       return -1;
573    return sr_Res(res);
574 }
575 
576 /* ---------------------------------------------------------------------
577    Fork
578    ------------------------------------------------------------------ */
579 
VG_(fork)580 Int VG_(fork) ( void )
581 {
582 #  if defined(VGO_linux) || defined(VGO_aix5)
583    SysRes res;
584    res = VG_(do_syscall0)(__NR_fork);
585    if (sr_isError(res))
586       return -1;
587    return sr_Res(res);
588 
589 #  elif defined(VGO_darwin)
590    SysRes res;
591    res = VG_(do_syscall0)(__NR_fork); /* __NR_fork is UX64 */
592    if (sr_isError(res))
593       return -1;
594    /* on success: wLO = child pid; wHI = 1 for child, 0 for parent */
595    if (sr_ResHI(res) != 0) {
596       return 0;  /* this is child: return 0 instead of child pid */
597    }
598    return sr_Res(res);
599 
600 #  else
601 #    error "Unknown OS"
602 #  endif
603 }
604 
605 /* ---------------------------------------------------------------------
606    Timing stuff
607    ------------------------------------------------------------------ */
608 
VG_(read_millisecond_timer)609 UInt VG_(read_millisecond_timer) ( void )
610 {
611    /* 'now' and 'base' are in microseconds */
612    static ULong base = 0;
613    ULong  now;
614 
615 #  if defined(VGO_linux)
616    { SysRes res;
617      struct vki_timespec ts_now;
618      res = VG_(do_syscall2)(__NR_clock_gettime, VKI_CLOCK_MONOTONIC,
619                             (UWord)&ts_now);
620      if (sr_isError(res) == 0) {
621         now = ts_now.tv_sec * 1000000ULL + ts_now.tv_nsec / 1000;
622      } else {
623        struct vki_timeval tv_now;
624        res = VG_(do_syscall2)(__NR_gettimeofday, (UWord)&tv_now, (UWord)NULL);
625        vg_assert(! sr_isError(res));
626        now = tv_now.tv_sec * 1000000ULL + tv_now.tv_usec;
627      }
628    }
629 
630 #  elif defined(VGO_aix5)
631    /* AIX requires a totally different implementation since
632       sys_gettimeofday doesn't exist.  We use the POWER real-time
633       register facility.  This will SIGILL on PowerPC 970 on AIX,
634       since PowerPC doesn't support these instructions. */
635    UWord nsec, sec1, sec2;
636    while (1) {
637       __asm__ __volatile__ ("\n"
638          "\tmfspr %0,4\n" /* 4==RTCU */
639          "\tmfspr %1,5\n" /* 5==RTCL */
640          "\tmfspr %2,4\n" /* 4==RTCU */
641          : "=b" (sec1), "=b" (nsec), "=b" (sec2)
642       );
643       if (sec1 == sec2) break;
644    }
645    vg_assert(nsec < 1000*1000*1000);
646    now  = ((ULong)sec1) * 1000000ULL;
647    now += (ULong)(nsec / 1000);
648 
649 #  elif defined(VGO_darwin)
650    // Weird: it seems that gettimeofday() doesn't fill in the timeval, but
651    // rather returns the tv_sec as the low 32 bits of the result and the
652    // tv_usec as the high 32 bits of the result.  (But the timeval cannot be
653    // NULL!)  See bug 200990.
654    { SysRes res;
655      struct vki_timeval tv_now = { 0, 0 };
656      res = VG_(do_syscall2)(__NR_gettimeofday, (UWord)&tv_now, (UWord)NULL);
657      vg_assert(! sr_isError(res));
658      now = sr_Res(res) * 1000000ULL + sr_ResHI(res);
659    }
660 
661 #  else
662 #    error "Unknown OS"
663 #  endif
664 
665    /* COMMON CODE */
666    if (base == 0)
667       base = now;
668 
669    return (now - base) / 1000;
670 }
671 
672 
673 /* ---------------------------------------------------------------------
674    atfork()
675    ------------------------------------------------------------------ */
676 
677 struct atfork {
678    vg_atfork_t  pre;
679    vg_atfork_t  parent;
680    vg_atfork_t  child;
681 };
682 
683 #define VG_MAX_ATFORK 10
684 
685 static struct atfork atforks[VG_MAX_ATFORK];
686 static Int n_atfork = 0;
687 
VG_(atfork)688 void VG_(atfork)(vg_atfork_t pre, vg_atfork_t parent, vg_atfork_t child)
689 {
690    Int i;
691 
692    for (i = 0; i < n_atfork; i++) {
693       if (atforks[i].pre == pre &&
694           atforks[i].parent == parent &&
695           atforks[i].child == child)
696          return;
697    }
698 
699    if (n_atfork >= VG_MAX_ATFORK)
700       VG_(core_panic)(
701          "Too many VG_(atfork) handlers requested: raise VG_MAX_ATFORK");
702 
703    atforks[n_atfork].pre    = pre;
704    atforks[n_atfork].parent = parent;
705    atforks[n_atfork].child  = child;
706 
707    n_atfork++;
708 }
709 
VG_(do_atfork_pre)710 void VG_(do_atfork_pre)(ThreadId tid)
711 {
712    Int i;
713 
714    for (i = 0; i < n_atfork; i++)
715       if (atforks[i].pre != NULL)
716          (*atforks[i].pre)(tid);
717 }
718 
VG_(do_atfork_parent)719 void VG_(do_atfork_parent)(ThreadId tid)
720 {
721    Int i;
722 
723    for (i = 0; i < n_atfork; i++)
724       if (atforks[i].parent != NULL)
725          (*atforks[i].parent)(tid);
726 }
727 
728 // Defined in m_main.c
729 void print_preamble(Bool logging_to_fd, const char* toolname);
730 
731 Char* VG_(clo_log_fname_unexpanded) = NULL;
732 Char* VG_(clo_xml_fname_unexpanded) = NULL;
733 
734 // If --log-file=ABC%pXYZ is specified, we'd like to have separate log files
735 // for each forked child.
736 // If %p is present in the --log-file option, this function creates
737 // a new log file and redirects the child's output to it.
open_new_logfile_for_forked_child(void)738 static void open_new_logfile_for_forked_child(void)
739 {
740    Int tmp_fd = -1;
741 
742    if (VG_(log_output_sink).is_socket == False && VG_(clo_log_fname_unexpanded) != NULL) {
743      tmp_fd = reopen_output_fd(False);
744      VG_(log_output_sink).fd = VG_(safe_fd)(tmp_fd);
745    }
746 
747    if (VG_(xml_output_sink).is_socket == False && VG_(clo_xml_fname_unexpanded) != NULL) {
748      tmp_fd = reopen_output_fd(True);
749      VG_(xml_output_sink).fd = VG_(safe_fd)(tmp_fd);
750    }
751 
752    print_preamble(False, NULL);
753 }
754 
VG_(do_atfork_child)755 void VG_(do_atfork_child)(ThreadId tid)
756 {
757    Int i;
758 
759    open_new_logfile_for_forked_child();
760 
761    for (i = 0; i < n_atfork; i++)
762       if (atforks[i].child != NULL)
763          (*atforks[i].child)(tid);
764 }
765 
766 
767 /*--------------------------------------------------------------------*/
768 /*--- end                                                          ---*/
769 /*--------------------------------------------------------------------*/
770