blob: 68328699d652a5ee3876b2adeb943ddc6dcaf7f1 [file] [log] [blame]
sewardjde4a1d02002-03-22 01:27:54 +00001
2/*--------------------------------------------------------------------*/
njnf39e9a32005-06-12 02:43:17 +00003/*--- Process-related libc stuff. m_libcproc.c ---*/
sewardjde4a1d02002-03-22 01:27:54 +00004/*--------------------------------------------------------------------*/
njned6b8242005-06-01 00:03:17 +00005
sewardjde4a1d02002-03-22 01:27:54 +00006/*
njnb9c427c2004-12-01 14:14:42 +00007 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
sewardjde4a1d02002-03-22 01:27:54 +00009
sewardj03f8d3f2012-08-05 15:46:46 +000010 Copyright (C) 2000-2012 Julian Seward
sewardjde4a1d02002-03-22 01:27:54 +000011 jseward@acm.org
sewardjde4a1d02002-03-22 01:27:54 +000012
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
njn25e49d8e72002-09-23 09:36:25 +000028 The GNU General Public License is contained in the file COPYING.
sewardjde4a1d02002-03-22 01:27:54 +000029*/
30
njnc7561b92005-06-19 01:24:32 +000031#include "pub_core_basics.h"
sewardj291849f2012-04-20 23:58:55 +000032#include "pub_core_machine.h" // For VG_(machine_get_VexArchInfo)
sewardj4cfea4f2006-10-14 19:26:10 +000033#include "pub_core_vki.h"
sewardjd470bfc2006-10-17 02:16:44 +000034#include "pub_core_vkiscnums.h"
njn97405b22005-06-02 03:39:33 +000035#include "pub_core_libcbase.h"
njn132bfcc2005-06-04 19:16:06 +000036#include "pub_core_libcassert.h"
njn36a20fa2005-06-03 03:08:39 +000037#include "pub_core_libcprint.h"
njnf39e9a32005-06-12 02:43:17 +000038#include "pub_core_libcproc.h"
sewardjd470bfc2006-10-17 02:16:44 +000039#include "pub_core_libcsignal.h"
sewardjd7a02db2008-12-12 08:07:49 +000040#include "pub_core_seqmatch.h"
njnaf1d7df2005-06-11 01:31:52 +000041#include "pub_core_mallocfree.h"
njn9abd6082005-06-17 21:31:45 +000042#include "pub_core_syscall.h"
sewardj14c7cc52007-02-25 15:08:24 +000043#include "pub_core_xarray.h"
sewardj45f4e7c2005-09-27 19:20:21 +000044#include "pub_core_clientstate.h"
sewardj1cf558c2005-04-25 01:36:56 +000045
njnf76d27a2009-05-28 01:53:07 +000046#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
njnf39e9a32005-06-12 02:43:17 +000057/* ---------------------------------------------------------------------
58 Command line and environment stuff
59 ------------------------------------------------------------------ */
sewardjde4a1d02002-03-22 01:27:54 +000060
njnf39e9a32005-06-12 02:43:17 +000061/* As deduced from sp_at_startup, the client's argc, argv[] and
62 envp[] as extracted from the client's stack at startup-time. */
florian19f91bb2012-11-10 22:29:54 +000063HChar** VG_(client_envp) = NULL;
njnf39e9a32005-06-12 02:43:17 +000064
njn8d9965c2005-06-12 17:47:24 +000065/* Path to library directory */
florian19f91bb2012-11-10 22:29:54 +000066const HChar *VG_(libdir) = VG_LIBDIR;
njn8d9965c2005-06-12 17:47:24 +000067
florian19f91bb2012-11-10 22:29:54 +000068const HChar *VG_(LD_PRELOAD_var_name) =
sewardj6e9de462011-06-28 07:25:29 +000069#if defined(VGO_linux)
njne323a6b2010-07-01 02:35:03 +000070 "LD_PRELOAD";
71#elif defined(VGO_darwin)
72 "DYLD_INSERT_LIBRARIES";
73#else
74# error Unknown OS
75#endif
76
njnf39e9a32005-06-12 02:43:17 +000077/* We do getenv without libc's help by snooping around in
78 VG_(client_envp) as determined at startup time. */
florian19f91bb2012-11-10 22:29:54 +000079HChar *VG_(getenv)(const HChar *varname)
jsgf855d93d2003-10-13 22:26:55 +000080{
njnf39e9a32005-06-12 02:43:17 +000081 Int i, n;
sewardj198f34f2007-07-09 23:13:07 +000082 vg_assert( VG_(client_envp) );
njnf39e9a32005-06-12 02:43:17 +000083 n = VG_(strlen)(varname);
84 for (i = 0; VG_(client_envp)[i] != NULL; i++) {
florian19f91bb2012-11-10 22:29:54 +000085 HChar* s = VG_(client_envp)[i];
njnf39e9a32005-06-12 02:43:17 +000086 if (VG_(strncmp)(varname, s, n) == 0 && s[n] == '=') {
87 return & s[n+1];
thughes8ef6d962004-10-16 10:46:01 +000088 }
89 }
njnf39e9a32005-06-12 02:43:17 +000090 return NULL;
nethercoteff9721d2004-01-26 17:10:01 +000091}
92
florian19f91bb2012-11-10 22:29:54 +000093void VG_(env_unsetenv) ( HChar **env, const HChar *varname )
fitzhardinge98abfc72003-12-16 02:05:15 +000094{
florian19f91bb2012-11-10 22:29:54 +000095 HChar **from, **to;
sewardjdc413092011-05-04 09:01:58 +000096 vg_assert(env);
97 vg_assert(varname);
98 to = NULL;
fitzhardinge98abfc72003-12-16 02:05:15 +000099 Int len = VG_(strlen)(varname);
100
sewardj45f4e7c2005-09-27 19:20:21 +0000101 for (from = to = env; from && *from; from++) {
fitzhardinge98abfc72003-12-16 02:05:15 +0000102 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 */
florian19f91bb2012-11-10 22:29:54 +0000111HChar **VG_(env_setenv) ( HChar ***envp, const HChar* varname,
112 const HChar *val )
fitzhardinge98abfc72003-12-16 02:05:15 +0000113{
florian19f91bb2012-11-10 22:29:54 +0000114 HChar **env = (*envp);
115 HChar **cpp;
fitzhardinge98abfc72003-12-16 02:05:15 +0000116 Int len = VG_(strlen)(varname);
florian19f91bb2012-11-10 22:29:54 +0000117 HChar *valstr = VG_(arena_malloc)(VG_AR_CORE, "libcproc.es.1",
118 len + VG_(strlen)(val) + 2);
119 HChar **oldenv = NULL;
fitzhardinge98abfc72003-12-16 02:05:15 +0000120
121 VG_(sprintf)(valstr, "%s=%s", varname, val);
122
sewardj45f4e7c2005-09-27 19:20:21 +0000123 for (cpp = env; cpp && *cpp; cpp++) {
fitzhardinge98abfc72003-12-16 02:05:15 +0000124 if (VG_(strncmp)(varname, *cpp, len) == 0 && (*cpp)[len] == '=') {
125 *cpp = valstr;
126 return oldenv;
127 }
128 }
129
130 if (env == NULL) {
florian19f91bb2012-11-10 22:29:54 +0000131 env = VG_(arena_malloc)(VG_AR_CORE, "libcproc.es.2", sizeof(HChar *) * 2);
fitzhardinge98abfc72003-12-16 02:05:15 +0000132 env[0] = valstr;
133 env[1] = NULL;
134
135 *envp = env;
136
137 } else {
138 Int envlen = (cpp-env) + 2;
florian19f91bb2012-11-10 22:29:54 +0000139 HChar **newenv = VG_(arena_malloc)(VG_AR_CORE, "libcproc.es.3",
140 envlen * sizeof(HChar *));
fitzhardinge98abfc72003-12-16 02:05:15 +0000141
sewardj45f4e7c2005-09-27 19:20:21 +0000142 for (cpp = newenv; *env; )
fitzhardinge98abfc72003-12-16 02:05:15 +0000143 *cpp++ = *env++;
144 *cpp++ = valstr;
145 *cpp++ = NULL;
146
147 oldenv = *envp;
148
149 *envp = newenv;
150 }
151
152 return oldenv;
153}
154
njncda2f0f2009-05-18 02:12:08 +0000155
nethercote60a96c52004-08-03 13:08:31 +0000156/* 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*/
florian19f91bb2012-11-10 22:29:54 +0000166static void mash_colon_env(HChar *varp, const HChar *remove_pattern)
nethercote60a96c52004-08-03 13:08:31 +0000167{
florian19f91bb2012-11-10 22:29:54 +0000168 HChar *const start = varp;
169 HChar *entry_start = varp;
170 HChar *output = varp;
nethercote60a96c52004-08-03 13:08:31 +0000171
172 if (varp == NULL)
173 return;
174
175 while(*varp) {
176 if (*varp == ':') {
florian19f91bb2012-11-10 22:29:54 +0000177 HChar prev;
nethercote60a96c52004-08-03 13:08:31 +0000178 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
tom149ede92010-06-15 12:49:07 +0000198 if (*varp)
199 *output++ = *varp++;
nethercote60a96c52004-08-03 13:08:31 +0000200 }
201
tom149ede92010-06-15 12:49:07 +0000202 /* make sure last entry is nul terminated */
203 *output = '\0';
204
nethercote60a96c52004-08-03 13:08:31 +0000205 /* 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.
florian19f91bb2012-11-10 22:29:54 +0000223void VG_(env_remove_valgrind_env_stuff)(HChar** envp)
nethercote60a96c52004-08-03 13:08:31 +0000224{
njnf76d27a2009-05-28 01:53:07 +0000225
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
nethercote60a96c52004-08-03 13:08:31 +0000233 Int i;
florian19f91bb2012-11-10 22:29:54 +0000234 HChar* ld_preload_str = NULL;
235 HChar* ld_library_path_str = NULL;
236 HChar* dyld_insert_libraries_str = NULL;
237 HChar* buf;
nethercote60a96c52004-08-03 13:08:31 +0000238
239 // Find LD_* variables
njnf76d27a2009-05-28 01:53:07 +0000240 // 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
nethercote60a96c52004-08-03 13:08:31 +0000244 for (i = 0; envp[i] != NULL; i++) {
philippe2aeaf8e2011-12-11 16:29:43 +0000245 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 }
nethercote60a96c52004-08-03 13:08:31 +0000257 }
258
tombe2fe8d2011-08-23 10:11:02 +0000259 buf = VG_(arena_malloc)(VG_AR_CORE, "libcproc.erves.4",
sewardj9c606bd2008-09-18 18:12:50 +0000260 VG_(strlen)(VG_(libdir)) + 20);
nethercote60a96c52004-08-03 13:08:31 +0000261
262 // Remove Valgrind-specific entries from LD_*.
nethercote60a96c52004-08-03 13:08:31 +0000263 VG_(sprintf)(buf, "%s*/vgpreload_*.so", VG_(libdir));
264 mash_colon_env(ld_preload_str, buf);
njnf76d27a2009-05-28 01:53:07 +0000265 mash_colon_env(dyld_insert_libraries_str, buf);
nethercote60a96c52004-08-03 13:08:31 +0000266 VG_(sprintf)(buf, "%s*", VG_(libdir));
267 mash_colon_env(ld_library_path_str, buf);
268
sewardj45f4e7c2005-09-27 19:20:21 +0000269 // Remove VALGRIND_LAUNCHER variable.
270 VG_(env_unsetenv)(envp, VALGRIND_LAUNCHER);
nethercote60a96c52004-08-03 13:08:31 +0000271
njnf76d27a2009-05-28 01:53:07 +0000272 // Remove DYLD_SHARED_REGION variable.
273 VG_(env_unsetenv)(envp, "DYLD_SHARED_REGION");
274
nethercote60a96c52004-08-03 13:08:31 +0000275 // XXX if variable becomes empty, remove it completely?
276
277 VG_(arena_free)(VG_AR_CORE, buf);
278}
279
njnf39e9a32005-06-12 02:43:17 +0000280/* ---------------------------------------------------------------------
281 Various important syscall wrappers
282 ------------------------------------------------------------------ */
283
284Int VG_(waitpid)(Int pid, Int *status, Int options)
285{
sewardjd470bfc2006-10-17 02:16:44 +0000286# if defined(VGO_linux)
njnf76d27a2009-05-28 01:53:07 +0000287 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);
njncda2f0f2009-05-18 02:12:08 +0000293 return sr_isError(res) ? -1 : sr_Res(res);
sewardjd470bfc2006-10-17 02:16:44 +0000294# else
295# error Unknown OS
296# endif
njnf39e9a32005-06-12 02:43:17 +0000297}
298
njnf39e9a32005-06-12 02:43:17 +0000299/* clone the environment */
florian19f91bb2012-11-10 22:29:54 +0000300HChar **VG_(env_clone) ( HChar **oldenv )
njnf39e9a32005-06-12 02:43:17 +0000301{
florian19f91bb2012-11-10 22:29:54 +0000302 HChar **oldenvp;
303 HChar **newenvp;
304 HChar **newenv;
njnf39e9a32005-06-12 02:43:17 +0000305 Int envlen;
306
sewardjdc413092011-05-04 09:01:58 +0000307 vg_assert(oldenv);
njnf39e9a32005-06-12 02:43:17 +0000308 for (oldenvp = oldenv; oldenvp && *oldenvp; oldenvp++);
309
310 envlen = oldenvp - oldenv + 1;
311
sewardj9c606bd2008-09-18 18:12:50 +0000312 newenv = VG_(arena_malloc)(VG_AR_CORE, "libcproc.ec.1",
florian19f91bb2012-11-10 22:29:54 +0000313 envlen * sizeof(HChar *));
njnf39e9a32005-06-12 02:43:17 +0000314
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
florian19f91bb2012-11-10 22:29:54 +0000327void VG_(execv) ( const HChar* filename, HChar** argv )
njne9ba34a2008-10-13 04:19:15 +0000328{
florian19f91bb2012-11-10 22:29:54 +0000329 HChar** envp;
njne9ba34a2008-10-13 04:19:15 +0000330 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
njncda2f0f2009-05-18 02:12:08 +0000341 VG_(printf)("EXEC failed, errno = %lld\n", (Long)sr_Err(res));
njne9ba34a2008-10-13 04:19:15 +0000342}
343
sewardje6a25242002-04-21 22:03:07 +0000344/* Return -1 if error, else 0. NOTE does not indicate return code of
345 child! */
florian19f91bb2012-11-10 22:29:54 +0000346Int VG_(system) ( const HChar* cmd )
sewardje6a25242002-04-21 22:03:07 +0000347{
njne9ba34a2008-10-13 04:19:15 +0000348 Int pid;
sewardje6a25242002-04-21 22:03:07 +0000349 if (cmd == NULL)
350 return 1;
njne9ba34a2008-10-13 04:19:15 +0000351 pid = VG_(fork)();
352 if (pid < 0)
sewardje6a25242002-04-21 22:03:07 +0000353 return -1;
354 if (pid == 0) {
355 /* child */
florian19f91bb2012-11-10 22:29:54 +0000356 const HChar* argv[4] = { "/bin/sh", "-c", cmd, 0 };
florian654b5422012-11-18 00:36:15 +0000357 VG_(execv)(argv[0], (HChar **)argv);
nethercoteff9721d2004-01-26 17:10:01 +0000358
florian654b5422012-11-18 00:36:15 +0000359 /* If we're still alive here, execv failed. */
fitzhardingeabab8392004-03-02 21:38:51 +0000360 VG_(exit)(1);
sewardje6a25242002-04-21 22:03:07 +0000361 } else {
362 /* parent */
sewardjd470bfc2006-10-17 02:16:44 +0000363 /* 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 */
njncda2f0f2009-05-18 02:12:08 +0000375 Int ir, zzz;
376 vki_sigaction_toK_t sa, sa2;
377 vki_sigaction_fromK_t saved_sa;
378 VG_(memset)( &sa, 0, sizeof(sa) );
sewardjd470bfc2006-10-17 02:16:44 +0000379 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
njncda2f0f2009-05-18 02:12:08 +0000387 VG_(convert_sigaction_fromK_to_toK)( &saved_sa, &sa2 );
388 ir = VG_(sigaction)(VKI_SIGCHLD, &sa2, NULL);
sewardjd470bfc2006-10-17 02:16:44 +0000389 vg_assert(ir == 0);
sewardja8d8e232005-06-07 20:04:56 +0000390 return zzz == -1 ? -1 : 0;
sewardje6a25242002-04-21 22:03:07 +0000391 }
392}
393
njnf39e9a32005-06-12 02:43:17 +0000394/* ---------------------------------------------------------------------
395 Resource limits
396 ------------------------------------------------------------------ */
397
njnf39e9a32005-06-12 02:43:17 +0000398/* Support for getrlimit. */
399Int 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
njncda2f0f2009-05-18 02:12:08 +0000406 if (sr_isError(res) && sr_Err(res) == VKI_ENOSYS)
njnf39e9a32005-06-12 02:43:17 +0000407 res = VG_(do_syscall2)(__NR_getrlimit, resource, (UWord)rlim);
njncda2f0f2009-05-18 02:12:08 +0000408 return sr_isError(res) ? -1 : sr_Res(res);
njnf39e9a32005-06-12 02:43:17 +0000409}
410
411
412/* Support for setrlimit. */
413Int 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);
njncda2f0f2009-05-18 02:12:08 +0000418 return sr_isError(res) ? -1 : sr_Res(res);
njnf39e9a32005-06-12 02:43:17 +0000419}
sewardje6a25242002-04-21 22:03:07 +0000420
sewardj3b290482011-05-06 21:02:55 +0000421/* Support for prctl. */
422Int 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
sewardjde4a1d02002-03-22 01:27:54 +0000436/* ---------------------------------------------------------------------
njnf39e9a32005-06-12 02:43:17 +0000437 pids, etc
438 ------------------------------------------------------------------ */
439
440Int VG_(gettid)(void)
441{
njncda2f0f2009-05-18 02:12:08 +0000442# if defined(VGO_linux)
njnf39e9a32005-06-12 02:43:17 +0000443 SysRes res = VG_(do_syscall0)(__NR_gettid);
444
njncda2f0f2009-05-18 02:12:08 +0000445 if (sr_isError(res) && sr_Res(res) == VKI_ENOSYS) {
florian19f91bb2012-11-10 22:29:54 +0000446 HChar pid[16];
njnf39e9a32005-06-12 02:43:17 +0000447 /*
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 res = VG_(do_syscall3)(__NR_readlink, (UWord)"/proc/self",
462 (UWord)pid, sizeof(pid));
njncda2f0f2009-05-18 02:12:08 +0000463 if (!sr_isError(res) && sr_Res(res) > 0) {
florian19f91bb2012-11-10 22:29:54 +0000464 HChar* s;
njncda2f0f2009-05-18 02:12:08 +0000465 pid[sr_Res(res)] = '\0';
466 res = VG_(mk_SysRes_Success)( VG_(strtoll10)(pid, &s) );
njn83df0b62009-02-25 01:01:05 +0000467 if (*s != '\0') {
468 VG_(message)(Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +0000469 "Warning: invalid file name linked to by /proc/self: %s\n",
470 pid);
njn83df0b62009-02-25 01:01:05 +0000471 }
njnf39e9a32005-06-12 02:43:17 +0000472 }
473 }
474
njncda2f0f2009-05-18 02:12:08 +0000475 return sr_Res(res);
476
njnf76d27a2009-05-28 01:53:07 +0000477# elif defined(VGO_darwin)
478 // Darwin's gettid syscall is something else.
479 // Use Mach thread ports for lwpid instead.
480 return mach_thread_self();
481
njncda2f0f2009-05-18 02:12:08 +0000482# else
483# error "Unknown OS"
sewardjd470bfc2006-10-17 02:16:44 +0000484# endif
njnf39e9a32005-06-12 02:43:17 +0000485}
486
487/* You'd be amazed how many places need to know the current pid. */
488Int VG_(getpid) ( void )
489{
490 /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
njncda2f0f2009-05-18 02:12:08 +0000491 return sr_Res( VG_(do_syscall0)(__NR_getpid) );
njnf39e9a32005-06-12 02:43:17 +0000492}
493
494Int VG_(getpgrp) ( void )
495{
496 /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
njncda2f0f2009-05-18 02:12:08 +0000497 return sr_Res( VG_(do_syscall0)(__NR_getpgrp) );
njnf39e9a32005-06-12 02:43:17 +0000498}
499
500Int VG_(getppid) ( void )
501{
502 /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
njncda2f0f2009-05-18 02:12:08 +0000503 return sr_Res( VG_(do_syscall0)(__NR_getppid) );
njnf39e9a32005-06-12 02:43:17 +0000504}
505
sewardj45f4e7c2005-09-27 19:20:21 +0000506Int VG_(geteuid) ( void )
njnf39e9a32005-06-12 02:43:17 +0000507{
508 /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
sewardj6e9de462011-06-28 07:25:29 +0000509# if defined(__NR_geteuid32)
njna8b1c482007-10-23 22:26:12 +0000510 // We use the 32-bit version if it's supported. Otherwise, IDs greater
511 // than 65536 cause problems, as bug #151209 showed.
njncda2f0f2009-05-18 02:12:08 +0000512 return sr_Res( VG_(do_syscall0)(__NR_geteuid32) );
sewardjd470bfc2006-10-17 02:16:44 +0000513# else
njncda2f0f2009-05-18 02:12:08 +0000514 return sr_Res( VG_(do_syscall0)(__NR_geteuid) );
sewardjd470bfc2006-10-17 02:16:44 +0000515# endif
sewardj45f4e7c2005-09-27 19:20:21 +0000516}
517
518Int VG_(getegid) ( void )
519{
520 /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
sewardj6e9de462011-06-28 07:25:29 +0000521# if defined(__NR_getegid32)
njna8b1c482007-10-23 22:26:12 +0000522 // We use the 32-bit version if it's supported. Otherwise, IDs greater
523 // than 65536 cause problems, as bug #151209 showed.
njncda2f0f2009-05-18 02:12:08 +0000524 return sr_Res( VG_(do_syscall0)(__NR_getegid32) );
sewardjd470bfc2006-10-17 02:16:44 +0000525# else
njncda2f0f2009-05-18 02:12:08 +0000526 return sr_Res( VG_(do_syscall0)(__NR_getegid) );
sewardjd470bfc2006-10-17 02:16:44 +0000527# endif
sewardj45f4e7c2005-09-27 19:20:21 +0000528}
529
530/* Get supplementary groups into list[0 .. size-1]. Returns the
531 number of groups written, or -1 if error. Note that in order to be
532 portable, the groups are 32-bit unsigned ints regardless of the
533 platform. */
534Int VG_(getgroups)( Int size, UInt* list )
535{
sewardja48a4932005-09-29 11:09:56 +0000536# if defined(VGP_x86_linux) || defined(VGP_ppc32_linux)
sewardj45f4e7c2005-09-27 19:20:21 +0000537 Int i;
538 SysRes sres;
sewardj3ae3dd32005-12-27 02:08:03 +0000539 UShort list16[64];
sewardj45f4e7c2005-09-27 19:20:21 +0000540 if (size < 0) return -1;
sewardj3ae3dd32005-12-27 02:08:03 +0000541 if (size > 64) size = 64;
sewardj45f4e7c2005-09-27 19:20:21 +0000542 sres = VG_(do_syscall2)(__NR_getgroups, size, (Addr)list16);
njncda2f0f2009-05-18 02:12:08 +0000543 if (sr_isError(sres))
sewardj45f4e7c2005-09-27 19:20:21 +0000544 return -1;
njncda2f0f2009-05-18 02:12:08 +0000545 if (sr_Res(sres) > size)
sewardj45f4e7c2005-09-27 19:20:21 +0000546 return -1;
njncda2f0f2009-05-18 02:12:08 +0000547 for (i = 0; i < sr_Res(sres); i++)
sewardj45f4e7c2005-09-27 19:20:21 +0000548 list[i] = (UInt)list16[i];
njncda2f0f2009-05-18 02:12:08 +0000549 return sr_Res(sres);
sewardj45f4e7c2005-09-27 19:20:21 +0000550
sewardj59570ff2010-01-01 11:59:33 +0000551# elif defined(VGP_amd64_linux) || defined(VGP_ppc64_linux) \
552 || defined(VGP_arm_linux) \
sewardj5db15402012-06-07 09:13:21 +0000553 || defined(VGO_darwin) || defined(VGP_s390x_linux) \
554 || defined(VGP_mips32_linux)
sewardj45f4e7c2005-09-27 19:20:21 +0000555 SysRes sres;
556 sres = VG_(do_syscall2)(__NR_getgroups, size, (Addr)list);
njncda2f0f2009-05-18 02:12:08 +0000557 if (sr_isError(sres))
sewardj45f4e7c2005-09-27 19:20:21 +0000558 return -1;
njncda2f0f2009-05-18 02:12:08 +0000559 return sr_Res(sres);
sewardj45f4e7c2005-09-27 19:20:21 +0000560
561# else
562# error "VG_(getgroups): needs implementation on this platform"
563# endif
564}
565
566/* ---------------------------------------------------------------------
567 Process tracing
568 ------------------------------------------------------------------ */
569
570Int VG_(ptrace) ( Int request, Int pid, void *addr, void *data )
571{
572 SysRes res;
573 res = VG_(do_syscall4)(__NR_ptrace, request, pid, (UWord)addr, (UWord)data);
njncda2f0f2009-05-18 02:12:08 +0000574 if (sr_isError(res))
sewardj45f4e7c2005-09-27 19:20:21 +0000575 return -1;
njncda2f0f2009-05-18 02:12:08 +0000576 return sr_Res(res);
sewardj45f4e7c2005-09-27 19:20:21 +0000577}
578
579/* ---------------------------------------------------------------------
580 Fork
581 ------------------------------------------------------------------ */
582
583Int VG_(fork) ( void )
584{
sewardj6e9de462011-06-28 07:25:29 +0000585# if defined(VGO_linux)
sewardj45f4e7c2005-09-27 19:20:21 +0000586 SysRes res;
587 res = VG_(do_syscall0)(__NR_fork);
njncda2f0f2009-05-18 02:12:08 +0000588 if (sr_isError(res))
sewardj45f4e7c2005-09-27 19:20:21 +0000589 return -1;
njncda2f0f2009-05-18 02:12:08 +0000590 return sr_Res(res);
591
njnf76d27a2009-05-28 01:53:07 +0000592# elif defined(VGO_darwin)
593 SysRes res;
594 res = VG_(do_syscall0)(__NR_fork); /* __NR_fork is UX64 */
595 if (sr_isError(res))
596 return -1;
597 /* on success: wLO = child pid; wHI = 1 for child, 0 for parent */
598 if (sr_ResHI(res) != 0) {
599 return 0; /* this is child: return 0 instead of child pid */
600 }
601 return sr_Res(res);
602
njncda2f0f2009-05-18 02:12:08 +0000603# else
604# error "Unknown OS"
605# endif
njnf39e9a32005-06-12 02:43:17 +0000606}
607
608/* ---------------------------------------------------------------------
609 Timing stuff
sewardj5f07b662002-04-23 16:52:51 +0000610 ------------------------------------------------------------------ */
611
sewardj5f07b662002-04-23 16:52:51 +0000612UInt VG_(read_millisecond_timer) ( void )
613{
sewardjd470bfc2006-10-17 02:16:44 +0000614 /* 'now' and 'base' are in microseconds */
fitzhardinge426f9e62004-01-25 03:44:18 +0000615 static ULong base = 0;
sewardja8d8e232005-06-07 20:04:56 +0000616 ULong now;
sewardj5f07b662002-04-23 16:52:51 +0000617
njncda2f0f2009-05-18 02:12:08 +0000618# if defined(VGO_linux)
619 { SysRes res;
620 struct vki_timespec ts_now;
621 res = VG_(do_syscall2)(__NR_clock_gettime, VKI_CLOCK_MONOTONIC,
622 (UWord)&ts_now);
623 if (sr_isError(res) == 0) {
624 now = ts_now.tv_sec * 1000000ULL + ts_now.tv_nsec / 1000;
625 } else {
626 struct vki_timeval tv_now;
627 res = VG_(do_syscall2)(__NR_gettimeofday, (UWord)&tv_now, (UWord)NULL);
628 vg_assert(! sr_isError(res));
629 now = tv_now.tv_sec * 1000000ULL + tv_now.tv_usec;
630 }
631 }
632
njnf76d27a2009-05-28 01:53:07 +0000633# elif defined(VGO_darwin)
njnbe7e31a2009-07-22 02:52:14 +0000634 // Weird: it seems that gettimeofday() doesn't fill in the timeval, but
635 // rather returns the tv_sec as the low 32 bits of the result and the
636 // tv_usec as the high 32 bits of the result. (But the timeval cannot be
637 // NULL!) See bug 200990.
njnf76d27a2009-05-28 01:53:07 +0000638 { SysRes res;
bart8f992592009-07-21 17:46:56 +0000639 struct vki_timeval tv_now = { 0, 0 };
njnf76d27a2009-05-28 01:53:07 +0000640 res = VG_(do_syscall2)(__NR_gettimeofday, (UWord)&tv_now, (UWord)NULL);
641 vg_assert(! sr_isError(res));
njnbe7e31a2009-07-22 02:52:14 +0000642 now = sr_Res(res) * 1000000ULL + sr_ResHI(res);
njnf76d27a2009-05-28 01:53:07 +0000643 }
644
njncda2f0f2009-05-18 02:12:08 +0000645# else
646# error "Unknown OS"
sewardjd470bfc2006-10-17 02:16:44 +0000647# endif
njncda2f0f2009-05-18 02:12:08 +0000648
649 /* COMMON CODE */
fitzhardinge66871692004-01-25 03:32:58 +0000650 if (base == 0)
651 base = now;
sewardj5f07b662002-04-23 16:52:51 +0000652
fitzhardinge66871692004-01-25 03:32:58 +0000653 return (now - base) / 1000;
sewardj5f07b662002-04-23 16:52:51 +0000654}
655
njncda2f0f2009-05-18 02:12:08 +0000656
sewardj5f07b662002-04-23 16:52:51 +0000657/* ---------------------------------------------------------------------
njne9ba34a2008-10-13 04:19:15 +0000658 atfork()
sewardja8d8e232005-06-07 20:04:56 +0000659 ------------------------------------------------------------------ */
660
njne9ba34a2008-10-13 04:19:15 +0000661struct atfork {
662 vg_atfork_t pre;
663 vg_atfork_t parent;
664 vg_atfork_t child;
665};
sewardja8d8e232005-06-07 20:04:56 +0000666
njne9ba34a2008-10-13 04:19:15 +0000667#define VG_MAX_ATFORK 10
sewardja8d8e232005-06-07 20:04:56 +0000668
njne9ba34a2008-10-13 04:19:15 +0000669static struct atfork atforks[VG_MAX_ATFORK];
670static Int n_atfork = 0;
671
672void VG_(atfork)(vg_atfork_t pre, vg_atfork_t parent, vg_atfork_t child)
sewardja8d8e232005-06-07 20:04:56 +0000673{
njne9ba34a2008-10-13 04:19:15 +0000674 Int i;
sewardja8d8e232005-06-07 20:04:56 +0000675
njne9ba34a2008-10-13 04:19:15 +0000676 for (i = 0; i < n_atfork; i++) {
677 if (atforks[i].pre == pre &&
678 atforks[i].parent == parent &&
679 atforks[i].child == child)
680 return;
681 }
682
683 if (n_atfork >= VG_MAX_ATFORK)
684 VG_(core_panic)(
685 "Too many VG_(atfork) handlers requested: raise VG_MAX_ATFORK");
686
687 atforks[n_atfork].pre = pre;
688 atforks[n_atfork].parent = parent;
689 atforks[n_atfork].child = child;
690
691 n_atfork++;
692}
693
694void VG_(do_atfork_pre)(ThreadId tid)
695{
696 Int i;
697
698 for (i = 0; i < n_atfork; i++)
699 if (atforks[i].pre != NULL)
700 (*atforks[i].pre)(tid);
701}
702
703void VG_(do_atfork_parent)(ThreadId tid)
704{
705 Int i;
706
707 for (i = 0; i < n_atfork; i++)
708 if (atforks[i].parent != NULL)
709 (*atforks[i].parent)(tid);
sewardja8d8e232005-06-07 20:04:56 +0000710}
711
712void VG_(do_atfork_child)(ThreadId tid)
713{
njne9ba34a2008-10-13 04:19:15 +0000714 Int i;
715
716 for (i = 0; i < n_atfork; i++)
717 if (atforks[i].child != NULL)
718 (*atforks[i].child)(tid);
sewardja8d8e232005-06-07 20:04:56 +0000719}
720
njnf76d27a2009-05-28 01:53:07 +0000721
sewardj291849f2012-04-20 23:58:55 +0000722/* ---------------------------------------------------------------------
723 icache invalidation
724 ------------------------------------------------------------------ */
725
726void VG_(invalidate_icache) ( void *ptr, SizeT nbytes )
727{
florian78627012012-10-07 19:47:04 +0000728 if (nbytes == 0) return; // nothing to do
729
730 // Get cache info
731 VexArchInfo vai;
732 VG_(machine_get_VexArchInfo)(NULL, &vai);
733
734 // If I-caches are coherent, nothing needs to be done here
735 if (vai.hwcache_info.icaches_maintain_coherence) return;
736
sewardj291849f2012-04-20 23:58:55 +0000737# if defined(VGA_ppc32) || defined(VGA_ppc64)
738 Addr startaddr = (Addr) ptr;
739 Addr endaddr = startaddr + nbytes;
740 Addr cls;
741 Addr addr;
sewardj291849f2012-04-20 23:58:55 +0000742
sewardj291849f2012-04-20 23:58:55 +0000743 VG_(machine_get_VexArchInfo)( NULL, &vai );
744 cls = vai.ppc_cache_line_szB;
745
746 /* Stay sane .. */
747 vg_assert(cls == 32 || cls == 64 || cls == 128);
748
749 startaddr &= ~(cls - 1);
750 for (addr = startaddr; addr < endaddr; addr += cls) {
751 __asm__ __volatile__("dcbst 0,%0" : : "r" (addr));
752 }
753 __asm__ __volatile__("sync");
754 for (addr = startaddr; addr < endaddr; addr += cls) {
755 __asm__ __volatile__("icbi 0,%0" : : "r" (addr));
756 }
757 __asm__ __volatile__("sync; isync");
758
sewardj291849f2012-04-20 23:58:55 +0000759# elif defined(VGP_arm_linux)
760 /* ARM cache flushes are privileged, so we must defer to the kernel. */
761 Addr startaddr = (Addr) ptr;
762 Addr endaddr = startaddr + nbytes;
763 VG_(do_syscall2)(__NR_ARM_cacheflush, startaddr, endaddr);
764
sewardj5db15402012-06-07 09:13:21 +0000765# elif defined(VGA_mips32)
766 SysRes sres = VG_(do_syscall3)(__NR_cacheflush, (UWord) ptr,
767 (UWord) nbytes, (UWord) 3);
768 vg_assert( sres._isError == 0 );
769
sewardj291849f2012-04-20 23:58:55 +0000770# endif
771}
772
773
sewardjde4a1d02002-03-22 01:27:54 +0000774/*--------------------------------------------------------------------*/
njnc6168192004-11-29 13:54:10 +0000775/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +0000776/*--------------------------------------------------------------------*/