Add support for the Linux io_uring system calls
[valgrind.git] / coregrind / m_libcproc.c
blob4fca35021c8ca57097e5dbce511fafebcc190cbc
2 /*--------------------------------------------------------------------*/
3 /*--- Process-related libc stuff. m_libcproc.c ---*/
4 /*--------------------------------------------------------------------*/
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
10 Copyright (C) 2000-2017 Julian Seward
11 jseward@acm.org
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.
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.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, see <http://www.gnu.org/licenses/>.
26 The GNU General Public License is contained in the file COPYING.
29 #include "pub_core_basics.h"
30 #include "pub_core_machine.h" // For VG_(machine_get_VexArchInfo)
31 #include "pub_core_vki.h"
32 #include "pub_core_vkiscnums.h"
33 #include "pub_core_libcbase.h"
34 #include "pub_core_libcassert.h"
35 #include "pub_core_libcfile.h"
36 #include "pub_core_libcprint.h"
37 #include "pub_core_libcproc.h"
38 #include "pub_core_libcsignal.h"
39 #include "pub_core_seqmatch.h"
40 #include "pub_core_mallocfree.h"
41 #include "pub_core_syscall.h"
42 #include "pub_core_xarray.h"
43 #include "pub_core_clientstate.h"
45 #if defined(VGO_darwin)
46 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
47 #include <mach/mach.h> /* mach_thread_self */
48 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
49 #endif
51 /* IMPORTANT: on Darwin it is essential to use the _nocancel versions
52 of syscalls rather than the vanilla version, if a _nocancel version
53 is available. See docs/internals/Darwin-notes.txt for the reason
54 why. */
56 /* ---------------------------------------------------------------------
57 Command line and environment stuff
58 ------------------------------------------------------------------ */
60 /* As deduced from sp_at_startup, the client's argc, argv[] and
61 envp[] as extracted from the client's stack at startup-time. */
62 HChar** VG_(client_envp) = NULL;
64 /* Path to library directory */
65 const HChar *VG_(libdir) = VG_LIBDIR;
67 const HChar *VG_(LD_PRELOAD_var_name) =
68 #if defined(VGO_linux) || defined(VGO_solaris)
69 "LD_PRELOAD";
70 #elif defined(VGO_darwin)
71 "DYLD_INSERT_LIBRARIES";
72 #else
73 # error Unknown OS
74 #endif
76 /* We do getenv without libc's help by snooping around in
77 VG_(client_envp) as determined at startup time. */
78 HChar *VG_(getenv)(const HChar *varname)
80 Int i, n;
81 vg_assert( VG_(client_envp) );
82 n = VG_(strlen)(varname);
83 for (i = 0; VG_(client_envp)[i] != NULL; i++) {
84 HChar* s = VG_(client_envp)[i];
85 if (VG_(strncmp)(varname, s, n) == 0 && s[n] == '=') {
86 return & s[n+1];
89 return NULL;
92 /* If free_fn is not NULL, it is called on "unset" environment variable. */
93 void VG_(env_unsetenv) ( HChar **env, const HChar *varname,
94 void (*free_fn) (void *) )
96 HChar **from, **to;
97 vg_assert(env);
98 vg_assert(varname);
99 to = NULL;
100 Int len = VG_(strlen)(varname);
102 for (from = to = env; from && *from; from++) {
103 if (!(VG_(strncmp)(varname, *from, len) == 0 && (*from)[len] == '=')) {
104 *to = *from;
105 to++;
106 } else if (free_fn != NULL) {
107 free_fn(*from);
110 *to = *from;
113 /* set the environment; returns the old env if a new one was allocated */
114 HChar **VG_(env_setenv) ( HChar ***envp, const HChar* varname,
115 const HChar *val )
117 HChar **env = (*envp);
118 HChar **cpp;
119 Int len = VG_(strlen)(varname);
120 HChar *valstr = VG_(malloc)("libcproc.es.1", len + VG_(strlen)(val) + 2);
121 HChar **oldenv = NULL;
123 VG_(sprintf)(valstr, "%s=%s", varname, val);
125 for (cpp = env; cpp && *cpp; cpp++) {
126 if (VG_(strncmp)(varname, *cpp, len) == 0 && (*cpp)[len] == '=') {
127 *cpp = valstr;
128 return oldenv;
132 if (env == NULL) {
133 env = VG_(malloc)("libcproc.es.2", sizeof(HChar *) * 2);
134 env[0] = valstr;
135 env[1] = NULL;
137 *envp = env;
139 } else {
140 Int envlen = (cpp-env) + 2;
141 HChar **newenv = VG_(malloc)("libcproc.es.3", envlen * sizeof(HChar *));
143 for (cpp = newenv; *env; )
144 *cpp++ = *env++;
145 *cpp++ = valstr;
146 *cpp++ = NULL;
148 oldenv = *envp;
150 *envp = newenv;
153 return oldenv;
157 /* Walk through a colon-separated environment variable, and remove the
158 entries which match remove_pattern. It slides everything down over
159 the removed entries, and pads the remaining space with '\0'. It
160 modifies the entries in place (in the client address space), but it
161 shouldn't matter too much, since we only do this just before an
162 execve().
164 This is also careful to mop up any excess ':'s, since empty strings
165 delimited by ':' are considered to be '.' in a path.
167 static void mash_colon_env(HChar *varp, const HChar *remove_pattern)
169 HChar *const start = varp;
170 HChar *entry_start = varp;
171 HChar *output = varp;
173 if (varp == NULL)
174 return;
176 while(*varp) {
177 if (*varp == ':') {
178 HChar prev;
179 Bool match;
181 /* This is a bit subtle: we want to match against the entry
182 we just copied, because it may have overlapped with
183 itself, junking the original. */
185 prev = *output;
186 *output = '\0';
188 match = VG_(string_match)(remove_pattern, entry_start);
190 *output = prev;
192 if (match) {
193 output = entry_start;
194 varp++; /* skip ':' after removed entry */
195 } else
196 entry_start = output+1; /* entry starts after ':' */
199 if (*varp)
200 *output++ = *varp++;
203 /* make sure last entry is nul terminated */
204 *output = '\0';
206 /* match against the last entry */
207 if (VG_(string_match)(remove_pattern, entry_start)) {
208 output = entry_start;
209 if (output > start) {
210 /* remove trailing ':' */
211 output--;
212 vg_assert(*output == ':');
216 /* pad out the left-overs with '\0' */
217 while(output < varp)
218 *output++ = '\0';
222 /* Removes all the Valgrind-added stuff from the passed environment. Used
223 when starting child processes, so they don't see that added stuff.
224 If the ro_strings option is set to True then all strings referenced by envp
225 are considered read-only, which means they will be duplicated before they
226 are modified.
227 If free_fn is not NULL, it is called on "unset" environment variables. */
228 void VG_(env_remove_valgrind_env_stuff)(HChar** envp, Bool ro_strings,
229 void (*free_fn) (void *) )
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;
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 if (ro_strings)
245 envp[i] = VG_(strdup)("libcproc.erves.1", envp[i]);
246 ld_preload_str = &envp[i][11];
248 if (VG_(strncmp)(envp[i], "LD_LIBRARY_PATH=", 16) == 0) {
249 if (ro_strings)
250 envp[i] = VG_(strdup)("libcproc.erves.2", envp[i]);
251 ld_library_path_str = &envp[i][16];
253 if (VG_(strncmp)(envp[i], "DYLD_INSERT_LIBRARIES=", 22) == 0) {
254 if (ro_strings)
255 envp[i] = VG_(strdup)("libcproc.erves.3", envp[i]);
256 dyld_insert_libraries_str = &envp[i][22];
260 buf = VG_(malloc)("libcproc.erves.4", VG_(strlen)(VG_(libdir)) + 20);
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);
269 // Remove VALGRIND_LAUNCHER variable.
270 VG_(env_unsetenv)(envp, VALGRIND_LAUNCHER, free_fn);
272 // Remove DYLD_SHARED_REGION variable.
273 VG_(env_unsetenv)(envp, "DYLD_SHARED_REGION", free_fn);
275 // XXX if variable becomes empty, remove it completely?
277 VG_(free)(buf);
280 /* Resolves filename of VG_(cl_exec_fd) and copies it to the buffer.
281 Buffer must not be NULL and buf_size must be at least 1.
282 If buffer is not large enough it is terminated with '\0' only
283 when 'terminate_with_NUL == True'. */
284 void VG_(client_fname)(HChar *buffer, SizeT buf_size, Bool terminate_with_NUL)
286 vg_assert(buffer != NULL);
287 vg_assert(buf_size >= 1);
289 const HChar *name;
290 if (VG_(resolve_filename)(VG_(cl_exec_fd), &name)) {
291 const HChar *n = name + VG_(strlen)(name) - 1;
293 while (n > name && *n != '/')
294 n--;
295 if (n != name)
296 n++;
298 VG_(strncpy)(buffer, n, buf_size);
299 if (terminate_with_NUL)
300 buffer[buf_size - 1] = '\0';
301 } else {
302 buffer[0] = '\0';
306 static Bool add_string(HChar *buffer, SizeT *buf_size, const HChar *string)
308 SizeT len = VG_(strlen)(string);
309 VG_(strncat)(buffer, string, *buf_size);
310 if (len >= *buf_size - 1) {
311 *buf_size = 0;
312 return False;
313 } else {
314 *buf_size -= len;
315 return True;
319 /* Concatenates client exename and command line arguments into
320 the buffer. Buffer must not be NULL and buf_size must be
321 at least 1. Buffer is always terminated with '\0'. */
322 void VG_(client_cmd_and_args)(HChar *buffer, SizeT buf_size)
324 vg_assert(buffer != NULL);
325 vg_assert(buf_size >= 1);
327 buffer[0] = '\0';
329 if (add_string(buffer, &buf_size, VG_(args_the_exename)) == False)
330 return;
332 Int i;
333 for (i = 0; i < VG_(sizeXA)(VG_(args_for_client)); i++) {
334 if (add_string(buffer, &buf_size, " ") == False)
335 return;
337 HChar *arg = *(HChar **) VG_(indexXA)(VG_(args_for_client), i);
338 if (add_string(buffer, &buf_size, arg) == False)
339 return;
343 /* ---------------------------------------------------------------------
344 Various important syscall wrappers
345 ------------------------------------------------------------------ */
347 Int VG_(waitpid)(Int pid, Int *status, Int options)
349 # if defined(VGO_linux)
350 SysRes res = VG_(do_syscall4)(__NR_wait4,
351 pid, (UWord)status, options, 0);
352 return sr_isError(res) ? -1 : sr_Res(res);
353 # elif defined(VGO_darwin)
354 SysRes res = VG_(do_syscall4)(__NR_wait4_nocancel,
355 pid, (UWord)status, options, 0);
356 return sr_isError(res) ? -1 : sr_Res(res);
357 # elif defined(VGO_solaris)
358 SysRes res;
359 vki_idtype_t idtype;
360 vki_id_t id;
361 vki_siginfo_t info;
363 /* We need to do a lot of work here. */
365 if (pid > 0) {
366 idtype = VKI_P_PID;
367 id = pid;
369 else if (pid < -1) {
370 idtype = VKI_P_PGID;
371 id = -pid;
373 else if (pid == -1) {
374 idtype = VKI_P_ALL;
375 id = 0;
377 else {
378 idtype = VKI_P_PGID;
379 res = VG_(do_syscall0)(__NR_getpid);
380 id = sr_ResHI(res);
383 options |= VKI_WEXITED | VKI_WTRAPPED;
385 res = VG_(do_syscall4)(__NR_waitsys, idtype, id, (UWord)&info, options);
386 if (sr_isError(res))
387 return -1;
389 if (status) {
390 Int s = info.si_status & 0xff;
392 switch (info.si_code) {
393 case VKI_CLD_EXITED:
394 s <<= 8;
395 break;
396 case VKI_CLD_DUMPED:
397 s |= VKI_WCOREFLG;
398 break;
399 case VKI_CLD_KILLED:
400 break;
401 case VKI_CLD_TRAPPED:
402 case VKI_CLD_STOPPED:
403 s <<= 8;
404 s |= VKI_WSTOPFLG;
405 break;
406 case VKI_CLD_CONTINUED:
407 s = VKI_WCONTFLG;
408 break;
410 *status = s;
413 return info.si_pid;
414 # else
415 # error Unknown OS
416 # endif
419 /* clone the environment */
420 HChar **VG_(env_clone) ( HChar **oldenv )
422 HChar **oldenvp;
423 HChar **newenvp;
424 HChar **newenv;
425 Int envlen;
427 vg_assert(oldenv);
428 for (oldenvp = oldenv; oldenvp && *oldenvp; oldenvp++);
430 envlen = oldenvp - oldenv + 1;
432 newenv = VG_(malloc)("libcproc.ec.1", envlen * sizeof(HChar *));
434 oldenvp = oldenv;
435 newenvp = newenv;
437 while (oldenvp && *oldenvp) {
438 *newenvp++ = *oldenvp++;
441 *newenvp = *oldenvp;
443 return newenv;
446 void VG_(execv) ( const HChar* filename, const HChar** argv )
448 HChar** envp;
449 SysRes res;
451 envp = VG_(env_clone)(VG_(client_envp));
452 VG_(env_remove_valgrind_env_stuff)( envp, True /*ro_strings*/, NULL );
454 res = VG_(do_syscall3)(__NR_execve,
455 (UWord)filename, (UWord)argv, (UWord)envp);
457 VG_(printf)("EXEC failed, errno = %lld\n", (Long)sr_Err(res));
460 /* Spawns a new child. Uses either spawn syscall or fork+execv combo. */
461 Int VG_(spawn) ( const HChar *filename, const HChar **argv )
463 vg_assert(filename != NULL);
464 vg_assert(argv != NULL);
466 # if defined(VGO_solaris) && defined(SOLARIS_SPAWN_SYSCALL)
467 HChar **envp = VG_(env_clone)(VG_(client_envp));
468 for (HChar **p = envp; *p != NULL; p++) {
469 *p = VG_(strdup)("libcproc.s.1", *p);
471 VG_(env_remove_valgrind_env_stuff)(envp, /* ro_strings */ False, VG_(free));
473 /* Now combine argv and argp into argenv. */
474 SizeT argenv_size = 1 + 1;
475 for (const HChar **p = argv; *p != NULL; p++) {
476 argenv_size += VG_(strlen)(*p) + 2;
478 for (HChar **p = envp; *p != NULL; p++) {
479 argenv_size += VG_(strlen)(*p) + 2;
482 HChar *argenv = VG_(malloc)("libcproc.s.2", argenv_size);
483 HChar *current = argenv;
484 # define COPY_CHAR_TO_ARGENV(dst, character) \
485 do { \
486 *(dst) = character; \
487 (dst) += 1; \
488 } while (0)
489 # define COPY_STRING_TO_ARGENV(dst, src) \
490 do { \
491 COPY_CHAR_TO_ARGENV(dst, '\1'); \
492 SizeT src_len = VG_(strlen)((src)) + 1; \
493 VG_(memcpy)((dst), (src), src_len); \
494 (dst) += src_len; \
495 } while (0)
497 for (const HChar **p = argv; *p != NULL; p++) {
498 COPY_STRING_TO_ARGENV(current, *p);
500 COPY_CHAR_TO_ARGENV(current, '\0');
501 for (HChar **p = envp; *p != NULL; p++) {
502 COPY_STRING_TO_ARGENV(current, *p);
504 COPY_CHAR_TO_ARGENV(current, '\0');
505 vg_assert(current == argenv + argenv_size);
506 # undef COPY_CHAR_TO_ARGENV
507 # undef COPY_STRING_TOARGENV
509 SysRes res = VG_(do_syscall5)(__NR_spawn, (UWord) filename, (UWord) NULL, 0,
510 (UWord) argenv, argenv_size);
512 VG_(free)(argenv);
513 for (HChar **p = envp; *p != NULL; p++) {
514 VG_(free)(*p);
516 VG_(free)(envp);
518 if (sr_isError(res))
519 return -1;
520 return sr_Res(res);
522 # else
524 Int pid = VG_(fork)();
525 if (pid < 0)
526 return -1;
527 if (pid == 0) {
528 /* child */
529 VG_(execv)(argv[0], argv);
531 /* If we're still alive here, execv failed. */
532 VG_(exit)(1);
533 } else {
534 return pid;
536 # endif /* VGO_solaris && SOLARIS_SPAWN_SYSCALL */
539 /* Return -1 if error, else 0. NOTE does not indicate return code of
540 child! */
541 Int VG_(system) ( const HChar* cmd )
543 Int pid;
544 if (cmd == NULL)
545 return 1;
547 const HChar *argv[4] = { "/bin/sh", "-c", cmd, 0 };
548 pid = VG_(spawn)(argv[0], argv);
549 if (pid < 0)
550 return -1;
552 vg_assert(pid > 0);
553 /* parent */
554 /* We have to set SIGCHLD to its default behaviour in order that
555 VG_(waitpid) works (at least on AIX). According to the Linux
556 man page for waitpid:
558 POSIX.1-2001 specifies that if the disposition of SIGCHLD is
559 set to SIG_IGN or the SA_NOCLDWAIT flag is set for SIGCHLD
560 (see sigaction(2)), then children that terminate do not
561 become zombies and a call to wait() or waitpid() will block
562 until all children have terminated, and then fail with errno
563 set to ECHILD. (The original POSIX standard left the
564 behaviour of setting SIGCHLD to SIG_IGN unspecified.)
566 Int ir, zzz;
567 vki_sigaction_toK_t sa, sa2;
568 vki_sigaction_fromK_t saved_sa;
569 VG_(memset)( &sa, 0, sizeof(sa) );
570 VG_(sigemptyset)(&sa.sa_mask);
571 sa.ksa_handler = VKI_SIG_DFL;
572 sa.sa_flags = 0;
573 ir = VG_(sigaction)(VKI_SIGCHLD, &sa, &saved_sa);
574 vg_assert(ir == 0);
576 zzz = VG_(waitpid)(pid, NULL, 0);
578 VG_(convert_sigaction_fromK_to_toK)( &saved_sa, &sa2 );
579 ir = VG_(sigaction)(VKI_SIGCHLD, &sa2, NULL);
580 vg_assert(ir == 0);
581 return zzz == -1 ? -1 : 0;
584 Int VG_(sysctl)(Int *name, UInt namelen, void *oldp, SizeT *oldlenp, void *newp, SizeT newlen)
586 SysRes res;
587 # if defined(VGO_darwin)
588 res = VG_(do_syscall6)(__NR___sysctl,
589 (UWord)name, namelen, (UWord)oldp, (UWord)oldlenp, (UWord)newp, newlen);
590 # else
591 res = VG_(mk_SysRes_Error)(VKI_ENOSYS);
592 # endif
593 return sr_isError(res) ? -1 : sr_Res(res);
596 /* ---------------------------------------------------------------------
597 Resource limits
598 ------------------------------------------------------------------ */
600 /* Support for getrlimit. */
601 Int VG_(getrlimit) (Int resource, struct vki_rlimit *rlim)
603 SysRes res = VG_(mk_SysRes_Error)(VKI_ENOSYS);
604 /* res = getrlimit( resource, rlim ); */
605 # ifdef __NR_ugetrlimit
606 res = VG_(do_syscall2)(__NR_ugetrlimit, resource, (UWord)rlim);
607 # endif
608 if (sr_isError(res) && sr_Err(res) == VKI_ENOSYS)
609 res = VG_(do_syscall2)(__NR_getrlimit, resource, (UWord)rlim);
610 return sr_isError(res) ? -1 : sr_Res(res);
614 /* Support for setrlimit. */
615 Int VG_(setrlimit) (Int resource, const struct vki_rlimit *rlim)
617 SysRes res;
618 /* res = setrlimit( resource, rlim ); */
619 res = VG_(do_syscall2)(__NR_setrlimit, resource, (UWord)rlim);
620 return sr_isError(res) ? -1 : sr_Res(res);
623 /* Support for prctl. */
624 Int VG_(prctl) (Int option,
625 ULong arg2, ULong arg3, ULong arg4, ULong arg5)
627 SysRes res = VG_(mk_SysRes_Error)(VKI_ENOSYS);
628 # if defined(VGO_linux)
629 /* res = prctl( option, arg2, arg3, arg4, arg5 ); */
630 res = VG_(do_syscall5)(__NR_prctl, (UWord) option,
631 (UWord) arg2, (UWord) arg3, (UWord) arg4,
632 (UWord) arg5);
633 # endif
635 return sr_isError(res) ? -1 : sr_Res(res);
638 /* ---------------------------------------------------------------------
639 pids, etc
640 ------------------------------------------------------------------ */
642 Int VG_(gettid)(void)
644 # if defined(VGO_linux)
645 SysRes res = VG_(do_syscall0)(__NR_gettid);
647 if (sr_isError(res) && sr_Res(res) == VKI_ENOSYS) {
648 HChar pid[16];
650 * The gettid system call does not exist. The obvious assumption
651 * to make at this point would be that we are running on an older
652 * system where the getpid system call actually returns the ID of
653 * the current thread.
655 * Unfortunately it seems that there are some systems with a kernel
656 * where getpid has been changed to return the ID of the thread group
657 * leader but where the gettid system call has not yet been added.
659 * So instead of calling getpid here we use readlink to see where
660 * the /proc/self link is pointing...
663 # if defined(VGP_arm64_linux)
664 res = VG_(do_syscall4)(__NR_readlinkat, VKI_AT_FDCWD,
665 (UWord)"/proc/self",
666 (UWord)pid, sizeof(pid));
667 # else
668 res = VG_(do_syscall3)(__NR_readlink, (UWord)"/proc/self",
669 (UWord)pid, sizeof(pid));
670 # endif
671 if (!sr_isError(res) && sr_Res(res) > 0) {
672 HChar* s;
673 pid[sr_Res(res)] = '\0';
674 res = VG_(mk_SysRes_Success)( VG_(strtoll10)(pid, &s) );
675 if (*s != '\0') {
676 VG_(message)(Vg_DebugMsg,
677 "Warning: invalid file name linked to by /proc/self: %s\n",
678 pid);
683 return sr_Res(res);
685 # elif defined(VGO_darwin)
686 // Darwin's gettid syscall is something else.
687 // Use Mach thread ports for lwpid instead.
688 return mach_thread_self();
690 # elif defined(VGO_solaris)
691 SysRes res = VG_(do_syscall0)(__NR_lwp_self);
692 return sr_Res(res);
694 # else
695 # error "Unknown OS"
696 # endif
699 /* You'd be amazed how many places need to know the current pid. */
700 Int VG_(getpid) ( void )
702 /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
703 return sr_Res( VG_(do_syscall0)(__NR_getpid) );
706 Int VG_(getpgrp) ( void )
708 /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
709 # if defined(VGP_arm64_linux)
710 return sr_Res( VG_(do_syscall1)(__NR_getpgid, 0) );
711 # elif defined(VGO_linux) || defined(VGO_darwin)
712 return sr_Res( VG_(do_syscall0)(__NR_getpgrp) );
713 # elif defined(VGO_solaris)
714 /* Uses the shared pgrpsys syscall, 0 for the getpgrp variant. */
715 return sr_Res( VG_(do_syscall1)(__NR_pgrpsys, 0) );
716 # else
717 # error Unknown OS
718 # endif
721 Int VG_(getppid) ( void )
723 /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
724 # if defined(VGO_linux) || defined(VGO_darwin)
725 return sr_Res( VG_(do_syscall0)(__NR_getppid) );
726 # elif defined(VGO_solaris)
727 /* Uses the shared getpid/getppid syscall, val2 contains a parent pid. */
728 return sr_ResHI( VG_(do_syscall0)(__NR_getpid) );
729 # else
730 # error Unknown OS
731 # endif
734 Int VG_(geteuid) ( void )
736 /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
737 # if defined(VGO_linux) || defined(VGO_darwin)
739 # if defined(__NR_geteuid32)
740 // We use the 32-bit version if it's supported. Otherwise, IDs greater
741 // than 65536 cause problems, as bug #151209 showed.
742 return sr_Res( VG_(do_syscall0)(__NR_geteuid32) );
743 # else
744 return sr_Res( VG_(do_syscall0)(__NR_geteuid) );
745 # endif
747 # elif defined(VGO_solaris)
748 /* Uses the shared getuid/geteuid syscall, val2 contains the effective
749 uid. */
750 return sr_ResHI( VG_(do_syscall0)(__NR_getuid) );
751 # else
752 # error Unknown OS
753 # endif
756 Int VG_(getegid) ( void )
758 # if defined(VGO_linux) || defined(VGO_darwin)
759 /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
760 # if defined(__NR_getegid32)
761 // We use the 32-bit version if it's supported. Otherwise, IDs greater
762 // than 65536 cause problems, as bug #151209 showed.
763 return sr_Res( VG_(do_syscall0)(__NR_getegid32) );
764 # else
765 return sr_Res( VG_(do_syscall0)(__NR_getegid) );
766 # endif
768 # elif defined(VGO_solaris)
769 /* Uses the shared getgid/getegid syscall, val2 contains the effective
770 gid. */
771 return sr_ResHI( VG_(do_syscall0)(__NR_getgid) );
772 # else
773 # error Unknown OS
774 # endif
777 /* Get supplementary groups into list[0 .. size-1]. Returns the
778 number of groups written, or -1 if error. Note that in order to be
779 portable, the groups are 32-bit unsigned ints regardless of the
780 platform.
781 As a special case, if size == 0 the function returns the number of
782 groups leaving list untouched. */
783 Int VG_(getgroups)( Int size, UInt* list )
785 if (size < 0) return -1;
787 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
788 || defined(VGP_mips64_linux)
789 Int i;
790 SysRes sres;
791 UShort list16[size];
792 sres = VG_(do_syscall2)(__NR_getgroups, size, (Addr)list16);
793 if (sr_isError(sres))
794 return -1;
795 if (size != 0) {
796 for (i = 0; i < sr_Res(sres); i++)
797 list[i] = (UInt)list16[i];
799 return sr_Res(sres);
801 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
802 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
803 || defined(VGO_darwin) || defined(VGP_s390x_linux) \
804 || defined(VGP_mips32_linux) || defined(VGP_arm64_linux) \
805 || defined(VGO_solaris)
806 SysRes sres;
807 sres = VG_(do_syscall2)(__NR_getgroups, size, (Addr)list);
808 if (sr_isError(sres))
809 return -1;
810 return sr_Res(sres);
812 # else
813 # error "VG_(getgroups): needs implementation on this platform"
814 # endif
817 /* ---------------------------------------------------------------------
818 Process tracing
819 ------------------------------------------------------------------ */
821 Int VG_(ptrace) ( Int request, Int pid, void *addr, void *data )
823 SysRes res;
824 # if defined(VGO_linux) || defined(VGO_darwin)
825 res = VG_(do_syscall4)(__NR_ptrace, request, pid, (UWord)addr, (UWord)data);
826 # elif defined(VGO_solaris)
827 /* There is no ptrace syscall on Solaris. Such requests has to be
828 implemented using the /proc interface. Callers of VG_(ptrace) should
829 ensure that this function is not reached on Solaris, i.e. they must
830 provide a special code for Solaris for whatever feature they provide. */
831 I_die_here;
832 # else
833 # error Unknown OS
834 # endif
835 if (sr_isError(res))
836 return -1;
837 return sr_Res(res);
840 /* ---------------------------------------------------------------------
841 Fork
842 ------------------------------------------------------------------ */
844 Int VG_(fork) ( void )
846 # if defined(VGP_arm64_linux)
847 SysRes res;
848 res = VG_(do_syscall5)(__NR_clone, VKI_SIGCHLD,
849 (UWord)NULL, (UWord)NULL, (UWord)NULL, (UWord)NULL);
850 if (sr_isError(res))
851 return -1;
852 return sr_Res(res);
854 # elif defined(VGO_linux)
855 SysRes res;
856 res = VG_(do_syscall0)(__NR_fork);
857 if (sr_isError(res))
858 return -1;
859 return sr_Res(res);
861 # elif defined(VGO_darwin)
862 SysRes res;
863 res = VG_(do_syscall0)(__NR_fork); /* __NR_fork is UX64 */
864 if (sr_isError(res))
865 return -1;
866 /* on success: wLO = child pid; wHI = 1 for child, 0 for parent */
867 if (sr_ResHI(res) != 0) {
868 return 0; /* this is child: return 0 instead of child pid */
870 return sr_Res(res);
872 # elif defined(VGO_solaris)
873 /* Using fork() on Solaris is not really the best thing to do. Solaris
874 does not do memory overcommitment so fork() can fail if there is not
875 enough memory to copy the current process into a new one.
876 Prefer to use VG_(spawn)() over VG_(fork)() + VG_(execv)(). */
877 SysRes res;
878 res = VG_(do_syscall2)(__NR_forksys, 0 /*subcode (fork)*/, 0 /*flags*/);
879 if (sr_isError(res))
880 return -1;
881 /* On success:
882 val = a pid of the child in the parent, a pid of the parent in the
883 child,
884 val2 = 0 in the parent process, 1 in the child process. */
885 if (sr_ResHI(res) != 0) {
886 return 0;
888 return sr_Res(res);
890 # else
891 # error "Unknown OS"
892 # endif
895 /* ---------------------------------------------------------------------
896 Timing stuff
897 ------------------------------------------------------------------ */
899 UInt VG_(read_millisecond_timer) ( void )
901 /* 'now' and 'base' are in microseconds */
902 static ULong base = 0;
903 ULong now;
905 # if defined(VGO_linux) || defined(VGO_solaris)
906 { SysRes res;
907 struct vki_timespec ts_now;
908 res = VG_(do_syscall2)(__NR_clock_gettime, VKI_CLOCK_MONOTONIC,
909 (UWord)&ts_now);
910 if (sr_isError(res) == 0) {
911 now = ts_now.tv_sec * 1000000ULL + ts_now.tv_nsec / 1000;
912 } else {
913 struct vki_timeval tv_now;
914 /* Note: On Solaris, this syscall takes only one parameter but the
915 extra dummy one does not cause any harm. */
916 res = VG_(do_syscall2)(__NR_gettimeofday, (UWord)&tv_now, (UWord)NULL);
917 vg_assert(! sr_isError(res));
918 now = tv_now.tv_sec * 1000000ULL + tv_now.tv_usec;
922 # elif defined(VGO_darwin)
923 // Weird: it seems that gettimeofday() doesn't fill in the timeval, but
924 // rather returns the tv_sec as the low 32 bits of the result and the
925 // tv_usec as the high 32 bits of the result. (But the timeval cannot be
926 // NULL!) See bug 200990.
927 { SysRes res;
928 struct vki_timeval tv_now = { 0, 0 };
929 res = VG_(do_syscall2)(__NR_gettimeofday, (UWord)&tv_now, (UWord)NULL);
930 vg_assert(! sr_isError(res));
931 now = sr_Res(res) * 1000000ULL + sr_ResHI(res);
934 # else
935 # error "Unknown OS"
936 # endif
938 /* COMMON CODE */
939 if (base == 0)
940 base = now;
942 return (now - base) / 1000;
945 Int VG_(gettimeofday)(struct vki_timeval *tv, struct vki_timezone *tz)
947 SysRes res;
948 res = VG_(do_syscall2)(__NR_gettimeofday, (UWord)tv, (UWord)tz);
950 if (! sr_isError(res)) return 0;
952 /* Make sure, argument values are deterministic upon failure */
953 if (tv) *tv = (struct vki_timeval){ .tv_sec = 0, .tv_usec = 0 };
954 if (tz) *tz = (struct vki_timezone){ .tz_minuteswest = 0, .tz_dsttime = 0 };
956 return -1;
959 UInt VG_(get_user_milliseconds)(void)
961 UInt res = 0;
962 # if defined(VGO_linux)
964 struct vki_rusage ru;
965 VG_(memset)(&ru, 0, sizeof(ru));
966 SysRes sr = VG_(do_syscall2)(__NR_getrusage, VKI_RUSAGE_SELF, (UWord)&ru);
967 if (!sr_isError(sr)) {
968 res = ru.ru_utime.tv_sec * 1000 + ru.ru_utime.tv_usec / 1000;
972 # elif defined(VGO_solaris)
974 struct vki_rusage ru;
975 VG_(memset)(&ru, 0, sizeof(ru));
976 SysRes sr = VG_(do_syscall2)(__NR_rusagesys, VKI__RUSAGESYS_GETRUSAGE,
977 (UWord) &ru);
978 if (!sr_isError(sr)) {
979 res = ru.ru_utime.tv_sec * 1000 + ru.ru_utime.tv_usec / 1000;
983 # elif defined(VGO_darwin)
984 res = 0;
986 # else
987 # error "Unknown OS"
988 # endif
990 return res;
994 /* ---------------------------------------------------------------------
995 atfork()
996 ------------------------------------------------------------------ */
998 struct atfork {
999 vg_atfork_t pre;
1000 vg_atfork_t parent;
1001 vg_atfork_t child;
1004 #define VG_MAX_ATFORK 10
1006 static struct atfork atforks[VG_MAX_ATFORK];
1007 static Int n_atfork = 0;
1009 void VG_(atfork)(vg_atfork_t pre, vg_atfork_t parent, vg_atfork_t child)
1011 Int i;
1013 for (i = 0; i < n_atfork; i++) {
1014 if (atforks[i].pre == pre &&
1015 atforks[i].parent == parent &&
1016 atforks[i].child == child)
1017 return;
1020 if (n_atfork >= VG_MAX_ATFORK)
1021 VG_(core_panic)(
1022 "Too many VG_(atfork) handlers requested: raise VG_MAX_ATFORK");
1024 atforks[n_atfork].pre = pre;
1025 atforks[n_atfork].parent = parent;
1026 atforks[n_atfork].child = child;
1028 n_atfork++;
1031 void VG_(do_atfork_pre)(ThreadId tid)
1033 Int i;
1035 for (i = 0; i < n_atfork; i++)
1036 if (atforks[i].pre != NULL)
1037 (*atforks[i].pre)(tid);
1040 void VG_(do_atfork_parent)(ThreadId tid)
1042 Int i;
1044 for (i = 0; i < n_atfork; i++)
1045 if (atforks[i].parent != NULL)
1046 (*atforks[i].parent)(tid);
1049 void VG_(do_atfork_child)(ThreadId tid)
1051 Int i;
1053 for (i = 0; i < n_atfork; i++)
1054 if (atforks[i].child != NULL)
1055 (*atforks[i].child)(tid);
1059 /* ---------------------------------------------------------------------
1060 icache invalidation
1061 ------------------------------------------------------------------ */
1063 void VG_(invalidate_icache) ( void *ptr, SizeT nbytes )
1065 if (nbytes == 0) return; // nothing to do
1067 // Get cache info
1068 VexArchInfo vai;
1069 VG_(machine_get_VexArchInfo)(NULL, &vai);
1071 // If I-caches are coherent, nothing needs to be done here
1072 if (vai.hwcache_info.icaches_maintain_coherence) return;
1074 # if defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le)
1075 Addr startaddr = (Addr) ptr;
1076 Addr endaddr = startaddr + nbytes;
1077 Addr cls;
1078 Addr addr;
1080 cls = vai.ppc_icache_line_szB;
1082 /* Stay sane .. */
1083 vg_assert(cls == 16 || cls == 32 || cls == 64 || cls == 128);
1085 startaddr &= ~(cls - 1);
1086 for (addr = startaddr; addr < endaddr; addr += cls) {
1087 __asm__ __volatile__("dcbst 0,%0" : : "r" (addr));
1089 __asm__ __volatile__("sync");
1090 for (addr = startaddr; addr < endaddr; addr += cls) {
1091 __asm__ __volatile__("icbi 0,%0" : : "r" (addr));
1093 __asm__ __volatile__("sync; isync");
1095 # elif defined(VGP_arm_linux)
1096 /* ARM cache flushes are privileged, so we must defer to the kernel. */
1097 Addr startaddr = (Addr) ptr;
1098 Addr endaddr = startaddr + nbytes;
1099 VG_(do_syscall2)(__NR_ARM_cacheflush, startaddr, endaddr);
1101 # elif defined(VGP_arm64_linux)
1102 // This arm64_linux section of this function VG_(invalidate_icache)
1103 // is copied from
1104 // https://github.com/armvixl/vixl/blob/master/src/a64/cpu-a64.cc
1105 // which has the following copyright notice:
1107 Copyright 2013, ARM Limited
1108 All rights reserved.
1110 Redistribution and use in source and binary forms, with or without
1111 modification, are permitted provided that the following conditions are met:
1113 * Redistributions of source code must retain the above copyright notice,
1114 this list of conditions and the following disclaimer.
1115 * Redistributions in binary form must reproduce the above copyright notice,
1116 this list of conditions and the following disclaimer in the documentation
1117 and/or other materials provided with the distribution.
1118 * Neither the name of ARM Limited nor the names of its contributors may be
1119 used to endorse or promote products derived from this software without
1120 specific prior written permission.
1122 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
1123 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1124 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1125 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
1126 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1127 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1128 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
1129 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
1130 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1131 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1134 // Ask what the I and D line sizes are
1135 UInt cache_type_register;
1136 // Copy the content of the cache type register to a core register.
1137 __asm__ __volatile__ ("mrs %[ctr], ctr_el0" // NOLINT
1138 : [ctr] "=r" (cache_type_register));
1140 const Int kDCacheLineSizeShift = 16;
1141 const Int kICacheLineSizeShift = 0;
1142 const UInt kDCacheLineSizeMask = 0xf << kDCacheLineSizeShift;
1143 const UInt kICacheLineSizeMask = 0xf << kICacheLineSizeShift;
1145 // The cache type register holds the size of the I and D caches as a power of
1146 // two.
1147 const UInt dcache_line_size_power_of_two =
1148 (cache_type_register & kDCacheLineSizeMask) >> kDCacheLineSizeShift;
1149 const UInt icache_line_size_power_of_two =
1150 (cache_type_register & kICacheLineSizeMask) >> kICacheLineSizeShift;
1152 const UInt dcache_line_size_ = 4 * (1 << dcache_line_size_power_of_two);
1153 const UInt icache_line_size_ = 4 * (1 << icache_line_size_power_of_two);
1155 Addr start = (Addr)ptr;
1156 // Sizes will be used to generate a mask big enough to cover a pointer.
1157 Addr dsize = (Addr)dcache_line_size_;
1158 Addr isize = (Addr)icache_line_size_;
1160 // Cache line sizes are always a power of 2.
1161 Addr dstart = start & ~(dsize - 1);
1162 Addr istart = start & ~(isize - 1);
1163 Addr end = start + nbytes;
1165 __asm__ __volatile__ (
1166 // Clean every line of the D cache containing the target data.
1167 "0: \n\t"
1168 // dc : Data Cache maintenance
1169 // c : Clean
1170 // va : by (Virtual) Address
1171 // u : to the point of Unification
1172 // The point of unification for a processor is the point by which the
1173 // instruction and data caches are guaranteed to see the same copy of a
1174 // memory location. See ARM DDI 0406B page B2-12 for more information.
1175 "dc cvau, %[dline] \n\t"
1176 "add %[dline], %[dline], %[dsize] \n\t"
1177 "cmp %[dline], %[end] \n\t"
1178 "b.lt 0b \n\t"
1179 // Barrier to make sure the effect of the code above is visible to the rest
1180 // of the world.
1181 // dsb : Data Synchronisation Barrier
1182 // ish : Inner SHareable domain
1183 // The point of unification for an Inner Shareable shareability domain is
1184 // the point by which the instruction and data caches of all the processors
1185 // in that Inner Shareable shareability domain are guaranteed to see the
1186 // same copy of a memory location. See ARM DDI 0406B page B2-12 for more
1187 // information.
1188 "dsb ish \n\t"
1189 // Invalidate every line of the I cache containing the target data.
1190 "1: \n\t"
1191 // ic : instruction cache maintenance
1192 // i : invalidate
1193 // va : by address
1194 // u : to the point of unification
1195 "ic ivau, %[iline] \n\t"
1196 "add %[iline], %[iline], %[isize] \n\t"
1197 "cmp %[iline], %[end] \n\t"
1198 "b.lt 1b \n\t"
1199 // Barrier to make sure the effect of the code above is visible to the rest
1200 // of the world.
1201 "dsb ish \n\t"
1202 // Barrier to ensure any prefetching which happened before this code is
1203 // discarded.
1204 // isb : Instruction Synchronisation Barrier
1205 "isb \n\t"
1206 : [dline] "+r" (dstart),
1207 [iline] "+r" (istart)
1208 : [dsize] "r" (dsize),
1209 [isize] "r" (isize),
1210 [end] "r" (end)
1211 // This code does not write to memory but without the dependency gcc might
1212 // move this code before the code is generated.
1213 : "cc", "memory"
1216 # elif defined(VGA_mips32) || defined(VGA_mips64)
1217 SysRes sres = VG_(do_syscall3)(__NR_cacheflush, (UWord) ptr,
1218 (UWord) nbytes, (UWord) 3);
1219 vg_assert( !sr_isError(sres) );
1221 # endif
1225 /* ---------------------------------------------------------------------
1226 dcache flushing
1227 ------------------------------------------------------------------ */
1229 void VG_(flush_dcache) ( void *ptr, SizeT nbytes )
1231 /* Currently this is only required on ARM64. */
1232 # if defined(VGA_arm64)
1233 Addr startaddr = (Addr) ptr;
1234 Addr endaddr = startaddr + nbytes;
1235 Addr cls;
1236 Addr addr;
1238 ULong ctr_el0;
1239 __asm__ __volatile__ ("mrs %0, ctr_el0" : "=r"(ctr_el0));
1240 cls = 4 * (1ULL << (0xF & (ctr_el0 >> 16)));
1242 /* Stay sane .. */
1243 vg_assert(cls == 64 || cls == 128);
1245 startaddr &= ~(cls - 1);
1246 for (addr = startaddr; addr < endaddr; addr += cls) {
1247 __asm__ __volatile__("dc cvau, %0" : : "r" (addr));
1249 __asm__ __volatile__("dsb ish");
1250 # endif
1253 /*--------------------------------------------------------------------*/
1254 /*--- end ---*/
1255 /*--------------------------------------------------------------------*/