Home | History | Annotate | Download | only in coregrind
      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-2012 Julian Seward
     11       jseward (at) 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_machine.h"    // For VG_(machine_get_VexArchInfo)
     33 #include "pub_core_vki.h"
     34 #include "pub_core_vkiscnums.h"
     35 #include "pub_core_libcbase.h"
     36 #include "pub_core_libcassert.h"
     37 #include "pub_core_libcprint.h"
     38 #include "pub_core_libcproc.h"
     39 #include "pub_core_libcsignal.h"
     40 #include "pub_core_seqmatch.h"
     41 #include "pub_core_mallocfree.h"
     42 #include "pub_core_syscall.h"
     43 #include "pub_core_xarray.h"
     44 #include "pub_core_clientstate.h"
     45 
     46 #if defined(VGO_darwin)
     47 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
     48 #include <mach/mach.h>   /* mach_thread_self */
     49 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
     50 #endif
     51 
     52 /* IMPORTANT: on Darwin it is essential to use the _nocancel versions
     53    of syscalls rather than the vanilla version, if a _nocancel version
     54    is available.  See docs/internals/Darwin-notes.txt for the reason
     55    why. */
     56 
     57 /* ---------------------------------------------------------------------
     58    Command line and environment stuff
     59    ------------------------------------------------------------------ */
     60 
     61 /* As deduced from sp_at_startup, the client's argc, argv[] and
     62    envp[] as extracted from the client's stack at startup-time. */
     63 Char** VG_(client_envp) = NULL;
     64 
     65 /* Path to library directory */
     66 const Char *VG_(libdir) = VG_LIBDIR;
     67 
     68 const Char *VG_(LD_PRELOAD_var_name) =
     69 #if defined(VGO_linux)
     70    "LD_PRELOAD";
     71 #elif defined(VGO_darwin)
     72    "DYLD_INSERT_LIBRARIES";
     73 #else
     74 #  error Unknown OS
     75 #endif
     76 
     77 /* We do getenv without libc's help by snooping around in
     78    VG_(client_envp) as determined at startup time. */
     79 Char *VG_(getenv)(Char *varname)
     80 {
     81    Int i, n;
     82    vg_assert( VG_(client_envp) );
     83    n = VG_(strlen)(varname);
     84    for (i = 0; VG_(client_envp)[i] != NULL; i++) {
     85       Char* s = VG_(client_envp)[i];
     86       if (VG_(strncmp)(varname, s, n) == 0 && s[n] == '=') {
     87          return & s[n+1];
     88       }
     89    }
     90    return NULL;
     91 }
     92 
     93 void  VG_(env_unsetenv) ( Char **env, const Char *varname )
     94 {
     95    Char **from, **to;
     96    vg_assert(env);
     97    vg_assert(varname);
     98    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 */
    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 */
    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.
    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          envp[i] = VG_(arena_strdup)(VG_AR_CORE, "libcproc.erves.1", envp[i]);
    246          ld_preload_str = &envp[i][11];
    247       }
    248       if (VG_(strncmp)(envp[i], "LD_LIBRARY_PATH=", 16) == 0) {
    249          envp[i] = VG_(arena_strdup)(VG_AR_CORE, "libcproc.erves.2", envp[i]);
    250          ld_library_path_str = &envp[i][16];
    251       }
    252       if (VG_(strncmp)(envp[i], "DYLD_INSERT_LIBRARIES=", 22) == 0) {
    253          envp[i] = VG_(arena_strdup)(VG_AR_CORE, "libcproc.erves.3", envp[i]);
    254          dyld_insert_libraries_str = &envp[i][22];
    255       }
    256    }
    257 
    258    buf = VG_(arena_malloc)(VG_AR_CORE, "libcproc.erves.4",
    259                            VG_(strlen)(VG_(libdir)) + 20);
    260 
    261    // Remove Valgrind-specific entries from LD_*.
    262    VG_(sprintf)(buf, "%s*/vgpreload_*.so", VG_(libdir));
    263    mash_colon_env(ld_preload_str, buf);
    264    mash_colon_env(dyld_insert_libraries_str, buf);
    265    VG_(sprintf)(buf, "%s*", VG_(libdir));
    266    mash_colon_env(ld_library_path_str, buf);
    267 
    268    // Remove VALGRIND_LAUNCHER variable.
    269    VG_(env_unsetenv)(envp, VALGRIND_LAUNCHER);
    270 
    271    // Remove DYLD_SHARED_REGION variable.
    272    VG_(env_unsetenv)(envp, "DYLD_SHARED_REGION");
    273 
    274    // XXX if variable becomes empty, remove it completely?
    275 
    276    VG_(arena_free)(VG_AR_CORE, buf);
    277 }
    278 
    279 /* ---------------------------------------------------------------------
    280    Various important syscall wrappers
    281    ------------------------------------------------------------------ */
    282 
    283 Int VG_(waitpid)(Int pid, Int *status, Int options)
    284 {
    285 #  if defined(VGO_linux)
    286    SysRes res = VG_(do_syscall4)(__NR_wait4,
    287                                  pid, (UWord)status, options, 0);
    288    return sr_isError(res) ? -1 : sr_Res(res);
    289 #  elif defined(VGO_darwin)
    290    SysRes res = VG_(do_syscall4)(__NR_wait4_nocancel,
    291                                  pid, (UWord)status, options, 0);
    292    return sr_isError(res) ? -1 : sr_Res(res);
    293 #  else
    294 #    error Unknown OS
    295 #  endif
    296 }
    297 
    298 /* clone the environment */
    299 Char **VG_(env_clone) ( Char **oldenv )
    300 {
    301    Char **oldenvp;
    302    Char **newenvp;
    303    Char **newenv;
    304    Int  envlen;
    305 
    306    vg_assert(oldenv);
    307    for (oldenvp = oldenv; oldenvp && *oldenvp; oldenvp++);
    308 
    309    envlen = oldenvp - oldenv + 1;
    310 
    311    newenv = VG_(arena_malloc)(VG_AR_CORE, "libcproc.ec.1",
    312                               envlen * sizeof(Char **));
    313 
    314    oldenvp = oldenv;
    315    newenvp = newenv;
    316 
    317    while (oldenvp && *oldenvp) {
    318       *newenvp++ = *oldenvp++;
    319    }
    320 
    321    *newenvp = *oldenvp;
    322 
    323    return newenv;
    324 }
    325 
    326 void VG_(execv) ( Char* filename, Char** argv )
    327 {
    328    Char** envp;
    329    SysRes res;
    330 
    331    /* restore the DATA rlimit for the child */
    332    VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
    333 
    334    envp = VG_(env_clone)(VG_(client_envp));
    335    VG_(env_remove_valgrind_env_stuff)( envp );
    336 
    337    res = VG_(do_syscall3)(__NR_execve,
    338                           (UWord)filename, (UWord)argv, (UWord)envp);
    339 
    340    VG_(printf)("EXEC failed, errno = %lld\n", (Long)sr_Err(res));
    341 }
    342 
    343 /* Return -1 if error, else 0.  NOTE does not indicate return code of
    344    child! */
    345 Int VG_(system) ( Char* cmd )
    346 {
    347    Int pid;
    348    if (cmd == NULL)
    349       return 1;
    350    pid = VG_(fork)();
    351    if (pid < 0)
    352       return -1;
    353    if (pid == 0) {
    354       /* child */
    355       Char* argv[4] = { "/bin/sh", "-c", cmd, 0 };
    356       VG_(execv)(argv[0], argv);
    357 
    358       /* If we're still alive here, execve failed. */
    359       VG_(exit)(1);
    360    } else {
    361       /* parent */
    362       /* We have to set SIGCHLD to its default behaviour in order that
    363          VG_(waitpid) works (at least on AIX).  According to the Linux
    364          man page for waitpid:
    365 
    366          POSIX.1-2001 specifies that if the disposition of SIGCHLD is
    367          set to SIG_IGN or the SA_NOCLDWAIT flag is set for SIGCHLD
    368          (see sigaction(2)), then children that terminate do not
    369          become zombies and a call to wait() or waitpid() will block
    370          until all children have terminated, and then fail with errno
    371          set to ECHILD.  (The original POSIX standard left the
    372          behaviour of setting SIGCHLD to SIG_IGN unspecified.)
    373       */
    374       Int ir, zzz;
    375       vki_sigaction_toK_t sa, sa2;
    376       vki_sigaction_fromK_t saved_sa;
    377       VG_(memset)( &sa, 0, sizeof(sa) );
    378       VG_(sigemptyset)(&sa.sa_mask);
    379       sa.ksa_handler = VKI_SIG_DFL;
    380       sa.sa_flags    = 0;
    381       ir = VG_(sigaction)(VKI_SIGCHLD, &sa, &saved_sa);
    382       vg_assert(ir == 0);
    383 
    384       zzz = VG_(waitpid)(pid, NULL, 0);
    385 
    386       VG_(convert_sigaction_fromK_to_toK)( &saved_sa, &sa2 );
    387       ir = VG_(sigaction)(VKI_SIGCHLD, &sa2, NULL);
    388       vg_assert(ir == 0);
    389       return zzz == -1 ? -1 : 0;
    390    }
    391 }
    392 
    393 /* ---------------------------------------------------------------------
    394    Resource limits
    395    ------------------------------------------------------------------ */
    396 
    397 /* Support for getrlimit. */
    398 Int VG_(getrlimit) (Int resource, struct vki_rlimit *rlim)
    399 {
    400    SysRes res = VG_(mk_SysRes_Error)(VKI_ENOSYS);
    401    /* res = getrlimit( resource, rlim ); */
    402 #  ifdef __NR_ugetrlimit
    403    res = VG_(do_syscall2)(__NR_ugetrlimit, resource, (UWord)rlim);
    404 #  endif
    405    if (sr_isError(res) && sr_Err(res) == VKI_ENOSYS)
    406       res = VG_(do_syscall2)(__NR_getrlimit, resource, (UWord)rlim);
    407    return sr_isError(res) ? -1 : sr_Res(res);
    408 }
    409 
    410 
    411 /* Support for setrlimit. */
    412 Int VG_(setrlimit) (Int resource, const struct vki_rlimit *rlim)
    413 {
    414    SysRes res;
    415    /* res = setrlimit( resource, rlim ); */
    416    res = VG_(do_syscall2)(__NR_setrlimit, resource, (UWord)rlim);
    417    return sr_isError(res) ? -1 : sr_Res(res);
    418 }
    419 
    420 /* Support for prctl. */
    421 Int VG_(prctl) (Int option,
    422                 ULong arg2, ULong arg3, ULong arg4, ULong arg5)
    423 {
    424    SysRes res = VG_(mk_SysRes_Error)(VKI_ENOSYS);
    425 #  if defined(VGO_linux)
    426    /* res = prctl( option, arg2, arg3, arg4, arg5 ); */
    427    res = VG_(do_syscall5)(__NR_prctl, (UWord) option,
    428                           (UWord) arg2, (UWord) arg3, (UWord) arg4,
    429                           (UWord) arg5);
    430 #  endif
    431 
    432    return sr_isError(res) ? -1 : sr_Res(res);
    433 }
    434 
    435 /* ---------------------------------------------------------------------
    436    pids, etc
    437    ------------------------------------------------------------------ */
    438 
    439 Int VG_(gettid)(void)
    440 {
    441 #  if defined(VGO_linux)
    442    SysRes res = VG_(do_syscall0)(__NR_gettid);
    443 
    444    if (sr_isError(res) && sr_Res(res) == VKI_ENOSYS) {
    445       Char pid[16];
    446       /*
    447        * The gettid system call does not exist. The obvious assumption
    448        * to make at this point would be that we are running on an older
    449        * system where the getpid system call actually returns the ID of
    450        * the current thread.
    451        *
    452        * Unfortunately it seems that there are some systems with a kernel
    453        * where getpid has been changed to return the ID of the thread group
    454        * leader but where the gettid system call has not yet been added.
    455        *
    456        * So instead of calling getpid here we use readlink to see where
    457        * the /proc/self link is pointing...
    458        */
    459 
    460       res = VG_(do_syscall3)(__NR_readlink, (UWord)"/proc/self",
    461                              (UWord)pid, sizeof(pid));
    462       if (!sr_isError(res) && sr_Res(res) > 0) {
    463          Char* s;
    464          pid[sr_Res(res)] = '\0';
    465          res = VG_(mk_SysRes_Success)(  VG_(strtoll10)(pid, &s) );
    466          if (*s != '\0') {
    467             VG_(message)(Vg_DebugMsg,
    468                "Warning: invalid file name linked to by /proc/self: %s\n",
    469                pid);
    470          }
    471       }
    472    }
    473 
    474    return sr_Res(res);
    475 
    476 #  elif defined(VGO_darwin)
    477    // Darwin's gettid syscall is something else.
    478    // Use Mach thread ports for lwpid instead.
    479    return mach_thread_self();
    480 
    481 #  else
    482 #    error "Unknown OS"
    483 #  endif
    484 }
    485 
    486 /* You'd be amazed how many places need to know the current pid. */
    487 Int VG_(getpid) ( void )
    488 {
    489    /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
    490    return sr_Res( VG_(do_syscall0)(__NR_getpid) );
    491 }
    492 
    493 Int VG_(getpgrp) ( void )
    494 {
    495    /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
    496    return sr_Res( VG_(do_syscall0)(__NR_getpgrp) );
    497 }
    498 
    499 Int VG_(getppid) ( void )
    500 {
    501    /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
    502    return sr_Res( VG_(do_syscall0)(__NR_getppid) );
    503 }
    504 
    505 Int VG_(geteuid) ( void )
    506 {
    507    /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
    508 #  if defined(__NR_geteuid32)
    509    // We use the 32-bit version if it's supported.  Otherwise, IDs greater
    510    // than 65536 cause problems, as bug #151209 showed.
    511    return sr_Res( VG_(do_syscall0)(__NR_geteuid32) );
    512 #  else
    513    return sr_Res( VG_(do_syscall0)(__NR_geteuid) );
    514 #  endif
    515 }
    516 
    517 Int VG_(getegid) ( void )
    518 {
    519    /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
    520 #  if defined(__NR_getegid32)
    521    // We use the 32-bit version if it's supported.  Otherwise, IDs greater
    522    // than 65536 cause problems, as bug #151209 showed.
    523    return sr_Res( VG_(do_syscall0)(__NR_getegid32) );
    524 #  else
    525    return sr_Res( VG_(do_syscall0)(__NR_getegid) );
    526 #  endif
    527 }
    528 
    529 /* Get supplementary groups into list[0 .. size-1].  Returns the
    530    number of groups written, or -1 if error.  Note that in order to be
    531    portable, the groups are 32-bit unsigned ints regardless of the
    532    platform. */
    533 Int VG_(getgroups)( Int size, UInt* list )
    534 {
    535 #  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux)
    536    Int    i;
    537    SysRes sres;
    538    UShort list16[64];
    539    if (size < 0) return -1;
    540    if (size > 64) size = 64;
    541    sres = VG_(do_syscall2)(__NR_getgroups, size, (Addr)list16);
    542    if (sr_isError(sres))
    543       return -1;
    544    if (sr_Res(sres) > size)
    545       return -1;
    546    for (i = 0; i < sr_Res(sres); i++)
    547       list[i] = (UInt)list16[i];
    548    return sr_Res(sres);
    549 
    550 #  elif defined(VGP_amd64_linux) || defined(VGP_ppc64_linux)  \
    551         || defined(VGP_arm_linux)                             \
    552         || defined(VGO_darwin) || defined(VGP_s390x_linux)    \
    553         || defined(VGP_mips32_linux)
    554    SysRes sres;
    555    sres = VG_(do_syscall2)(__NR_getgroups, size, (Addr)list);
    556    if (sr_isError(sres))
    557       return -1;
    558    return sr_Res(sres);
    559 
    560 #  else
    561 #     error "VG_(getgroups): needs implementation on this platform"
    562 #  endif
    563 }
    564 
    565 /* ---------------------------------------------------------------------
    566    Process tracing
    567    ------------------------------------------------------------------ */
    568 
    569 Int VG_(ptrace) ( Int request, Int pid, void *addr, void *data )
    570 {
    571    SysRes res;
    572    res = VG_(do_syscall4)(__NR_ptrace, request, pid, (UWord)addr, (UWord)data);
    573    if (sr_isError(res))
    574       return -1;
    575    return sr_Res(res);
    576 }
    577 
    578 /* ---------------------------------------------------------------------
    579    Fork
    580    ------------------------------------------------------------------ */
    581 
    582 Int VG_(fork) ( void )
    583 {
    584 #  if defined(VGO_linux)
    585    SysRes res;
    586    res = VG_(do_syscall0)(__NR_fork);
    587    if (sr_isError(res))
    588       return -1;
    589    return sr_Res(res);
    590 
    591 #  elif defined(VGO_darwin)
    592    SysRes res;
    593    res = VG_(do_syscall0)(__NR_fork); /* __NR_fork is UX64 */
    594    if (sr_isError(res))
    595       return -1;
    596    /* on success: wLO = child pid; wHI = 1 for child, 0 for parent */
    597    if (sr_ResHI(res) != 0) {
    598       return 0;  /* this is child: return 0 instead of child pid */
    599    }
    600    return sr_Res(res);
    601 
    602 #  else
    603 #    error "Unknown OS"
    604 #  endif
    605 }
    606 
    607 /* ---------------------------------------------------------------------
    608    Timing stuff
    609    ------------------------------------------------------------------ */
    610 
    611 UInt VG_(read_millisecond_timer) ( void )
    612 {
    613    /* 'now' and 'base' are in microseconds */
    614    static ULong base = 0;
    615    ULong  now;
    616 
    617 #  if defined(VGO_linux)
    618    { SysRes res;
    619      struct vki_timespec ts_now;
    620      res = VG_(do_syscall2)(__NR_clock_gettime, VKI_CLOCK_MONOTONIC,
    621                             (UWord)&ts_now);
    622      if (sr_isError(res) == 0) {
    623         now = ts_now.tv_sec * 1000000ULL + ts_now.tv_nsec / 1000;
    624      } else {
    625        struct vki_timeval tv_now;
    626        res = VG_(do_syscall2)(__NR_gettimeofday, (UWord)&tv_now, (UWord)NULL);
    627        vg_assert(! sr_isError(res));
    628        now = tv_now.tv_sec * 1000000ULL + tv_now.tv_usec;
    629      }
    630    }
    631 
    632 #  elif defined(VGO_darwin)
    633    // Weird: it seems that gettimeofday() doesn't fill in the timeval, but
    634    // rather returns the tv_sec as the low 32 bits of the result and the
    635    // tv_usec as the high 32 bits of the result.  (But the timeval cannot be
    636    // NULL!)  See bug 200990.
    637    { SysRes res;
    638      struct vki_timeval tv_now = { 0, 0 };
    639      res = VG_(do_syscall2)(__NR_gettimeofday, (UWord)&tv_now, (UWord)NULL);
    640      vg_assert(! sr_isError(res));
    641      now = sr_Res(res) * 1000000ULL + sr_ResHI(res);
    642    }
    643 
    644 #  else
    645 #    error "Unknown OS"
    646 #  endif
    647 
    648    /* COMMON CODE */
    649    if (base == 0)
    650       base = now;
    651 
    652    return (now - base) / 1000;
    653 }
    654 
    655 
    656 /* ---------------------------------------------------------------------
    657    atfork()
    658    ------------------------------------------------------------------ */
    659 
    660 struct atfork {
    661    vg_atfork_t  pre;
    662    vg_atfork_t  parent;
    663    vg_atfork_t  child;
    664 };
    665 
    666 #define VG_MAX_ATFORK 10
    667 
    668 static struct atfork atforks[VG_MAX_ATFORK];
    669 static Int n_atfork = 0;
    670 
    671 void VG_(atfork)(vg_atfork_t pre, vg_atfork_t parent, vg_atfork_t child)
    672 {
    673    Int i;
    674 
    675    for (i = 0; i < n_atfork; i++) {
    676       if (atforks[i].pre == pre &&
    677           atforks[i].parent == parent &&
    678           atforks[i].child == child)
    679          return;
    680    }
    681 
    682    if (n_atfork >= VG_MAX_ATFORK)
    683       VG_(core_panic)(
    684          "Too many VG_(atfork) handlers requested: raise VG_MAX_ATFORK");
    685 
    686    atforks[n_atfork].pre    = pre;
    687    atforks[n_atfork].parent = parent;
    688    atforks[n_atfork].child  = child;
    689 
    690    n_atfork++;
    691 }
    692 
    693 void VG_(do_atfork_pre)(ThreadId tid)
    694 {
    695    Int i;
    696 
    697    for (i = 0; i < n_atfork; i++)
    698       if (atforks[i].pre != NULL)
    699          (*atforks[i].pre)(tid);
    700 }
    701 
    702 void VG_(do_atfork_parent)(ThreadId tid)
    703 {
    704    Int i;
    705 
    706    for (i = 0; i < n_atfork; i++)
    707       if (atforks[i].parent != NULL)
    708          (*atforks[i].parent)(tid);
    709 }
    710 
    711 void VG_(do_atfork_child)(ThreadId tid)
    712 {
    713    Int i;
    714 
    715    for (i = 0; i < n_atfork; i++)
    716       if (atforks[i].child != NULL)
    717          (*atforks[i].child)(tid);
    718 }
    719 
    720 
    721 /* ---------------------------------------------------------------------
    722    icache invalidation
    723    ------------------------------------------------------------------ */
    724 
    725 void VG_(invalidate_icache) ( void *ptr, SizeT nbytes )
    726 {
    727 #  if defined(VGA_ppc32) || defined(VGA_ppc64)
    728    Addr startaddr = (Addr) ptr;
    729    Addr endaddr   = startaddr + nbytes;
    730    Addr cls;
    731    Addr addr;
    732    VexArchInfo vai;
    733 
    734    if (nbytes == 0) return;
    735    vg_assert(nbytes > 0);
    736 
    737    VG_(machine_get_VexArchInfo)( NULL, &vai );
    738    cls = vai.ppc_cache_line_szB;
    739 
    740    /* Stay sane .. */
    741    vg_assert(cls == 32 || cls == 64 || cls == 128);
    742 
    743    startaddr &= ~(cls - 1);
    744    for (addr = startaddr; addr < endaddr; addr += cls) {
    745       __asm__ __volatile__("dcbst 0,%0" : : "r" (addr));
    746    }
    747    __asm__ __volatile__("sync");
    748    for (addr = startaddr; addr < endaddr; addr += cls) {
    749       __asm__ __volatile__("icbi 0,%0" : : "r" (addr));
    750    }
    751    __asm__ __volatile__("sync; isync");
    752 
    753 #  elif defined(VGA_x86)
    754    /* no need to do anything, hardware provides coherence */
    755 
    756 #  elif defined(VGA_amd64)
    757    /* no need to do anything, hardware provides coherence */
    758 
    759 #  elif defined(VGA_s390x)
    760    /* no need to do anything, hardware provides coherence */
    761 
    762 #  elif defined(VGP_arm_linux)
    763    /* ARM cache flushes are privileged, so we must defer to the kernel. */
    764    Addr startaddr = (Addr) ptr;
    765    Addr endaddr   = startaddr + nbytes;
    766    VG_(do_syscall2)(__NR_ARM_cacheflush, startaddr, endaddr);
    767 
    768 #  elif defined(VGA_mips32)
    769    SysRes sres = VG_(do_syscall3)(__NR_cacheflush, (UWord) ptr,
    770                                  (UWord) nbytes, (UWord) 3);
    771    vg_assert( sres._isError == 0 );
    772 
    773 #  else
    774 #    error "Unknown ARCH"
    775 #  endif
    776 }
    777 
    778 
    779 /*--------------------------------------------------------------------*/
    780 /*--- end                                                          ---*/
    781 /*--------------------------------------------------------------------*/
    782