1 2 /*--------------------------------------------------------------------*/ 3 /*--- Process-related libc stuff. m_libcproc.c ---*/ 4 /*--------------------------------------------------------------------*/ 5 6 /* 7 This file is part of Valgrind, a dynamic binary instrumentation 8 framework. 9 10 Copyright (C) 2000-2013 Julian Seward 11 jseward (at) acm.org 12 13 This program is free software; you can redistribute it and/or 14 modify it under the terms of the GNU General Public License as 15 published by the Free Software Foundation; either version 2 of the 16 License, or (at your option) any later version. 17 18 This program is distributed in the hope that it will be useful, but 19 WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 General Public License for more details. 22 23 You should have received a copy of the GNU General Public License 24 along with this program; if not, write to the Free Software 25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 26 02111-1307, USA. 27 28 The GNU General Public License is contained in the file COPYING. 29 */ 30 31 #include "pub_core_basics.h" 32 #include "pub_core_machine.h" // For VG_(machine_get_VexArchInfo) 33 #include "pub_core_vki.h" 34 #include "pub_core_vkiscnums.h" 35 #include "pub_core_libcbase.h" 36 #include "pub_core_libcassert.h" 37 #include "pub_core_libcprint.h" 38 #include "pub_core_libcproc.h" 39 #include "pub_core_libcsignal.h" 40 #include "pub_core_seqmatch.h" 41 #include "pub_core_mallocfree.h" 42 #include "pub_core_syscall.h" 43 #include "pub_core_xarray.h" 44 #include "pub_core_clientstate.h" 45 46 #if defined(VGO_darwin) 47 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */ 48 #include <mach/mach.h> /* mach_thread_self */ 49 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */ 50 #endif 51 52 /* IMPORTANT: on Darwin it is essential to use the _nocancel versions 53 of syscalls rather than the vanilla version, if a _nocancel version 54 is available. See docs/internals/Darwin-notes.txt for the reason 55 why. */ 56 57 /* --------------------------------------------------------------------- 58 Command line and environment stuff 59 ------------------------------------------------------------------ */ 60 61 /* As deduced from sp_at_startup, the client's argc, argv[] and 62 envp[] as extracted from the client's stack at startup-time. */ 63 HChar** VG_(client_envp) = NULL; 64 65 /* Path to library directory */ 66 const HChar *VG_(libdir) = VG_LIBDIR; 67 68 const HChar *VG_(LD_PRELOAD_var_name) = 69 #if defined(VGO_linux) 70 "LD_PRELOAD"; 71 #elif defined(VGO_darwin) 72 "DYLD_INSERT_LIBRARIES"; 73 #else 74 # error Unknown OS 75 #endif 76 77 /* We do getenv without libc's help by snooping around in 78 VG_(client_envp) as determined at startup time. */ 79 HChar *VG_(getenv)(const HChar *varname) 80 { 81 Int i, n; 82 vg_assert( VG_(client_envp) ); 83 n = VG_(strlen)(varname); 84 for (i = 0; VG_(client_envp)[i] != NULL; i++) { 85 HChar* s = VG_(client_envp)[i]; 86 if (VG_(strncmp)(varname, s, n) == 0 && s[n] == '=') { 87 return & s[n+1]; 88 } 89 } 90 return NULL; 91 } 92 93 void VG_(env_unsetenv) ( HChar **env, const HChar *varname ) 94 { 95 HChar **from, **to; 96 vg_assert(env); 97 vg_assert(varname); 98 to = NULL; 99 Int len = VG_(strlen)(varname); 100 101 for (from = to = env; from && *from; from++) { 102 if (!(VG_(strncmp)(varname, *from, len) == 0 && (*from)[len] == '=')) { 103 *to = *from; 104 to++; 105 } 106 } 107 *to = *from; 108 } 109 110 /* set the environment; returns the old env if a new one was allocated */ 111 HChar **VG_(env_setenv) ( HChar ***envp, const HChar* varname, 112 const HChar *val ) 113 { 114 HChar **env = (*envp); 115 HChar **cpp; 116 Int len = VG_(strlen)(varname); 117 HChar *valstr = VG_(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 */ 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. 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 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 */ 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 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! */ 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 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. */ 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. */ 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. */ 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 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. */ 502 Int VG_(getpid) ( void ) 503 { 504 /* ASSUMES SYSCALL ALWAYS SUCCEEDS */ 505 return sr_Res( VG_(do_syscall0)(__NR_getpid) ); 506 } 507 508 Int VG_(getpgrp) ( void ) 509 { 510 /* ASSUMES SYSCALL ALWAYS SUCCEEDS */ 511 return sr_Res( VG_(do_syscall0)(__NR_getpgrp) ); 512 } 513 514 Int VG_(getppid) ( void ) 515 { 516 /* ASSUMES SYSCALL ALWAYS SUCCEEDS */ 517 return sr_Res( VG_(do_syscall0)(__NR_getppid) ); 518 } 519 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 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. */ 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 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 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 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 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 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 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 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 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 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 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