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