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-2013 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 HChar** VG_(client_envp) = NULL;
     64 
     65 /* Path to library directory */
     66 const HChar *VG_(libdir) = VG_LIBDIR;
     67 
     68 const HChar *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 HChar *VG_(getenv)(const HChar *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       HChar* 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) ( HChar **env, const HChar *varname )
     94 {
     95    HChar **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 HChar **VG_(env_setenv) ( HChar ***envp, const HChar* varname,
    112                           const HChar *val )
    113 {
    114    HChar **env = (*envp);
    115    HChar **cpp;
    116    Int len = VG_(strlen)(varname);
    117    HChar *valstr = VG_(arena_malloc)(VG_AR_CORE, "libcproc.es.1",
    118                                      len + VG_(strlen)(val) + 2);
    119    HChar **oldenv = NULL;
    120 
    121    VG_(sprintf)(valstr, "%s=%s", varname, val);
    122 
    123    for (cpp = env; cpp && *cpp; cpp++) {
    124       if (VG_(strncmp)(varname, *cpp, len) == 0 && (*cpp)[len] == '=') {
    125 	 *cpp = valstr;
    126 	 return oldenv;
    127       }
    128    }
    129 
    130    if (env == NULL) {
    131       env = VG_(arena_malloc)(VG_AR_CORE, "libcproc.es.2", sizeof(HChar *) * 2);
    132       env[0] = valstr;
    133       env[1] = NULL;
    134 
    135       *envp = env;
    136 
    137    }  else {
    138       Int envlen = (cpp-env) + 2;
    139       HChar **newenv = VG_(arena_malloc)(VG_AR_CORE, "libcproc.es.3",
    140                                          envlen * sizeof(HChar *));
    141 
    142       for (cpp = newenv; *env; )
    143 	 *cpp++ = *env++;
    144       *cpp++ = valstr;
    145       *cpp++ = NULL;
    146 
    147       oldenv = *envp;
    148 
    149       *envp = newenv;
    150    }
    151 
    152    return oldenv;
    153 }
    154 
    155 
    156 /* Walk through a colon-separated environment variable, and remove the
    157    entries which match remove_pattern.  It slides everything down over
    158    the removed entries, and pads the remaining space with '\0'.  It
    159    modifies the entries in place (in the client address space), but it
    160    shouldn't matter too much, since we only do this just before an
    161    execve().
    162 
    163    This is also careful to mop up any excess ':'s, since empty strings
    164    delimited by ':' are considered to be '.' in a path.
    165 */
    166 static void mash_colon_env(HChar *varp, const HChar *remove_pattern)
    167 {
    168    HChar *const start = varp;
    169    HChar *entry_start = varp;
    170    HChar *output = varp;
    171 
    172    if (varp == NULL)
    173       return;
    174 
    175    while(*varp) {
    176       if (*varp == ':') {
    177 	 HChar prev;
    178 	 Bool match;
    179 
    180 	 /* This is a bit subtle: we want to match against the entry
    181 	    we just copied, because it may have overlapped with
    182 	    itself, junking the original. */
    183 
    184 	 prev = *output;
    185 	 *output = '\0';
    186 
    187 	 match = VG_(string_match)(remove_pattern, entry_start);
    188 
    189 	 *output = prev;
    190 
    191 	 if (match) {
    192 	    output = entry_start;
    193 	    varp++;			/* skip ':' after removed entry */
    194 	 } else
    195 	    entry_start = output+1;	/* entry starts after ':' */
    196       }
    197 
    198       if (*varp)
    199          *output++ = *varp++;
    200    }
    201 
    202    /* make sure last entry is nul terminated */
    203    *output = '\0';
    204 
    205    /* match against the last entry */
    206    if (VG_(string_match)(remove_pattern, entry_start)) {
    207       output = entry_start;
    208       if (output > start) {
    209 	 /* remove trailing ':' */
    210 	 output--;
    211 	 vg_assert(*output == ':');
    212       }
    213    }
    214 
    215    /* pad out the left-overs with '\0' */
    216    while(output < varp)
    217       *output++ = '\0';
    218 }
    219 
    220 
    221 // Removes all the Valgrind-added stuff from the passed environment.  Used
    222 // when starting child processes, so they don't see that added stuff.
    223 void VG_(env_remove_valgrind_env_stuff)(HChar** envp)
    224 {
    225 
    226 #if defined(VGO_darwin)
    227 
    228    // Environment cleanup is also handled during parent launch
    229    // in vg_preloaded.c:vg_cleanup_env().
    230 
    231 #endif
    232 
    233    Int i;
    234    HChar* ld_preload_str = NULL;
    235    HChar* ld_library_path_str = NULL;
    236    HChar* dyld_insert_libraries_str = NULL;
    237    HChar* buf;
    238 
    239    // Find LD_* variables
    240    // DDD: should probably conditionally compiled some of this:
    241    // - LD_LIBRARY_PATH is universal?
    242    // - LD_PRELOAD is on Linux, not on Darwin, not sure about AIX
    243    // - DYLD_INSERT_LIBRARIES and DYLD_SHARED_REGION are Darwin-only
    244    for (i = 0; envp[i] != NULL; i++) {
    245       if (VG_(strncmp)(envp[i], "LD_PRELOAD=", 11) == 0) {
    246          envp[i] = VG_(arena_strdup)(VG_AR_CORE, "libcproc.erves.1", envp[i]);
    247          ld_preload_str = &envp[i][11];
    248       }
    249       if (VG_(strncmp)(envp[i], "LD_LIBRARY_PATH=", 16) == 0) {
    250          envp[i] = VG_(arena_strdup)(VG_AR_CORE, "libcproc.erves.2", envp[i]);
    251          ld_library_path_str = &envp[i][16];
    252       }
    253       if (VG_(strncmp)(envp[i], "DYLD_INSERT_LIBRARIES=", 22) == 0) {
    254          envp[i] = VG_(arena_strdup)(VG_AR_CORE, "libcproc.erves.3", envp[i]);
    255          dyld_insert_libraries_str = &envp[i][22];
    256       }
    257    }
    258 
    259    buf = VG_(arena_malloc)(VG_AR_CORE, "libcproc.erves.4",
    260                            VG_(strlen)(VG_(libdir)) + 20);
    261 
    262    // Remove Valgrind-specific entries from LD_*.
    263    VG_(sprintf)(buf, "%s*/vgpreload_*.so", VG_(libdir));
    264    mash_colon_env(ld_preload_str, buf);
    265    mash_colon_env(dyld_insert_libraries_str, buf);
    266    VG_(sprintf)(buf, "%s*", VG_(libdir));
    267    mash_colon_env(ld_library_path_str, buf);
    268 
    269    // Remove VALGRIND_LAUNCHER variable.
    270    VG_(env_unsetenv)(envp, VALGRIND_LAUNCHER);
    271 
    272    // Remove DYLD_SHARED_REGION variable.
    273    VG_(env_unsetenv)(envp, "DYLD_SHARED_REGION");
    274 
    275    // XXX if variable becomes empty, remove it completely?
    276 
    277    VG_(arena_free)(VG_AR_CORE, buf);
    278 }
    279 
    280 /* ---------------------------------------------------------------------
    281    Various important syscall wrappers
    282    ------------------------------------------------------------------ */
    283 
    284 Int VG_(waitpid)(Int pid, Int *status, Int options)
    285 {
    286 #  if defined(VGO_linux)
    287    SysRes res = VG_(do_syscall4)(__NR_wait4,
    288                                  pid, (UWord)status, options, 0);
    289    return sr_isError(res) ? -1 : sr_Res(res);
    290 #  elif defined(VGO_darwin)
    291    SysRes res = VG_(do_syscall4)(__NR_wait4_nocancel,
    292                                  pid, (UWord)status, options, 0);
    293    return sr_isError(res) ? -1 : sr_Res(res);
    294 #  else
    295 #    error Unknown OS
    296 #  endif
    297 }
    298 
    299 /* clone the environment */
    300 HChar **VG_(env_clone) ( HChar **oldenv )
    301 {
    302    HChar **oldenvp;
    303    HChar **newenvp;
    304    HChar **newenv;
    305    Int  envlen;
    306 
    307    vg_assert(oldenv);
    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(HChar *));
    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 
    327 void VG_(execv) ( const HChar* filename, HChar** argv )
    328 {
    329    HChar** 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! */
    346 Int VG_(system) ( const HChar* 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       const HChar* argv[4] = { "/bin/sh", "-c", cmd, 0 };
    357       VG_(execv)(argv[0], (HChar **)argv);
    358 
    359       /* If we're still alive here, execv 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. */
    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. */
    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 /* Support for prctl. */
    422 Int VG_(prctl) (Int option,
    423                 ULong arg2, ULong arg3, ULong arg4, ULong arg5)
    424 {
    425    SysRes res = VG_(mk_SysRes_Error)(VKI_ENOSYS);
    426 #  if defined(VGO_linux)
    427    /* res = prctl( option, arg2, arg3, arg4, arg5 ); */
    428    res = VG_(do_syscall5)(__NR_prctl, (UWord) option,
    429                           (UWord) arg2, (UWord) arg3, (UWord) arg4,
    430                           (UWord) arg5);
    431 #  endif
    432 
    433    return sr_isError(res) ? -1 : sr_Res(res);
    434 }
    435 
    436 /* ---------------------------------------------------------------------
    437    pids, etc
    438    ------------------------------------------------------------------ */
    439 
    440 Int VG_(gettid)(void)
    441 {
    442 #  if defined(VGO_linux)
    443    SysRes res = VG_(do_syscall0)(__NR_gettid);
    444 
    445    if (sr_isError(res) && sr_Res(res) == VKI_ENOSYS) {
    446       HChar pid[16];
    447       /*
    448        * The gettid system call does not exist. The obvious assumption
    449        * to make at this point would be that we are running on an older
    450        * system where the getpid system call actually returns the ID of
    451        * the current thread.
    452        *
    453        * Unfortunately it seems that there are some systems with a kernel
    454        * where getpid has been changed to return the ID of the thread group
    455        * leader but where the gettid system call has not yet been added.
    456        *
    457        * So instead of calling getpid here we use readlink to see where
    458        * the /proc/self link is pointing...
    459        */
    460 
    461 #     if defined(VGP_arm64_linux)
    462       res = VG_(do_syscall4)(__NR_readlinkat, VKI_AT_FDCWD,
    463                              (UWord)"/proc/self",
    464                              (UWord)pid, sizeof(pid));
    465 #     else
    466       res = VG_(do_syscall3)(__NR_readlink, (UWord)"/proc/self",
    467                              (UWord)pid, sizeof(pid));
    468 #     endif
    469       if (!sr_isError(res) && sr_Res(res) > 0) {
    470          HChar* s;
    471          pid[sr_Res(res)] = '\0';
    472          res = VG_(mk_SysRes_Success)(  VG_(strtoll10)(pid, &s) );
    473          if (*s != '\0') {
    474             VG_(message)(Vg_DebugMsg,
    475                "Warning: invalid file name linked to by /proc/self: %s\n",
    476                pid);
    477          }
    478       }
    479    }
    480 
    481    return sr_Res(res);
    482 
    483 #  elif defined(VGO_darwin)
    484    // Darwin's gettid syscall is something else.
    485    // Use Mach thread ports for lwpid instead.
    486    return mach_thread_self();
    487 
    488 #  else
    489 #    error "Unknown OS"
    490 #  endif
    491 }
    492 
    493 /* You'd be amazed how many places need to know the current pid. */
    494 Int VG_(getpid) ( void )
    495 {
    496    /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
    497    return sr_Res( VG_(do_syscall0)(__NR_getpid) );
    498 }
    499 
    500 Int VG_(getpgrp) ( void )
    501 {
    502    /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
    503    return sr_Res( VG_(do_syscall0)(__NR_getpgrp) );
    504 }
    505 
    506 Int VG_(getppid) ( void )
    507 {
    508    /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
    509    return sr_Res( VG_(do_syscall0)(__NR_getppid) );
    510 }
    511 
    512 Int VG_(geteuid) ( void )
    513 {
    514    /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
    515 #  if defined(__NR_geteuid32)
    516    // We use the 32-bit version if it's supported.  Otherwise, IDs greater
    517    // than 65536 cause problems, as bug #151209 showed.
    518    return sr_Res( VG_(do_syscall0)(__NR_geteuid32) );
    519 #  else
    520    return sr_Res( VG_(do_syscall0)(__NR_geteuid) );
    521 #  endif
    522 }
    523 
    524 Int VG_(getegid) ( void )
    525 {
    526    /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
    527 #  if defined(__NR_getegid32)
    528    // We use the 32-bit version if it's supported.  Otherwise, IDs greater
    529    // than 65536 cause problems, as bug #151209 showed.
    530    return sr_Res( VG_(do_syscall0)(__NR_getegid32) );
    531 #  else
    532    return sr_Res( VG_(do_syscall0)(__NR_getegid) );
    533 #  endif
    534 }
    535 
    536 /* Get supplementary groups into list[0 .. size-1].  Returns the
    537    number of groups written, or -1 if error.  Note that in order to be
    538    portable, the groups are 32-bit unsigned ints regardless of the
    539    platform. */
    540 Int VG_(getgroups)( Int size, UInt* list )
    541 {
    542 #  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
    543       || defined(VGP_mips64_linux)
    544    Int    i;
    545    SysRes sres;
    546    UShort list16[64];
    547    if (size < 0) return -1;
    548    if (size > 64) size = 64;
    549    sres = VG_(do_syscall2)(__NR_getgroups, size, (Addr)list16);
    550    if (sr_isError(sres))
    551       return -1;
    552    if (sr_Res(sres) > size)
    553       return -1;
    554    for (i = 0; i < sr_Res(sres); i++)
    555       list[i] = (UInt)list16[i];
    556    return sr_Res(sres);
    557 
    558 #  elif defined(VGP_amd64_linux) || defined(VGP_ppc64_linux)  \
    559         || defined(VGP_arm_linux)                             \
    560         || defined(VGO_darwin) || defined(VGP_s390x_linux)    \
    561         || defined(VGP_mips32_linux) || defined(VGP_arm64_linux)
    562    SysRes sres;
    563    sres = VG_(do_syscall2)(__NR_getgroups, size, (Addr)list);
    564    if (sr_isError(sres))
    565       return -1;
    566    return sr_Res(sres);
    567 
    568 #  else
    569 #     error "VG_(getgroups): needs implementation on this platform"
    570 #  endif
    571 }
    572 
    573 /* ---------------------------------------------------------------------
    574    Process tracing
    575    ------------------------------------------------------------------ */
    576 
    577 Int VG_(ptrace) ( Int request, Int pid, void *addr, void *data )
    578 {
    579    SysRes res;
    580    res = VG_(do_syscall4)(__NR_ptrace, request, pid, (UWord)addr, (UWord)data);
    581    if (sr_isError(res))
    582       return -1;
    583    return sr_Res(res);
    584 }
    585 
    586 /* ---------------------------------------------------------------------
    587    Fork
    588    ------------------------------------------------------------------ */
    589 
    590 Int VG_(fork) ( void )
    591 {
    592 #  if defined(VGO_linux)
    593    SysRes res;
    594    res = VG_(do_syscall0)(__NR_fork);
    595    if (sr_isError(res))
    596       return -1;
    597    return sr_Res(res);
    598 
    599 #  elif defined(VGO_darwin)
    600    SysRes res;
    601    res = VG_(do_syscall0)(__NR_fork); /* __NR_fork is UX64 */
    602    if (sr_isError(res))
    603       return -1;
    604    /* on success: wLO = child pid; wHI = 1 for child, 0 for parent */
    605    if (sr_ResHI(res) != 0) {
    606       return 0;  /* this is child: return 0 instead of child pid */
    607    }
    608    return sr_Res(res);
    609 
    610 #  else
    611 #    error "Unknown OS"
    612 #  endif
    613 }
    614 
    615 /* ---------------------------------------------------------------------
    616    Timing stuff
    617    ------------------------------------------------------------------ */
    618 
    619 UInt VG_(read_millisecond_timer) ( void )
    620 {
    621    /* 'now' and 'base' are in microseconds */
    622    static ULong base = 0;
    623    ULong  now;
    624 
    625 #  if defined(VGO_linux)
    626    { SysRes res;
    627      struct vki_timespec ts_now;
    628      res = VG_(do_syscall2)(__NR_clock_gettime, VKI_CLOCK_MONOTONIC,
    629                             (UWord)&ts_now);
    630      if (sr_isError(res) == 0) {
    631         now = ts_now.tv_sec * 1000000ULL + ts_now.tv_nsec / 1000;
    632      } else {
    633        struct vki_timeval tv_now;
    634        res = VG_(do_syscall2)(__NR_gettimeofday, (UWord)&tv_now, (UWord)NULL);
    635        vg_assert(! sr_isError(res));
    636        now = tv_now.tv_sec * 1000000ULL + tv_now.tv_usec;
    637      }
    638    }
    639 
    640 #  elif defined(VGO_darwin)
    641    // Weird: it seems that gettimeofday() doesn't fill in the timeval, but
    642    // rather returns the tv_sec as the low 32 bits of the result and the
    643    // tv_usec as the high 32 bits of the result.  (But the timeval cannot be
    644    // NULL!)  See bug 200990.
    645    { SysRes res;
    646      struct vki_timeval tv_now = { 0, 0 };
    647      res = VG_(do_syscall2)(__NR_gettimeofday, (UWord)&tv_now, (UWord)NULL);
    648      vg_assert(! sr_isError(res));
    649      now = sr_Res(res) * 1000000ULL + sr_ResHI(res);
    650    }
    651 
    652 #  else
    653 #    error "Unknown OS"
    654 #  endif
    655 
    656    /* COMMON CODE */
    657    if (base == 0)
    658       base = now;
    659 
    660    return (now - base) / 1000;
    661 }
    662 
    663 
    664 /* ---------------------------------------------------------------------
    665    atfork()
    666    ------------------------------------------------------------------ */
    667 
    668 struct atfork {
    669    vg_atfork_t  pre;
    670    vg_atfork_t  parent;
    671    vg_atfork_t  child;
    672 };
    673 
    674 #define VG_MAX_ATFORK 10
    675 
    676 static struct atfork atforks[VG_MAX_ATFORK];
    677 static Int n_atfork = 0;
    678 
    679 void VG_(atfork)(vg_atfork_t pre, vg_atfork_t parent, vg_atfork_t child)
    680 {
    681    Int i;
    682 
    683    for (i = 0; i < n_atfork; i++) {
    684       if (atforks[i].pre == pre &&
    685           atforks[i].parent == parent &&
    686           atforks[i].child == child)
    687          return;
    688    }
    689 
    690    if (n_atfork >= VG_MAX_ATFORK)
    691       VG_(core_panic)(
    692          "Too many VG_(atfork) handlers requested: raise VG_MAX_ATFORK");
    693 
    694    atforks[n_atfork].pre    = pre;
    695    atforks[n_atfork].parent = parent;
    696    atforks[n_atfork].child  = child;
    697 
    698    n_atfork++;
    699 }
    700 
    701 void VG_(do_atfork_pre)(ThreadId tid)
    702 {
    703    Int i;
    704 
    705    for (i = 0; i < n_atfork; i++)
    706       if (atforks[i].pre != NULL)
    707          (*atforks[i].pre)(tid);
    708 }
    709 
    710 void VG_(do_atfork_parent)(ThreadId tid)
    711 {
    712    Int i;
    713 
    714    for (i = 0; i < n_atfork; i++)
    715       if (atforks[i].parent != NULL)
    716          (*atforks[i].parent)(tid);
    717 }
    718 
    719 void VG_(do_atfork_child)(ThreadId tid)
    720 {
    721    Int i;
    722 
    723    for (i = 0; i < n_atfork; i++)
    724       if (atforks[i].child != NULL)
    725          (*atforks[i].child)(tid);
    726 }
    727 
    728 
    729 /* ---------------------------------------------------------------------
    730    icache invalidation
    731    ------------------------------------------------------------------ */
    732 
    733 void VG_(invalidate_icache) ( void *ptr, SizeT nbytes )
    734 {
    735    if (nbytes == 0) return;    // nothing to do
    736 
    737    // Get cache info
    738    VexArchInfo vai;
    739    VG_(machine_get_VexArchInfo)(NULL, &vai);
    740 
    741    // If I-caches are coherent, nothing needs to be done here
    742    if (vai.hwcache_info.icaches_maintain_coherence) return;
    743 
    744 #  if defined(VGA_ppc32) || defined(VGA_ppc64)
    745    Addr startaddr = (Addr) ptr;
    746    Addr endaddr   = startaddr + nbytes;
    747    Addr cls;
    748    Addr addr;
    749 
    750    VG_(machine_get_VexArchInfo)( NULL, &vai );
    751    cls = vai.ppc_icache_line_szB;
    752 
    753    /* Stay sane .. */
    754    vg_assert(cls == 16 || cls == 32 || cls == 64 || cls == 128);
    755 
    756    startaddr &= ~(cls - 1);
    757    for (addr = startaddr; addr < endaddr; addr += cls) {
    758       __asm__ __volatile__("dcbst 0,%0" : : "r" (addr));
    759    }
    760    __asm__ __volatile__("sync");
    761    for (addr = startaddr; addr < endaddr; addr += cls) {
    762       __asm__ __volatile__("icbi 0,%0" : : "r" (addr));
    763    }
    764    __asm__ __volatile__("sync; isync");
    765 
    766 #  elif defined(VGP_arm_linux)
    767    /* ARM cache flushes are privileged, so we must defer to the kernel. */
    768    Addr startaddr = (Addr) ptr;
    769    Addr endaddr   = startaddr + nbytes;
    770    VG_(do_syscall2)(__NR_ARM_cacheflush, startaddr, endaddr);
    771 
    772 #  elif defined(VGP_arm64_linux)
    773    // This arm64_linux section of this function VG_(invalidate_icache)
    774    // is copied from
    775    // https://github.com/armvixl/vixl/blob/master/src/a64/cpu-a64.cc
    776    // which has the following copyright notice:
    777    /*
    778    Copyright 2013, ARM Limited
    779    All rights reserved.
    780 
    781    Redistribution and use in source and binary forms, with or without
    782    modification, are permitted provided that the following conditions are met:
    783 
    784    * Redistributions of source code must retain the above copyright notice,
    785      this list of conditions and the following disclaimer.
    786    * Redistributions in binary form must reproduce the above copyright notice,
    787      this list of conditions and the following disclaimer in the documentation
    788      and/or other materials provided with the distribution.
    789    * Neither the name of ARM Limited nor the names of its contributors may be
    790      used to endorse or promote products derived from this software without
    791      specific prior written permission.
    792 
    793    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
    794    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    795    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    796    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
    797    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    798    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    799    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
    800    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    801    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    802    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    803    */
    804 
    805    // Ask what the I and D line sizes are
    806    UInt cache_type_register;
    807    // Copy the content of the cache type register to a core register.
    808    __asm__ __volatile__ ("mrs %[ctr], ctr_el0" // NOLINT
    809                          : [ctr] "=r" (cache_type_register));
    810 
    811    const Int kDCacheLineSizeShift = 16;
    812    const Int kICacheLineSizeShift = 0;
    813    const UInt kDCacheLineSizeMask = 0xf << kDCacheLineSizeShift;
    814    const UInt kICacheLineSizeMask = 0xf << kICacheLineSizeShift;
    815 
    816    // The cache type register holds the size of the I and D caches as a power of
    817    // two.
    818    const UInt dcache_line_size_power_of_two =
    819        (cache_type_register & kDCacheLineSizeMask) >> kDCacheLineSizeShift;
    820    const UInt icache_line_size_power_of_two =
    821        (cache_type_register & kICacheLineSizeMask) >> kICacheLineSizeShift;
    822 
    823    const UInt dcache_line_size_ = 4 * (1 << dcache_line_size_power_of_two);
    824    const UInt icache_line_size_ = 4 * (1 << icache_line_size_power_of_two);
    825 
    826    Addr start = (Addr)ptr;
    827    // Sizes will be used to generate a mask big enough to cover a pointer.
    828    Addr dsize = (Addr)dcache_line_size_;
    829    Addr isize = (Addr)icache_line_size_;
    830 
    831    // Cache line sizes are always a power of 2.
    832    Addr dstart = start & ~(dsize - 1);
    833    Addr istart = start & ~(isize - 1);
    834    Addr end    = start + nbytes;
    835 
    836    __asm__ __volatile__ (
    837      // Clean every line of the D cache containing the target data.
    838      "0: \n\t"
    839      // dc : Data Cache maintenance
    840      // c : Clean
    841      // va : by (Virtual) Address
    842      // u : to the point of Unification
    843      // The point of unification for a processor is the point by which the
    844      // instruction and data caches are guaranteed to see the same copy of a
    845      // memory location. See ARM DDI 0406B page B2-12 for more information.
    846      "dc cvau, %[dline] \n\t"
    847      "add %[dline], %[dline], %[dsize] \n\t"
    848      "cmp %[dline], %[end] \n\t"
    849      "b.lt 0b \n\t"
    850      // Barrier to make sure the effect of the code above is visible to the rest
    851      // of the world.
    852      // dsb : Data Synchronisation Barrier
    853      // ish : Inner SHareable domain
    854      // The point of unification for an Inner Shareable shareability domain is
    855      // the point by which the instruction and data caches of all the processors
    856      // in that Inner Shareable shareability domain are guaranteed to see the
    857      // same copy of a memory location. See ARM DDI 0406B page B2-12 for more
    858      // information.
    859      "dsb ish \n\t"
    860      // Invalidate every line of the I cache containing the target data.
    861      "1: \n\t"
    862      // ic : instruction cache maintenance
    863      // i : invalidate
    864      // va : by address
    865      // u : to the point of unification
    866      "ic ivau, %[iline] \n\t"
    867      "add %[iline], %[iline], %[isize] \n\t"
    868      "cmp %[iline], %[end] \n\t"
    869      "b.lt 1b \n\t"
    870      // Barrier to make sure the effect of the code above is visible to the rest
    871      // of the world.
    872      "dsb ish \n\t"
    873      // Barrier to ensure any prefetching which happened before this code is
    874      // discarded.
    875      // isb : Instruction Synchronisation Barrier
    876      "isb \n\t"
    877      : [dline] "+r" (dstart),
    878        [iline] "+r" (istart)
    879      : [dsize] "r" (dsize),
    880        [isize] "r" (isize),
    881        [end] "r" (end)
    882      // This code does not write to memory but without the dependency gcc might
    883      // move this code before the code is generated.
    884      : "cc", "memory"
    885    );
    886 
    887 #  elif defined(VGA_mips32) || defined(VGA_mips64)
    888    SysRes sres = VG_(do_syscall3)(__NR_cacheflush, (UWord) ptr,
    889                                  (UWord) nbytes, (UWord) 3);
    890    vg_assert( sres._isError == 0 );
    891 
    892 #  endif
    893 }
    894 
    895 
    896 /* ---------------------------------------------------------------------
    897    dcache flushing
    898    ------------------------------------------------------------------ */
    899 
    900 void VG_(flush_dcache) ( void *ptr, SizeT nbytes )
    901 {
    902    /* Currently this is only required on ARM64. */
    903 #  if defined(VGA_arm64)
    904    Addr startaddr = (Addr) ptr;
    905    Addr endaddr   = startaddr + nbytes;
    906    Addr cls;
    907    Addr addr;
    908 
    909    ULong ctr_el0;
    910    __asm__ __volatile__ ("mrs %0, ctr_el0" : "=r"(ctr_el0));
    911    cls = 4 * (1ULL << (0xF & (ctr_el0 >> 16)));
    912 
    913    /* Stay sane .. */
    914    vg_assert(cls == 64);
    915 
    916    startaddr &= ~(cls - 1);
    917    for (addr = startaddr; addr < endaddr; addr += cls) {
    918       __asm__ __volatile__("dc cvau, %0" : : "r" (addr));
    919    }
    920    __asm__ __volatile__("dsb ish");
    921 #  endif
    922 }
    923 
    924 /*--------------------------------------------------------------------*/
    925 /*--- end                                                          ---*/
    926 /*--------------------------------------------------------------------*/
    927