vgdb-invoker-ptrace.c revision 582d58245637ab05272d89fb94b12fd0f18fa0f8
13c761f0f0344757ac243c65511392fb41d1c841aphilippe/*--------------------------------------------------------------------*/ 23c761f0f0344757ac243c65511392fb41d1c841aphilippe/*--- Implementation of vgdb invoker subsystem via ptrace() calls. ---*/ 33c761f0f0344757ac243c65511392fb41d1c841aphilippe/*--------------------------------------------------------------------*/ 43c761f0f0344757ac243c65511392fb41d1c841aphilippe 53c761f0f0344757ac243c65511392fb41d1c841aphilippe/* 63c761f0f0344757ac243c65511392fb41d1c841aphilippe This file is part of Valgrind, a dynamic binary instrumentation 73c761f0f0344757ac243c65511392fb41d1c841aphilippe framework. 83c761f0f0344757ac243c65511392fb41d1c841aphilippe 93c761f0f0344757ac243c65511392fb41d1c841aphilippe Copyright (C) 2011-2013 Philippe Waroquiers 103c761f0f0344757ac243c65511392fb41d1c841aphilippe 113c761f0f0344757ac243c65511392fb41d1c841aphilippe This program is free software; you can redistribute it and/or 123c761f0f0344757ac243c65511392fb41d1c841aphilippe modify it under the terms of the GNU General Public License as 133c761f0f0344757ac243c65511392fb41d1c841aphilippe published by the Free Software Foundation; either version 2 of the 143c761f0f0344757ac243c65511392fb41d1c841aphilippe License, or (at your option) any later version. 153c761f0f0344757ac243c65511392fb41d1c841aphilippe 163c761f0f0344757ac243c65511392fb41d1c841aphilippe This program is distributed in the hope that it will be useful, but 173c761f0f0344757ac243c65511392fb41d1c841aphilippe WITHOUT ANY WARRANTY; without even the implied warranty of 183c761f0f0344757ac243c65511392fb41d1c841aphilippe MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 193c761f0f0344757ac243c65511392fb41d1c841aphilippe General Public License for more details. 203c761f0f0344757ac243c65511392fb41d1c841aphilippe 213c761f0f0344757ac243c65511392fb41d1c841aphilippe You should have received a copy of the GNU General Public License 223c761f0f0344757ac243c65511392fb41d1c841aphilippe along with this program; if not, write to the Free Software 233c761f0f0344757ac243c65511392fb41d1c841aphilippe Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 243c761f0f0344757ac243c65511392fb41d1c841aphilippe 02111-1307, USA. 253c761f0f0344757ac243c65511392fb41d1c841aphilippe 263c761f0f0344757ac243c65511392fb41d1c841aphilippe The GNU General Public License is contained in the file COPYING. 273c761f0f0344757ac243c65511392fb41d1c841aphilippe*/ 283c761f0f0344757ac243c65511392fb41d1c841aphilippe 293c761f0f0344757ac243c65511392fb41d1c841aphilippe#include "config.h" 303c761f0f0344757ac243c65511392fb41d1c841aphilippe 313c761f0f0344757ac243c65511392fb41d1c841aphilippe#include "vgdb.h" 323c761f0f0344757ac243c65511392fb41d1c841aphilippe#include "pub_core_threadstate.h" 333c761f0f0344757ac243c65511392fb41d1c841aphilippe 343c761f0f0344757ac243c65511392fb41d1c841aphilippe#include <alloca.h> 353c761f0f0344757ac243c65511392fb41d1c841aphilippe#include <assert.h> 363c761f0f0344757ac243c65511392fb41d1c841aphilippe#include <errno.h> 373c761f0f0344757ac243c65511392fb41d1c841aphilippe#include <stdio.h> 383c761f0f0344757ac243c65511392fb41d1c841aphilippe#include <stdlib.h> 393c761f0f0344757ac243c65511392fb41d1c841aphilippe#include <string.h> 403c761f0f0344757ac243c65511392fb41d1c841aphilippe#include <sys/ptrace.h> 413c761f0f0344757ac243c65511392fb41d1c841aphilippe#include <sys/time.h> 423c761f0f0344757ac243c65511392fb41d1c841aphilippe#include <sys/user.h> 433c761f0f0344757ac243c65511392fb41d1c841aphilippe#include <sys/wait.h> 443c761f0f0344757ac243c65511392fb41d1c841aphilippe 45c07369bc8be6f6a26adfdbe391be7fe64a211829philippe#ifdef PTRACE_GETREGSET 46c07369bc8be6f6a26adfdbe391be7fe64a211829philippe// TBD: better have a configure test instead ? 47c07369bc8be6f6a26adfdbe391be7fe64a211829philippe#define HAVE_PTRACE_GETREGSET 48c07369bc8be6f6a26adfdbe391be7fe64a211829philippe 49c07369bc8be6f6a26adfdbe391be7fe64a211829philippe// A bi-arch build using PTRACE_GET/SETREGSET needs 50c07369bc8be6f6a26adfdbe391be7fe64a211829philippe// some conversion code for register structures. 51c07369bc8be6f6a26adfdbe391be7fe64a211829philippe// So, better do not use PTRACE_GET/SETREGSET 52c07369bc8be6f6a26adfdbe391be7fe64a211829philippe// Rather we use PTRACE_GETREGS or PTRACE_PEEKUSER. 53c07369bc8be6f6a26adfdbe391be7fe64a211829philippe 54c07369bc8be6f6a26adfdbe391be7fe64a211829philippe// The only platform on which we must use PTRACE_GETREGSET is arm64. 55c07369bc8be6f6a26adfdbe391be7fe64a211829philippe// The resulting vgdb cannot work in a bi-arch setup. 56c07369bc8be6f6a26adfdbe391be7fe64a211829philippe// -1 means we will check that PTRACE_GETREGSET works. 57c07369bc8be6f6a26adfdbe391be7fe64a211829philippe# if defined(VGA_arm64) 58c07369bc8be6f6a26adfdbe391be7fe64a211829philippe#define USE_PTRACE_GETREGSET 59c07369bc8be6f6a26adfdbe391be7fe64a211829philippe# endif 60c07369bc8be6f6a26adfdbe391be7fe64a211829philippe#endif 61c07369bc8be6f6a26adfdbe391be7fe64a211829philippe 62c07369bc8be6f6a26adfdbe391be7fe64a211829philippe#include <sys/uio.h> 63c07369bc8be6f6a26adfdbe391be7fe64a211829philippe#include <elf.h> 64c07369bc8be6f6a26adfdbe391be7fe64a211829philippe 65c07369bc8be6f6a26adfdbe391be7fe64a211829philippe#include <sys/procfs.h> 66c07369bc8be6f6a26adfdbe391be7fe64a211829philippe 673b4ef11d87596b6d63d690caf517a3abf62d39d4florian#if defined(VGA_s390x) 683b4ef11d87596b6d63d690caf517a3abf62d39d4florian/* RHEL 5 uses glibc 2.3.4 which does not define PTRACE_GETSIGINFO */ 693b4ef11d87596b6d63d690caf517a3abf62d39d4florian# ifndef PTRACE_GETSIGINFO 703b4ef11d87596b6d63d690caf517a3abf62d39d4florian# define PTRACE_GETSIGINFO 0x4202 713b4ef11d87596b6d63d690caf517a3abf62d39d4florian# endif 723b4ef11d87596b6d63d690caf517a3abf62d39d4florian#endif 733b4ef11d87596b6d63d690caf517a3abf62d39d4florian 743c761f0f0344757ac243c65511392fb41d1c841aphilippe#if VEX_HOST_WORDSIZE == 8 753c761f0f0344757ac243c65511392fb41d1c841aphilippetypedef Addr64 CORE_ADDR; 763c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif VEX_HOST_WORDSIZE == 4 773c761f0f0344757ac243c65511392fb41d1c841aphilippetypedef Addr32 CORE_ADDR; 783c761f0f0344757ac243c65511392fb41d1c841aphilippe#else 793c761f0f0344757ac243c65511392fb41d1c841aphilippe# error "unexpected wordsize" 803c761f0f0344757ac243c65511392fb41d1c841aphilippe#endif 813c761f0f0344757ac243c65511392fb41d1c841aphilippe 823c761f0f0344757ac243c65511392fb41d1c841aphilippe#if VEX_HOST_WORDSIZE == 8 833c761f0f0344757ac243c65511392fb41d1c841aphilippetypedef Addr64 PTRACE_XFER_TYPE; 843c761f0f0344757ac243c65511392fb41d1c841aphilippetypedef void* PTRACE_ARG3_TYPE; 853c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif VEX_HOST_WORDSIZE == 4 863c761f0f0344757ac243c65511392fb41d1c841aphilippetypedef Addr32 PTRACE_XFER_TYPE; 873c761f0f0344757ac243c65511392fb41d1c841aphilippetypedef void* PTRACE_ARG3_TYPE; 883c761f0f0344757ac243c65511392fb41d1c841aphilippe#else 893c761f0f0344757ac243c65511392fb41d1c841aphilippe# error "unexpected wordsize" 903c761f0f0344757ac243c65511392fb41d1c841aphilippe#endif 913c761f0f0344757ac243c65511392fb41d1c841aphilippe 926654de8547d2e420c20e21980669b807aa80710ephilippe// if > 0, pid for which registers have to be restored. 936654de8547d2e420c20e21980669b807aa80710ephilippe// if == 0, means we have not yet called setregs (or have already 946654de8547d2e420c20e21980669b807aa80710ephilippe// restored the registers). 956654de8547d2e420c20e21980669b807aa80710ephilippestatic int pid_of_save_regs = 0; 963c761f0f0344757ac243c65511392fb41d1c841aphilippe/* True if we have continued pid_of_save_regs after PTRACE_ATTACH. */ 973c761f0f0344757ac243c65511392fb41d1c841aphilippestatic Bool pid_of_save_regs_continued = False; 986654de8547d2e420c20e21980669b807aa80710ephilippe// When setregs has been called to change the registers of pid_of_save_regs, 996654de8547d2e420c20e21980669b807aa80710ephilippe// vgdb cannot transmit the signals intercepted during ptrace. 1006654de8547d2e420c20e21980669b807aa80710ephilippe// So, we queue them, and will deliver them when detaching. 1016654de8547d2e420c20e21980669b807aa80710ephilippe// See function waitstopped for more info. 1026654de8547d2e420c20e21980669b807aa80710ephilippestatic int signal_queue_sz = 0; 1036654de8547d2e420c20e21980669b807aa80710ephilippestatic siginfo_t *signal_queue; 1043c761f0f0344757ac243c65511392fb41d1c841aphilippe 1053c761f0f0344757ac243c65511392fb41d1c841aphilippe/* True when loss of connection indicating that the Valgrind 1063c761f0f0344757ac243c65511392fb41d1c841aphilippe process is dying. */ 1073c761f0f0344757ac243c65511392fb41d1c841aphilippestatic Bool dying = False; 1083c761f0f0344757ac243c65511392fb41d1c841aphilippe 1093c761f0f0344757ac243c65511392fb41d1c841aphilippe/* ptrace_(read|write)_memory are modified extracts of linux-low.c 1103c761f0f0344757ac243c65511392fb41d1c841aphilippe from gdb 6.6. Copyrighted FSF */ 1113c761f0f0344757ac243c65511392fb41d1c841aphilippe/* Copy LEN bytes from valgrind memory starting at MEMADDR 1123c761f0f0344757ac243c65511392fb41d1c841aphilippe to vgdb memory starting at MYADDR. */ 1133c761f0f0344757ac243c65511392fb41d1c841aphilippestatic 1143c761f0f0344757ac243c65511392fb41d1c841aphilippeint ptrace_read_memory (pid_t inferior_pid, CORE_ADDR memaddr, 1153c761f0f0344757ac243c65511392fb41d1c841aphilippe void *myaddr, size_t len) 1163c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 1173c761f0f0344757ac243c65511392fb41d1c841aphilippe register int i; 1183c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Round starting address down to longword boundary. */ 1193c761f0f0344757ac243c65511392fb41d1c841aphilippe register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE); 1203c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Round ending address up; get number of longwords that makes. */ 1213c761f0f0344757ac243c65511392fb41d1c841aphilippe register int count 1223c761f0f0344757ac243c65511392fb41d1c841aphilippe = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) 1233c761f0f0344757ac243c65511392fb41d1c841aphilippe / sizeof (PTRACE_XFER_TYPE); 1243c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Allocate buffer of that many longwords. */ 1253c761f0f0344757ac243c65511392fb41d1c841aphilippe register PTRACE_XFER_TYPE *buffer 1263c761f0f0344757ac243c65511392fb41d1c841aphilippe = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE)); 1273c761f0f0344757ac243c65511392fb41d1c841aphilippe 1283c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Read all the longwords */ 1293c761f0f0344757ac243c65511392fb41d1c841aphilippe for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) { 1303c761f0f0344757ac243c65511392fb41d1c841aphilippe errno = 0; 1313c761f0f0344757ac243c65511392fb41d1c841aphilippe buffer[i] = ptrace (PTRACE_PEEKTEXT, inferior_pid, 1323c761f0f0344757ac243c65511392fb41d1c841aphilippe (PTRACE_ARG3_TYPE) addr, 0); 1333c761f0f0344757ac243c65511392fb41d1c841aphilippe if (errno) 1343c761f0f0344757ac243c65511392fb41d1c841aphilippe return errno; 1353c761f0f0344757ac243c65511392fb41d1c841aphilippe } 1363c761f0f0344757ac243c65511392fb41d1c841aphilippe 1373c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Copy appropriate bytes out of the buffer. */ 1383c761f0f0344757ac243c65511392fb41d1c841aphilippe memcpy (myaddr, 1393c761f0f0344757ac243c65511392fb41d1c841aphilippe (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), len); 1403c761f0f0344757ac243c65511392fb41d1c841aphilippe 1413c761f0f0344757ac243c65511392fb41d1c841aphilippe return 0; 1423c761f0f0344757ac243c65511392fb41d1c841aphilippe} 1433c761f0f0344757ac243c65511392fb41d1c841aphilippe 1443c761f0f0344757ac243c65511392fb41d1c841aphilippe/* Copy LEN bytes of data from vgdb memory at MYADDR 1453c761f0f0344757ac243c65511392fb41d1c841aphilippe to valgrind memory at MEMADDR. 1463c761f0f0344757ac243c65511392fb41d1c841aphilippe On failure (cannot write the valgrind memory) 1473c761f0f0344757ac243c65511392fb41d1c841aphilippe returns the value of errno. */ 1483c761f0f0344757ac243c65511392fb41d1c841aphilippe__attribute__((unused)) /* not used on all platforms */ 1493c761f0f0344757ac243c65511392fb41d1c841aphilippestatic 1503c761f0f0344757ac243c65511392fb41d1c841aphilippeint ptrace_write_memory (pid_t inferior_pid, CORE_ADDR memaddr, 1513c761f0f0344757ac243c65511392fb41d1c841aphilippe const void *myaddr, size_t len) 1523c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 1533c761f0f0344757ac243c65511392fb41d1c841aphilippe register int i; 1543c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Round starting address down to longword boundary. */ 1553c761f0f0344757ac243c65511392fb41d1c841aphilippe register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE); 1563c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Round ending address up; get number of longwords that makes. */ 1573c761f0f0344757ac243c65511392fb41d1c841aphilippe register int count 1583c761f0f0344757ac243c65511392fb41d1c841aphilippe = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) 1593c761f0f0344757ac243c65511392fb41d1c841aphilippe / sizeof (PTRACE_XFER_TYPE); 1603c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Allocate buffer of that many longwords. */ 1613c761f0f0344757ac243c65511392fb41d1c841aphilippe register PTRACE_XFER_TYPE *buffer 1623c761f0f0344757ac243c65511392fb41d1c841aphilippe = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE)); 1633c761f0f0344757ac243c65511392fb41d1c841aphilippe 1643c761f0f0344757ac243c65511392fb41d1c841aphilippe if (debuglevel >= 1) { 1653c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG (1, "Writing "); 1663c761f0f0344757ac243c65511392fb41d1c841aphilippe for (i = 0; i < len; i++) 1673c761f0f0344757ac243c65511392fb41d1c841aphilippe PDEBUG (1, "%02x", ((const unsigned char*)myaddr)[i]); 1683c761f0f0344757ac243c65511392fb41d1c841aphilippe PDEBUG(1, " to %p\n", (void *) memaddr); 1693c761f0f0344757ac243c65511392fb41d1c841aphilippe } 1703c761f0f0344757ac243c65511392fb41d1c841aphilippe 1713c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Fill start and end extra bytes of buffer with existing memory data. */ 1723c761f0f0344757ac243c65511392fb41d1c841aphilippe 1733c761f0f0344757ac243c65511392fb41d1c841aphilippe buffer[0] = ptrace (PTRACE_PEEKTEXT, inferior_pid, 1743c761f0f0344757ac243c65511392fb41d1c841aphilippe (PTRACE_ARG3_TYPE) addr, 0); 1753c761f0f0344757ac243c65511392fb41d1c841aphilippe 1763c761f0f0344757ac243c65511392fb41d1c841aphilippe if (count > 1) { 1773c761f0f0344757ac243c65511392fb41d1c841aphilippe buffer[count - 1] 1783c761f0f0344757ac243c65511392fb41d1c841aphilippe = ptrace (PTRACE_PEEKTEXT, inferior_pid, 1793c761f0f0344757ac243c65511392fb41d1c841aphilippe (PTRACE_ARG3_TYPE) (addr + (count - 1) 1803c761f0f0344757ac243c65511392fb41d1c841aphilippe * sizeof (PTRACE_XFER_TYPE)), 1813c761f0f0344757ac243c65511392fb41d1c841aphilippe 0); 1823c761f0f0344757ac243c65511392fb41d1c841aphilippe } 1833c761f0f0344757ac243c65511392fb41d1c841aphilippe 1843c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Copy data to be written over corresponding part of buffer */ 1853c761f0f0344757ac243c65511392fb41d1c841aphilippe 1863c761f0f0344757ac243c65511392fb41d1c841aphilippe memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), 1873c761f0f0344757ac243c65511392fb41d1c841aphilippe myaddr, len); 1883c761f0f0344757ac243c65511392fb41d1c841aphilippe 1893c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Write the entire buffer. */ 1903c761f0f0344757ac243c65511392fb41d1c841aphilippe 1913c761f0f0344757ac243c65511392fb41d1c841aphilippe for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) { 1923c761f0f0344757ac243c65511392fb41d1c841aphilippe errno = 0; 1933c761f0f0344757ac243c65511392fb41d1c841aphilippe ptrace (PTRACE_POKETEXT, inferior_pid, 1943c761f0f0344757ac243c65511392fb41d1c841aphilippe (PTRACE_ARG3_TYPE) addr, buffer[i]); 1953c761f0f0344757ac243c65511392fb41d1c841aphilippe if (errno) 1963c761f0f0344757ac243c65511392fb41d1c841aphilippe return errno; 1973c761f0f0344757ac243c65511392fb41d1c841aphilippe } 1983c761f0f0344757ac243c65511392fb41d1c841aphilippe 1993c761f0f0344757ac243c65511392fb41d1c841aphilippe return 0; 2003c761f0f0344757ac243c65511392fb41d1c841aphilippe} 2013c761f0f0344757ac243c65511392fb41d1c841aphilippe 2023c761f0f0344757ac243c65511392fb41d1c841aphilippe/* subset of VG_(threads) needed for vgdb ptrace. 2033c761f0f0344757ac243c65511392fb41d1c841aphilippe This is initialized when process is attached. */ 2043c761f0f0344757ac243c65511392fb41d1c841aphilippetypedef struct { 2053c761f0f0344757ac243c65511392fb41d1c841aphilippe ThreadStatus status; 2063c761f0f0344757ac243c65511392fb41d1c841aphilippe Int lwpid; 2073c761f0f0344757ac243c65511392fb41d1c841aphilippe} 2083c761f0f0344757ac243c65511392fb41d1c841aphilippeVgdbThreadState; 2093c761f0f0344757ac243c65511392fb41d1c841aphilippestatic VgdbThreadState vgdb_threads[VG_N_THREADS]; 2103c761f0f0344757ac243c65511392fb41d1c841aphilippe 2113c761f0f0344757ac243c65511392fb41d1c841aphilippestatic const 2123c761f0f0344757ac243c65511392fb41d1c841aphilippeHChar* name_of_ThreadStatus ( ThreadStatus status ) 2133c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 2143c761f0f0344757ac243c65511392fb41d1c841aphilippe switch (status) { 2153c761f0f0344757ac243c65511392fb41d1c841aphilippe case VgTs_Empty: return "VgTs_Empty"; 2163c761f0f0344757ac243c65511392fb41d1c841aphilippe case VgTs_Init: return "VgTs_Init"; 2173c761f0f0344757ac243c65511392fb41d1c841aphilippe case VgTs_Runnable: return "VgTs_Runnable"; 2183c761f0f0344757ac243c65511392fb41d1c841aphilippe case VgTs_WaitSys: return "VgTs_WaitSys"; 2193c761f0f0344757ac243c65511392fb41d1c841aphilippe case VgTs_Yielding: return "VgTs_Yielding"; 2203c761f0f0344757ac243c65511392fb41d1c841aphilippe case VgTs_Zombie: return "VgTs_Zombie"; 2213c761f0f0344757ac243c65511392fb41d1c841aphilippe default: return "VgTs_???"; 2223c761f0f0344757ac243c65511392fb41d1c841aphilippe } 2233c761f0f0344757ac243c65511392fb41d1c841aphilippe} 2243c761f0f0344757ac243c65511392fb41d1c841aphilippe 2253c761f0f0344757ac243c65511392fb41d1c841aphilippestatic 2263c761f0f0344757ac243c65511392fb41d1c841aphilippechar *status_image (int status) 2273c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 2283c761f0f0344757ac243c65511392fb41d1c841aphilippe static char result[256]; 2293c761f0f0344757ac243c65511392fb41d1c841aphilippe int sz = 0; 2303c761f0f0344757ac243c65511392fb41d1c841aphilippe#define APPEND(...) sz += snprintf (result+sz, 256 - sz - 1, __VA_ARGS__) 2313c761f0f0344757ac243c65511392fb41d1c841aphilippe 2323c761f0f0344757ac243c65511392fb41d1c841aphilippe result[0] = 0; 2333c761f0f0344757ac243c65511392fb41d1c841aphilippe 2343c761f0f0344757ac243c65511392fb41d1c841aphilippe if (WIFEXITED(status)) 2353c761f0f0344757ac243c65511392fb41d1c841aphilippe APPEND ("WIFEXITED %d ", WEXITSTATUS(status)); 2363c761f0f0344757ac243c65511392fb41d1c841aphilippe 2373c761f0f0344757ac243c65511392fb41d1c841aphilippe if (WIFSIGNALED(status)) { 2383c761f0f0344757ac243c65511392fb41d1c841aphilippe APPEND ("WIFSIGNALED %d ", WTERMSIG(status)); 2393c761f0f0344757ac243c65511392fb41d1c841aphilippe if (WCOREDUMP(status)) APPEND ("WCOREDUMP "); 2403c761f0f0344757ac243c65511392fb41d1c841aphilippe } 2413c761f0f0344757ac243c65511392fb41d1c841aphilippe 2423c761f0f0344757ac243c65511392fb41d1c841aphilippe if (WIFSTOPPED(status)) 2433c761f0f0344757ac243c65511392fb41d1c841aphilippe APPEND ("WIFSTOPPED %d ", WSTOPSIG(status)); 2443c761f0f0344757ac243c65511392fb41d1c841aphilippe 2453c761f0f0344757ac243c65511392fb41d1c841aphilippe#ifdef WIFCONTINUED 2463c761f0f0344757ac243c65511392fb41d1c841aphilippe if (WIFCONTINUED(status)) 2473c761f0f0344757ac243c65511392fb41d1c841aphilippe APPEND ("WIFCONTINUED "); 2483c761f0f0344757ac243c65511392fb41d1c841aphilippe#endif 2493c761f0f0344757ac243c65511392fb41d1c841aphilippe 2503c761f0f0344757ac243c65511392fb41d1c841aphilippe return result; 2513c761f0f0344757ac243c65511392fb41d1c841aphilippe#undef APPEND 2523c761f0f0344757ac243c65511392fb41d1c841aphilippe} 2533c761f0f0344757ac243c65511392fb41d1c841aphilippe 2543c761f0f0344757ac243c65511392fb41d1c841aphilippe/* Wait till the process pid is reported as stopped with signal_expected. 2553c761f0f0344757ac243c65511392fb41d1c841aphilippe If other signal(s) than signal_expected are received, waitstopped 2563c761f0f0344757ac243c65511392fb41d1c841aphilippe will pass them to pid, waiting for signal_expected to stop pid. 2573c761f0f0344757ac243c65511392fb41d1c841aphilippe Returns True when process is in stopped state with signal_expected. 2583c761f0f0344757ac243c65511392fb41d1c841aphilippe Returns False if a problem was encountered while waiting for pid 2593c761f0f0344757ac243c65511392fb41d1c841aphilippe to be stopped. 2603c761f0f0344757ac243c65511392fb41d1c841aphilippe 2613c761f0f0344757ac243c65511392fb41d1c841aphilippe If pid is reported as being dead/exited, waitstopped will return False. 2623c761f0f0344757ac243c65511392fb41d1c841aphilippe*/ 2633c761f0f0344757ac243c65511392fb41d1c841aphilippestatic 2643c761f0f0344757ac243c65511392fb41d1c841aphilippeBool waitstopped (pid_t pid, int signal_expected, const char *msg) 2653c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 2663c761f0f0344757ac243c65511392fb41d1c841aphilippe pid_t p; 2673c761f0f0344757ac243c65511392fb41d1c841aphilippe int status = 0; 2683c761f0f0344757ac243c65511392fb41d1c841aphilippe int signal_received; 2693c761f0f0344757ac243c65511392fb41d1c841aphilippe int res; 2703c761f0f0344757ac243c65511392fb41d1c841aphilippe 2713c761f0f0344757ac243c65511392fb41d1c841aphilippe while (1) { 2723c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "waitstopped %s before waitpid signal_expected %d\n", 2733c761f0f0344757ac243c65511392fb41d1c841aphilippe msg, signal_expected); 2743c761f0f0344757ac243c65511392fb41d1c841aphilippe p = waitpid(pid, &status, __WALL); 2753c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "after waitpid pid %d p %d status 0x%x %s\n", pid, p, 2763c761f0f0344757ac243c65511392fb41d1c841aphilippe status, status_image (status)); 2773c761f0f0344757ac243c65511392fb41d1c841aphilippe if (p != pid) { 2783c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(errno, "%s waitpid pid %d in waitstopped %d status 0x%x %s\n", 2793c761f0f0344757ac243c65511392fb41d1c841aphilippe msg, pid, p, status, status_image (status)); 2803c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 2813c761f0f0344757ac243c65511392fb41d1c841aphilippe } 2823c761f0f0344757ac243c65511392fb41d1c841aphilippe 2833c761f0f0344757ac243c65511392fb41d1c841aphilippe if (WIFEXITED(status)) { 2843c761f0f0344757ac243c65511392fb41d1c841aphilippe shutting_down = True; 2853c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 2863c761f0f0344757ac243c65511392fb41d1c841aphilippe } 2873c761f0f0344757ac243c65511392fb41d1c841aphilippe 2883c761f0f0344757ac243c65511392fb41d1c841aphilippe assert (WIFSTOPPED(status)); 2893c761f0f0344757ac243c65511392fb41d1c841aphilippe signal_received = WSTOPSIG(status); 2903c761f0f0344757ac243c65511392fb41d1c841aphilippe if (signal_received == signal_expected) 2913c761f0f0344757ac243c65511392fb41d1c841aphilippe break; 2923c761f0f0344757ac243c65511392fb41d1c841aphilippe 2933c761f0f0344757ac243c65511392fb41d1c841aphilippe /* pid received a signal which is not the signal we are waiting for. 2946654de8547d2e420c20e21980669b807aa80710ephilippe If we have not (yet) changed the registers of the inferior 2956654de8547d2e420c20e21980669b807aa80710ephilippe or we have (already) reset them, we can transmit the signal. 2966654de8547d2e420c20e21980669b807aa80710ephilippe 2976654de8547d2e420c20e21980669b807aa80710ephilippe If we have already set the registers of the inferior, we cannot 2986654de8547d2e420c20e21980669b807aa80710ephilippe transmit the signal, as this signal would arrive when the 2996654de8547d2e420c20e21980669b807aa80710ephilippe gdbserver code runs. And valgrind only expects signals to 3006654de8547d2e420c20e21980669b807aa80710ephilippe arrive in a small code portion around 3016654de8547d2e420c20e21980669b807aa80710ephilippe client syscall logic, where signal are unmasked (see e.g. 3026654de8547d2e420c20e21980669b807aa80710ephilippe m_syswrap/syscall-x86-linux.S ML_(do_syscall_for_client_WRK). 3036654de8547d2e420c20e21980669b807aa80710ephilippe 3046654de8547d2e420c20e21980669b807aa80710ephilippe As ptrace is forcing a call to gdbserver by jumping 3056654de8547d2e420c20e21980669b807aa80710ephilippe 'out of this region', signals are not masked, but 3066654de8547d2e420c20e21980669b807aa80710ephilippe will arrive outside of the allowed/expected code region. 3076654de8547d2e420c20e21980669b807aa80710ephilippe So, if we have changed the registers of the inferior, we 3086654de8547d2e420c20e21980669b807aa80710ephilippe rather queue the signal to transmit them when detaching, 3096654de8547d2e420c20e21980669b807aa80710ephilippe after having restored the registers to the initial values. */ 3106654de8547d2e420c20e21980669b807aa80710ephilippe if (pid_of_save_regs) { 3116654de8547d2e420c20e21980669b807aa80710ephilippe siginfo_t *newsiginfo; 3126654de8547d2e420c20e21980669b807aa80710ephilippe 3136654de8547d2e420c20e21980669b807aa80710ephilippe // realloc a bigger queue, and store new signal at the end. 3146654de8547d2e420c20e21980669b807aa80710ephilippe // This is not very efficient but we assume not many sigs are queued. 3156654de8547d2e420c20e21980669b807aa80710ephilippe signal_queue_sz++; 3166654de8547d2e420c20e21980669b807aa80710ephilippe signal_queue = vrealloc(signal_queue, sizeof(siginfo_t) * signal_queue_sz); 3176654de8547d2e420c20e21980669b807aa80710ephilippe newsiginfo = signal_queue + (signal_queue_sz - 1); 3186654de8547d2e420c20e21980669b807aa80710ephilippe 3196654de8547d2e420c20e21980669b807aa80710ephilippe res = ptrace (PTRACE_GETSIGINFO, pid, NULL, newsiginfo); 3206654de8547d2e420c20e21980669b807aa80710ephilippe if (res != 0) { 3216654de8547d2e420c20e21980669b807aa80710ephilippe ERROR(errno, "PTRACE_GETSIGINFO failed: signal lost !!!!\n"); 3226654de8547d2e420c20e21980669b807aa80710ephilippe signal_queue_sz--; 3236654de8547d2e420c20e21980669b807aa80710ephilippe } else 3246654de8547d2e420c20e21980669b807aa80710ephilippe DEBUG(1, "waitstopped PTRACE_CONT, queuing signal %d" 3256654de8547d2e420c20e21980669b807aa80710ephilippe " si_signo %d si_pid %d\n", 3266654de8547d2e420c20e21980669b807aa80710ephilippe signal_received, newsiginfo->si_signo, newsiginfo->si_pid); 3276654de8547d2e420c20e21980669b807aa80710ephilippe res = ptrace (PTRACE_CONT, pid, NULL, 0); 3286654de8547d2e420c20e21980669b807aa80710ephilippe } else { 3296654de8547d2e420c20e21980669b807aa80710ephilippe DEBUG(1, "waitstopped PTRACE_CONT with signal %d\n", signal_received); 3306654de8547d2e420c20e21980669b807aa80710ephilippe res = ptrace (PTRACE_CONT, pid, NULL, signal_received); 3316654de8547d2e420c20e21980669b807aa80710ephilippe } 3323c761f0f0344757ac243c65511392fb41d1c841aphilippe if (res != 0) { 3333c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(errno, "waitstopped PTRACE_CONT\n"); 3343c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 3353c761f0f0344757ac243c65511392fb41d1c841aphilippe } 3363c761f0f0344757ac243c65511392fb41d1c841aphilippe } 3373c761f0f0344757ac243c65511392fb41d1c841aphilippe 3383c761f0f0344757ac243c65511392fb41d1c841aphilippe return True; 3393c761f0f0344757ac243c65511392fb41d1c841aphilippe} 3403c761f0f0344757ac243c65511392fb41d1c841aphilippe 3413c761f0f0344757ac243c65511392fb41d1c841aphilippe/* Stops the given pid, wait for the process to be stopped. 3423c761f0f0344757ac243c65511392fb41d1c841aphilippe Returns True if succesful, False otherwise. 3433c761f0f0344757ac243c65511392fb41d1c841aphilippe msg is used in tracing and error reporting. */ 3443c761f0f0344757ac243c65511392fb41d1c841aphilippestatic 3453c761f0f0344757ac243c65511392fb41d1c841aphilippeBool stop (pid_t pid, const char *msg) 3463c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 3473c761f0f0344757ac243c65511392fb41d1c841aphilippe long res; 3483c761f0f0344757ac243c65511392fb41d1c841aphilippe 3493c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "%s SIGSTOP pid %d\n", msg, pid); 3503c761f0f0344757ac243c65511392fb41d1c841aphilippe res = kill (pid, SIGSTOP); 3513c761f0f0344757ac243c65511392fb41d1c841aphilippe if (res != 0) { 3523c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(errno, "%s SIGSTOP pid %d %ld\n", msg, pid, res); 3533c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 3543c761f0f0344757ac243c65511392fb41d1c841aphilippe } 3553c761f0f0344757ac243c65511392fb41d1c841aphilippe 3563c761f0f0344757ac243c65511392fb41d1c841aphilippe return waitstopped (pid, SIGSTOP, msg); 3573c761f0f0344757ac243c65511392fb41d1c841aphilippe 3583c761f0f0344757ac243c65511392fb41d1c841aphilippe} 3593c761f0f0344757ac243c65511392fb41d1c841aphilippe 3603c761f0f0344757ac243c65511392fb41d1c841aphilippe/* Attaches to given pid, wait for the process to be stopped. 3613c761f0f0344757ac243c65511392fb41d1c841aphilippe Returns True if succesful, False otherwise. 3623c761f0f0344757ac243c65511392fb41d1c841aphilippe msg is used in tracing and error reporting. */ 3633c761f0f0344757ac243c65511392fb41d1c841aphilippestatic 3643c761f0f0344757ac243c65511392fb41d1c841aphilippeBool attach (pid_t pid, const char *msg) 3653c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 3663c761f0f0344757ac243c65511392fb41d1c841aphilippe long res; 3673c761f0f0344757ac243c65511392fb41d1c841aphilippe static Bool output_error = True; 3683c761f0f0344757ac243c65511392fb41d1c841aphilippe static Bool initial_attach = True; 3693c761f0f0344757ac243c65511392fb41d1c841aphilippe // For a ptrace_scope protected system, we do not want to output 3703c761f0f0344757ac243c65511392fb41d1c841aphilippe // repetitively attach error. We will output once an error 3713c761f0f0344757ac243c65511392fb41d1c841aphilippe // for the initial_attach. Once the 1st attach has succeeded, we 3723c761f0f0344757ac243c65511392fb41d1c841aphilippe // again show all errors. 3733c761f0f0344757ac243c65511392fb41d1c841aphilippe 3743c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "%s PTRACE_ATTACH pid %d\n", msg, pid); 3753c761f0f0344757ac243c65511392fb41d1c841aphilippe res = ptrace (PTRACE_ATTACH, pid, NULL, NULL); 3763c761f0f0344757ac243c65511392fb41d1c841aphilippe if (res != 0) { 3773c761f0f0344757ac243c65511392fb41d1c841aphilippe if (output_error || debuglevel > 0) { 3783c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(errno, "%s PTRACE_ATTACH pid %d %ld\n", msg, pid, res); 3793c761f0f0344757ac243c65511392fb41d1c841aphilippe if (initial_attach) 3803c761f0f0344757ac243c65511392fb41d1c841aphilippe output_error = False; 3813c761f0f0344757ac243c65511392fb41d1c841aphilippe } 3823c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 3833c761f0f0344757ac243c65511392fb41d1c841aphilippe } 3843c761f0f0344757ac243c65511392fb41d1c841aphilippe 3853c761f0f0344757ac243c65511392fb41d1c841aphilippe initial_attach = False; 3863c761f0f0344757ac243c65511392fb41d1c841aphilippe output_error = True; 3873c761f0f0344757ac243c65511392fb41d1c841aphilippe return waitstopped(pid, SIGSTOP, msg); 3883c761f0f0344757ac243c65511392fb41d1c841aphilippe} 3893c761f0f0344757ac243c65511392fb41d1c841aphilippe 3903c761f0f0344757ac243c65511392fb41d1c841aphilippe/* once we are attached to the pid, get the list of threads and stop 3913c761f0f0344757ac243c65511392fb41d1c841aphilippe them all. 3923c761f0f0344757ac243c65511392fb41d1c841aphilippe Returns True if all threads properly suspended, False otherwise. */ 3933c761f0f0344757ac243c65511392fb41d1c841aphilippestatic 3943c761f0f0344757ac243c65511392fb41d1c841aphilippeBool acquire_and_suspend_threads (pid_t pid) 3953c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 3963c761f0f0344757ac243c65511392fb41d1c841aphilippe int i; 3973c761f0f0344757ac243c65511392fb41d1c841aphilippe int rw; 3983c761f0f0344757ac243c65511392fb41d1c841aphilippe Bool pid_found = False; 3993c761f0f0344757ac243c65511392fb41d1c841aphilippe Addr vgt; 4003c761f0f0344757ac243c65511392fb41d1c841aphilippe int sz_tst; 4013c761f0f0344757ac243c65511392fb41d1c841aphilippe int off_status; 4023c761f0f0344757ac243c65511392fb41d1c841aphilippe int off_lwpid; 4033c761f0f0344757ac243c65511392fb41d1c841aphilippe int nr_live_threads = 0; 4043c761f0f0344757ac243c65511392fb41d1c841aphilippe 4053c761f0f0344757ac243c65511392fb41d1c841aphilippe if (shared32 != NULL) { 4063c761f0f0344757ac243c65511392fb41d1c841aphilippe vgt = shared32->threads; 4073c761f0f0344757ac243c65511392fb41d1c841aphilippe sz_tst = shared32->sizeof_ThreadState; 4083c761f0f0344757ac243c65511392fb41d1c841aphilippe off_status = shared32->offset_status; 4093c761f0f0344757ac243c65511392fb41d1c841aphilippe off_lwpid = shared32->offset_lwpid; 4103c761f0f0344757ac243c65511392fb41d1c841aphilippe } 4113c761f0f0344757ac243c65511392fb41d1c841aphilippe else if (shared64 != NULL) { 4123c761f0f0344757ac243c65511392fb41d1c841aphilippe vgt = shared64->threads; 4133c761f0f0344757ac243c65511392fb41d1c841aphilippe sz_tst = shared64->sizeof_ThreadState; 4143c761f0f0344757ac243c65511392fb41d1c841aphilippe off_status = shared64->offset_status; 4153c761f0f0344757ac243c65511392fb41d1c841aphilippe off_lwpid = shared64->offset_lwpid; 4163c761f0f0344757ac243c65511392fb41d1c841aphilippe } else { 4173c761f0f0344757ac243c65511392fb41d1c841aphilippe assert (0); 4183c761f0f0344757ac243c65511392fb41d1c841aphilippe } 4193c761f0f0344757ac243c65511392fb41d1c841aphilippe 4203c761f0f0344757ac243c65511392fb41d1c841aphilippe /* note: the entry 0 is unused */ 4213c761f0f0344757ac243c65511392fb41d1c841aphilippe for (i = 1; i < VG_N_THREADS; i++) { 4223c761f0f0344757ac243c65511392fb41d1c841aphilippe vgt += sz_tst; 4233c761f0f0344757ac243c65511392fb41d1c841aphilippe rw = ptrace_read_memory(pid, vgt+off_status, 4243c761f0f0344757ac243c65511392fb41d1c841aphilippe &(vgdb_threads[i].status), 4253c761f0f0344757ac243c65511392fb41d1c841aphilippe sizeof(ThreadStatus)); 4263c761f0f0344757ac243c65511392fb41d1c841aphilippe if (rw != 0) { 4273c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(rw, "status ptrace_read_memory\n"); 4283c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 4293c761f0f0344757ac243c65511392fb41d1c841aphilippe } 4303c761f0f0344757ac243c65511392fb41d1c841aphilippe 4313c761f0f0344757ac243c65511392fb41d1c841aphilippe rw = ptrace_read_memory(pid, vgt+off_lwpid, 4323c761f0f0344757ac243c65511392fb41d1c841aphilippe &(vgdb_threads[i].lwpid), 4333c761f0f0344757ac243c65511392fb41d1c841aphilippe sizeof(Int)); 4343c761f0f0344757ac243c65511392fb41d1c841aphilippe if (rw != 0) { 4353c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(rw, "lwpid ptrace_read_memory\n"); 4363c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 4373c761f0f0344757ac243c65511392fb41d1c841aphilippe } 4383c761f0f0344757ac243c65511392fb41d1c841aphilippe 4393c761f0f0344757ac243c65511392fb41d1c841aphilippe if (vgdb_threads[i].status != VgTs_Empty) { 4403c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "found tid %d status %s lwpid %d\n", 4413c761f0f0344757ac243c65511392fb41d1c841aphilippe i, name_of_ThreadStatus(vgdb_threads[i].status), 4423c761f0f0344757ac243c65511392fb41d1c841aphilippe vgdb_threads[i].lwpid); 4433c761f0f0344757ac243c65511392fb41d1c841aphilippe nr_live_threads++; 4443c761f0f0344757ac243c65511392fb41d1c841aphilippe if (vgdb_threads[i].lwpid <= 1) { 4453c761f0f0344757ac243c65511392fb41d1c841aphilippe if (vgdb_threads[i].lwpid == 0 4463c761f0f0344757ac243c65511392fb41d1c841aphilippe && vgdb_threads[i].status == VgTs_Init) { 4473c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "not set lwpid tid %d status %s lwpid %d\n", 4483c761f0f0344757ac243c65511392fb41d1c841aphilippe i, name_of_ThreadStatus(vgdb_threads[i].status), 4493c761f0f0344757ac243c65511392fb41d1c841aphilippe vgdb_threads[i].lwpid); 4503c761f0f0344757ac243c65511392fb41d1c841aphilippe } else { 4513c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(1, "unexpected lwpid tid %d status %s lwpid %d\n", 4523c761f0f0344757ac243c65511392fb41d1c841aphilippe i, name_of_ThreadStatus(vgdb_threads[i].status), 4533c761f0f0344757ac243c65511392fb41d1c841aphilippe vgdb_threads[i].lwpid); 4543c761f0f0344757ac243c65511392fb41d1c841aphilippe } 4553c761f0f0344757ac243c65511392fb41d1c841aphilippe /* in case we have a VtTs_Init thread with lwpid not yet set, 4563c761f0f0344757ac243c65511392fb41d1c841aphilippe we try again later. */ 4573c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 4583c761f0f0344757ac243c65511392fb41d1c841aphilippe } 4593c761f0f0344757ac243c65511392fb41d1c841aphilippe if (vgdb_threads[i].lwpid == pid) { 4603c761f0f0344757ac243c65511392fb41d1c841aphilippe assert (!pid_found); 4613c761f0f0344757ac243c65511392fb41d1c841aphilippe assert (i == 1); 4623c761f0f0344757ac243c65511392fb41d1c841aphilippe pid_found = True; 4633c761f0f0344757ac243c65511392fb41d1c841aphilippe } else { 4643c761f0f0344757ac243c65511392fb41d1c841aphilippe if (!attach(vgdb_threads[i].lwpid, "attach_thread")) { 4653c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(0, "ERROR attach pid %d tid %d\n", 4663c761f0f0344757ac243c65511392fb41d1c841aphilippe vgdb_threads[i].lwpid, i); 4673c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 4683c761f0f0344757ac243c65511392fb41d1c841aphilippe } 4693c761f0f0344757ac243c65511392fb41d1c841aphilippe } 4703c761f0f0344757ac243c65511392fb41d1c841aphilippe } 4713c761f0f0344757ac243c65511392fb41d1c841aphilippe } 4723c761f0f0344757ac243c65511392fb41d1c841aphilippe /* If we found no thread, it means the process is stopping, and 4733c761f0f0344757ac243c65511392fb41d1c841aphilippe we better do not force anything to happen during that. */ 4743c761f0f0344757ac243c65511392fb41d1c841aphilippe if (nr_live_threads > 0) 4753c761f0f0344757ac243c65511392fb41d1c841aphilippe return True; 4763c761f0f0344757ac243c65511392fb41d1c841aphilippe else 4773c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 4783c761f0f0344757ac243c65511392fb41d1c841aphilippe} 4793c761f0f0344757ac243c65511392fb41d1c841aphilippe 4803c761f0f0344757ac243c65511392fb41d1c841aphilippestatic 4813c761f0f0344757ac243c65511392fb41d1c841aphilippevoid detach_from_all_threads (pid_t pid) 4823c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 4833c761f0f0344757ac243c65511392fb41d1c841aphilippe int i; 4843c761f0f0344757ac243c65511392fb41d1c841aphilippe long res; 4853c761f0f0344757ac243c65511392fb41d1c841aphilippe Bool pid_found = False; 4863c761f0f0344757ac243c65511392fb41d1c841aphilippe 4873c761f0f0344757ac243c65511392fb41d1c841aphilippe /* detach from all the threads */ 4883c761f0f0344757ac243c65511392fb41d1c841aphilippe for (i = 1; i < VG_N_THREADS; i++) { 4893c761f0f0344757ac243c65511392fb41d1c841aphilippe if (vgdb_threads[i].status != VgTs_Empty) { 4903c761f0f0344757ac243c65511392fb41d1c841aphilippe if (vgdb_threads[i].status == VgTs_Init 4913c761f0f0344757ac243c65511392fb41d1c841aphilippe && vgdb_threads[i].lwpid == 0) { 4923c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "skipping PTRACE_DETACH pid %d tid %d status %s\n", 4933c761f0f0344757ac243c65511392fb41d1c841aphilippe vgdb_threads[i].lwpid, i, 4943c761f0f0344757ac243c65511392fb41d1c841aphilippe name_of_ThreadStatus (vgdb_threads[i].status)); 4953c761f0f0344757ac243c65511392fb41d1c841aphilippe } else { 4963c761f0f0344757ac243c65511392fb41d1c841aphilippe if (vgdb_threads[i].lwpid == pid) { 4973c761f0f0344757ac243c65511392fb41d1c841aphilippe assert (!pid_found); 4983c761f0f0344757ac243c65511392fb41d1c841aphilippe pid_found = True; 4993c761f0f0344757ac243c65511392fb41d1c841aphilippe } 5003c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "PTRACE_DETACH pid %d tid %d status %s\n", 5013c761f0f0344757ac243c65511392fb41d1c841aphilippe vgdb_threads[i].lwpid, i, 5023c761f0f0344757ac243c65511392fb41d1c841aphilippe name_of_ThreadStatus (vgdb_threads[i].status)); 5033c761f0f0344757ac243c65511392fb41d1c841aphilippe res = ptrace (PTRACE_DETACH, vgdb_threads[i].lwpid, NULL, NULL); 5043c761f0f0344757ac243c65511392fb41d1c841aphilippe if (res != 0) { 5053c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(errno, "PTRACE_DETACH pid %d tid %d status %s res %ld\n", 5063c761f0f0344757ac243c65511392fb41d1c841aphilippe vgdb_threads[i].lwpid, i, 5073c761f0f0344757ac243c65511392fb41d1c841aphilippe name_of_ThreadStatus (vgdb_threads[i].status), 5083c761f0f0344757ac243c65511392fb41d1c841aphilippe res); 5093c761f0f0344757ac243c65511392fb41d1c841aphilippe } 5103c761f0f0344757ac243c65511392fb41d1c841aphilippe } 5113c761f0f0344757ac243c65511392fb41d1c841aphilippe } 5123c761f0f0344757ac243c65511392fb41d1c841aphilippe } 5133c761f0f0344757ac243c65511392fb41d1c841aphilippe 5143c761f0f0344757ac243c65511392fb41d1c841aphilippe if (!pid_found && pid) { 5153c761f0f0344757ac243c65511392fb41d1c841aphilippe /* No threads are live. Process is busy stopping. 5163c761f0f0344757ac243c65511392fb41d1c841aphilippe We need to detach from pid explicitely. */ 5173c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "no thread live => PTRACE_DETACH pid %d\n", pid); 5183c761f0f0344757ac243c65511392fb41d1c841aphilippe res = ptrace (PTRACE_DETACH, pid, NULL, NULL); 5193c761f0f0344757ac243c65511392fb41d1c841aphilippe if (res != 0) 5203c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(errno, "PTRACE_DETACH pid %d res %ld\n", pid, res); 5213c761f0f0344757ac243c65511392fb41d1c841aphilippe } 5223c761f0f0344757ac243c65511392fb41d1c841aphilippe} 5233c761f0f0344757ac243c65511392fb41d1c841aphilippe 524c07369bc8be6f6a26adfdbe391be7fe64a211829philippe# if defined(VGA_arm64) 5252a429f5d70a41ab1673c9f2ec220e8a10d8c90d5mjw/* arm64 is extra special, old glibc defined kernel user_pt_regs, but 5262a429f5d70a41ab1673c9f2ec220e8a10d8c90d5mjw newer glibc instead define user_regs_struct. */ 5272a429f5d70a41ab1673c9f2ec220e8a10d8c90d5mjw# ifdef HAVE_SYS_USER_REGS 5282a429f5d70a41ab1673c9f2ec220e8a10d8c90d5mjwstatic struct user_regs_struct user_save; 5292a429f5d70a41ab1673c9f2ec220e8a10d8c90d5mjw# else 530c07369bc8be6f6a26adfdbe391be7fe64a211829philippestatic struct user_pt_regs user_save; 5312a429f5d70a41ab1673c9f2ec220e8a10d8c90d5mjw# endif 532c07369bc8be6f6a26adfdbe391be7fe64a211829philippe# else 5333c761f0f0344757ac243c65511392fb41d1c841aphilippestatic struct user user_save; 534c07369bc8be6f6a26adfdbe391be7fe64a211829philippe# endif 5353c761f0f0344757ac243c65511392fb41d1c841aphilippe// The below indicates if ptrace_getregs (and ptrace_setregs) can be used. 5363c761f0f0344757ac243c65511392fb41d1c841aphilippe// Note that some linux versions are defining PTRACE_GETREGS but using 5373c761f0f0344757ac243c65511392fb41d1c841aphilippe// it gives back EIO. 5383c761f0f0344757ac243c65511392fb41d1c841aphilippe// has_working_ptrace_getregs can take the following values: 5393c761f0f0344757ac243c65511392fb41d1c841aphilippe// -1 : PTRACE_GETREGS is defined 5403c761f0f0344757ac243c65511392fb41d1c841aphilippe// runtime check not yet done. 5413c761f0f0344757ac243c65511392fb41d1c841aphilippe// 0 : PTRACE_GETREGS runtime check has failed. 5423c761f0f0344757ac243c65511392fb41d1c841aphilippe// 1 : PTRACE_GETREGS defined and runtime check ok. 5433c761f0f0344757ac243c65511392fb41d1c841aphilippe#ifdef HAVE_PTRACE_GETREGS 5443c761f0f0344757ac243c65511392fb41d1c841aphilippestatic int has_working_ptrace_getregs = -1; 5453c761f0f0344757ac243c65511392fb41d1c841aphilippe#endif 546c07369bc8be6f6a26adfdbe391be7fe64a211829philippe// Similar but for PTRACE_GETREGSET 547c07369bc8be6f6a26adfdbe391be7fe64a211829philippe#ifdef HAVE_PTRACE_GETREGSET 548c07369bc8be6f6a26adfdbe391be7fe64a211829philippestatic int has_working_ptrace_getregset = -1; 549c07369bc8be6f6a26adfdbe391be7fe64a211829philippe#endif 5503c761f0f0344757ac243c65511392fb41d1c841aphilippe 5513c761f0f0344757ac243c65511392fb41d1c841aphilippe/* Get the registers from pid into regs. 5523c761f0f0344757ac243c65511392fb41d1c841aphilippe regs_bsz value gives the length of *regs. 5533c761f0f0344757ac243c65511392fb41d1c841aphilippe Returns True if all ok, otherwise False. */ 5543c761f0f0344757ac243c65511392fb41d1c841aphilippestatic 5553c761f0f0344757ac243c65511392fb41d1c841aphilippeBool getregs (pid_t pid, void *regs, long regs_bsz) 5563c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 5573c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "getregs regs_bsz %ld\n", regs_bsz); 558c07369bc8be6f6a26adfdbe391be7fe64a211829philippe# ifdef HAVE_PTRACE_GETREGSET 559c07369bc8be6f6a26adfdbe391be7fe64a211829philippe# ifndef USE_PTRACE_GETREGSET 560c07369bc8be6f6a26adfdbe391be7fe64a211829philippe if (has_working_ptrace_getregset) 561c07369bc8be6f6a26adfdbe391be7fe64a211829philippe DEBUG(1, "PTRACE_GETREGSET defined, not used (yet?) by vgdb\n"); 562c07369bc8be6f6a26adfdbe391be7fe64a211829philippe has_working_ptrace_getregset = 0; 563c07369bc8be6f6a26adfdbe391be7fe64a211829philippe# endif 564c07369bc8be6f6a26adfdbe391be7fe64a211829philippe if (has_working_ptrace_getregset) { 565c07369bc8be6f6a26adfdbe391be7fe64a211829philippe // Platforms having GETREGSET 566c07369bc8be6f6a26adfdbe391be7fe64a211829philippe long res; 567c07369bc8be6f6a26adfdbe391be7fe64a211829philippe elf_gregset_t elf_regs; 568c07369bc8be6f6a26adfdbe391be7fe64a211829philippe struct iovec iovec; 569c07369bc8be6f6a26adfdbe391be7fe64a211829philippe 570c07369bc8be6f6a26adfdbe391be7fe64a211829philippe DEBUG(1, "getregs PTRACE_GETREGSET sizeof(elf_regs) %d\n", sizeof(elf_regs)); 571c07369bc8be6f6a26adfdbe391be7fe64a211829philippe iovec.iov_base = regs; 572c07369bc8be6f6a26adfdbe391be7fe64a211829philippe iovec.iov_len = sizeof(elf_regs); 573c07369bc8be6f6a26adfdbe391be7fe64a211829philippe 574c07369bc8be6f6a26adfdbe391be7fe64a211829philippe res = ptrace (PTRACE_GETREGSET, pid, NT_PRSTATUS, &iovec); 575c07369bc8be6f6a26adfdbe391be7fe64a211829philippe if (res == 0) { 576c07369bc8be6f6a26adfdbe391be7fe64a211829philippe if (has_working_ptrace_getregset == -1) { 577c07369bc8be6f6a26adfdbe391be7fe64a211829philippe // First call to PTRACE_GETREGSET succesful => 578c07369bc8be6f6a26adfdbe391be7fe64a211829philippe has_working_ptrace_getregset = 1; 579c07369bc8be6f6a26adfdbe391be7fe64a211829philippe DEBUG(1, "detected a working PTRACE_GETREGSET\n"); 580c07369bc8be6f6a26adfdbe391be7fe64a211829philippe } 581c07369bc8be6f6a26adfdbe391be7fe64a211829philippe assert (has_working_ptrace_getregset == 1); 582c07369bc8be6f6a26adfdbe391be7fe64a211829philippe return True; 583c07369bc8be6f6a26adfdbe391be7fe64a211829philippe } 584c07369bc8be6f6a26adfdbe391be7fe64a211829philippe else if (has_working_ptrace_getregset == 1) { 585c07369bc8be6f6a26adfdbe391be7fe64a211829philippe // We had a working call, but now it fails. 586c07369bc8be6f6a26adfdbe391be7fe64a211829philippe // This is unexpected. 587c07369bc8be6f6a26adfdbe391be7fe64a211829philippe ERROR(errno, "PTRACE_GETREGSET %ld\n", res); 588c07369bc8be6f6a26adfdbe391be7fe64a211829philippe return False; 589c07369bc8be6f6a26adfdbe391be7fe64a211829philippe } else { 590c07369bc8be6f6a26adfdbe391be7fe64a211829philippe // Check this is the first call: 591c07369bc8be6f6a26adfdbe391be7fe64a211829philippe assert (has_working_ptrace_getregset == -1); 592c07369bc8be6f6a26adfdbe391be7fe64a211829philippe if (errno == EIO) { 593c07369bc8be6f6a26adfdbe391be7fe64a211829philippe DEBUG(1, "detected a broken PTRACE_GETREGSET with EIO\n"); 594c07369bc8be6f6a26adfdbe391be7fe64a211829philippe has_working_ptrace_getregset = 0; 595c07369bc8be6f6a26adfdbe391be7fe64a211829philippe // Fall over to the PTRACE_GETREGS or PTRACE_PEEKUSER case. 596c07369bc8be6f6a26adfdbe391be7fe64a211829philippe } else { 597c07369bc8be6f6a26adfdbe391be7fe64a211829philippe ERROR(errno, "broken PTRACE_GETREGSET unexpected errno %ld\n", res); 598c07369bc8be6f6a26adfdbe391be7fe64a211829philippe return False; 599c07369bc8be6f6a26adfdbe391be7fe64a211829philippe } 600c07369bc8be6f6a26adfdbe391be7fe64a211829philippe } 601c07369bc8be6f6a26adfdbe391be7fe64a211829philippe } 602c07369bc8be6f6a26adfdbe391be7fe64a211829philippe# endif 603c07369bc8be6f6a26adfdbe391be7fe64a211829philippe 6043c761f0f0344757ac243c65511392fb41d1c841aphilippe# ifdef HAVE_PTRACE_GETREGS 6053c761f0f0344757ac243c65511392fb41d1c841aphilippe if (has_working_ptrace_getregs) { 6063c761f0f0344757ac243c65511392fb41d1c841aphilippe // Platforms having GETREGS 6073c761f0f0344757ac243c65511392fb41d1c841aphilippe long res; 6083c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "getregs PTRACE_GETREGS\n"); 6093c761f0f0344757ac243c65511392fb41d1c841aphilippe res = ptrace (PTRACE_GETREGS, pid, NULL, regs); 6103c761f0f0344757ac243c65511392fb41d1c841aphilippe if (res == 0) { 6113c761f0f0344757ac243c65511392fb41d1c841aphilippe if (has_working_ptrace_getregs == -1) { 6123c761f0f0344757ac243c65511392fb41d1c841aphilippe // First call to PTRACE_GETREGS succesful => 6133c761f0f0344757ac243c65511392fb41d1c841aphilippe has_working_ptrace_getregs = 1; 6143c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "detected a working PTRACE_GETREGS\n"); 6153c761f0f0344757ac243c65511392fb41d1c841aphilippe } 6163c761f0f0344757ac243c65511392fb41d1c841aphilippe assert (has_working_ptrace_getregs == 1); 6173c761f0f0344757ac243c65511392fb41d1c841aphilippe return True; 6183c761f0f0344757ac243c65511392fb41d1c841aphilippe } 6193c761f0f0344757ac243c65511392fb41d1c841aphilippe else if (has_working_ptrace_getregs == 1) { 6203c761f0f0344757ac243c65511392fb41d1c841aphilippe // We had a working call, but now it fails. 6213c761f0f0344757ac243c65511392fb41d1c841aphilippe // This is unexpected. 6223c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(errno, "PTRACE_GETREGS %ld\n", res); 6233c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 6243c761f0f0344757ac243c65511392fb41d1c841aphilippe } else { 6253c761f0f0344757ac243c65511392fb41d1c841aphilippe // Check this is the first call: 6263c761f0f0344757ac243c65511392fb41d1c841aphilippe assert (has_working_ptrace_getregs == -1); 6273c761f0f0344757ac243c65511392fb41d1c841aphilippe if (errno == EIO) { 6283c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "detected a broken PTRACE_GETREGS with EIO\n"); 6293c761f0f0344757ac243c65511392fb41d1c841aphilippe has_working_ptrace_getregs = 0; 6303c761f0f0344757ac243c65511392fb41d1c841aphilippe // Fall over to the PTRACE_PEEKUSER case. 6313c761f0f0344757ac243c65511392fb41d1c841aphilippe } else { 6323c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(errno, "broken PTRACE_GETREGS unexpected errno %ld\n", res); 6333c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 6343c761f0f0344757ac243c65511392fb41d1c841aphilippe } 6353c761f0f0344757ac243c65511392fb41d1c841aphilippe } 6363c761f0f0344757ac243c65511392fb41d1c841aphilippe } 6373c761f0f0344757ac243c65511392fb41d1c841aphilippe# endif 6383c761f0f0344757ac243c65511392fb41d1c841aphilippe 6393c761f0f0344757ac243c65511392fb41d1c841aphilippe // We assume PTRACE_PEEKUSER is defined everywhere. 6403c761f0f0344757ac243c65511392fb41d1c841aphilippe { 6413c761f0f0344757ac243c65511392fb41d1c841aphilippe# ifdef PT_ENDREGS 6423c761f0f0344757ac243c65511392fb41d1c841aphilippe long peek_bsz = PT_ENDREGS; 6433c761f0f0344757ac243c65511392fb41d1c841aphilippe assert (peek_bsz <= regs_bsz); 6443c761f0f0344757ac243c65511392fb41d1c841aphilippe# else 6453c761f0f0344757ac243c65511392fb41d1c841aphilippe long peek_bsz = regs_bsz-1; 6463c761f0f0344757ac243c65511392fb41d1c841aphilippe# endif 6473c761f0f0344757ac243c65511392fb41d1c841aphilippe char *pregs = (char *) regs; 6483c761f0f0344757ac243c65511392fb41d1c841aphilippe long offset; 6493c761f0f0344757ac243c65511392fb41d1c841aphilippe errno = 0; 6503c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "getregs PTRACE_PEEKUSER(s) peek_bsz %ld\n", peek_bsz); 6513c761f0f0344757ac243c65511392fb41d1c841aphilippe for (offset = 0; offset < peek_bsz; offset = offset + sizeof(long)) { 6523c761f0f0344757ac243c65511392fb41d1c841aphilippe *(long *)(pregs+offset) = ptrace(PTRACE_PEEKUSER, pid, offset, NULL); 6533c761f0f0344757ac243c65511392fb41d1c841aphilippe if (errno != 0) { 6543c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(errno, "PTRACE_PEEKUSER offset %ld\n", offset); 6553c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 6563c761f0f0344757ac243c65511392fb41d1c841aphilippe } 6573c761f0f0344757ac243c65511392fb41d1c841aphilippe } 6583c761f0f0344757ac243c65511392fb41d1c841aphilippe return True; 6593c761f0f0344757ac243c65511392fb41d1c841aphilippe } 6603c761f0f0344757ac243c65511392fb41d1c841aphilippe 661c07369bc8be6f6a26adfdbe391be7fe64a211829philippe // If neither of PTRACE_GETREGSET PTRACE_GETREGS PTRACE_PEEKUSER have 662c07369bc8be6f6a26adfdbe391be7fe64a211829philippe // returned, then we are in serious trouble. 6633c761f0f0344757ac243c65511392fb41d1c841aphilippe assert (0); 6643c761f0f0344757ac243c65511392fb41d1c841aphilippe} 6653c761f0f0344757ac243c65511392fb41d1c841aphilippe 6663c761f0f0344757ac243c65511392fb41d1c841aphilippe/* Set the registers of pid to regs. 6673c761f0f0344757ac243c65511392fb41d1c841aphilippe regs_bsz value gives the length of *regs. 6683c761f0f0344757ac243c65511392fb41d1c841aphilippe Returns True if all ok, otherwise False. */ 6693c761f0f0344757ac243c65511392fb41d1c841aphilippestatic 6703c761f0f0344757ac243c65511392fb41d1c841aphilippeBool setregs (pid_t pid, void *regs, long regs_bsz) 6713c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 6723c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "setregs regs_bsz %ld\n", regs_bsz); 673c07369bc8be6f6a26adfdbe391be7fe64a211829philippe 674c07369bc8be6f6a26adfdbe391be7fe64a211829philippe// Note : the below is checking for GETREGSET, not SETREGSET 675c07369bc8be6f6a26adfdbe391be7fe64a211829philippe// as if one is defined and working, the other one should also work. 676c07369bc8be6f6a26adfdbe391be7fe64a211829philippe# ifdef HAVE_PTRACE_GETREGSET 677c07369bc8be6f6a26adfdbe391be7fe64a211829philippe if (has_working_ptrace_getregset) { 678c07369bc8be6f6a26adfdbe391be7fe64a211829philippe // Platforms having SETREGSET 679c07369bc8be6f6a26adfdbe391be7fe64a211829philippe long res; 680c07369bc8be6f6a26adfdbe391be7fe64a211829philippe elf_gregset_t elf_regs; 681c07369bc8be6f6a26adfdbe391be7fe64a211829philippe struct iovec iovec; 682c07369bc8be6f6a26adfdbe391be7fe64a211829philippe 683c07369bc8be6f6a26adfdbe391be7fe64a211829philippe // setregset can never be called before getregset has done a runtime check. 684c07369bc8be6f6a26adfdbe391be7fe64a211829philippe assert (has_working_ptrace_getregset == 1); 685c07369bc8be6f6a26adfdbe391be7fe64a211829philippe DEBUG(1, "setregs PTRACE_SETREGSET sizeof(elf_regs) %d\n", sizeof(elf_regs)); 686c07369bc8be6f6a26adfdbe391be7fe64a211829philippe iovec.iov_base = regs; 687c07369bc8be6f6a26adfdbe391be7fe64a211829philippe iovec.iov_len = sizeof(elf_regs); 688c07369bc8be6f6a26adfdbe391be7fe64a211829philippe res = ptrace (PTRACE_SETREGSET, pid, NT_PRSTATUS, &iovec); 689c07369bc8be6f6a26adfdbe391be7fe64a211829philippe if (res != 0) { 690c07369bc8be6f6a26adfdbe391be7fe64a211829philippe ERROR(errno, "PTRACE_SETREGSET %ld\n", res); 691c07369bc8be6f6a26adfdbe391be7fe64a211829philippe return False; 692c07369bc8be6f6a26adfdbe391be7fe64a211829philippe } 693c07369bc8be6f6a26adfdbe391be7fe64a211829philippe return True; 694c07369bc8be6f6a26adfdbe391be7fe64a211829philippe } 695c07369bc8be6f6a26adfdbe391be7fe64a211829philippe# endif 696c07369bc8be6f6a26adfdbe391be7fe64a211829philippe 6973c761f0f0344757ac243c65511392fb41d1c841aphilippe// Note : the below is checking for GETREGS, not SETREGS 6983c761f0f0344757ac243c65511392fb41d1c841aphilippe// as if one is defined and working, the other one should also work. 6993c761f0f0344757ac243c65511392fb41d1c841aphilippe# ifdef HAVE_PTRACE_GETREGS 7003c761f0f0344757ac243c65511392fb41d1c841aphilippe if (has_working_ptrace_getregs) { 7013c761f0f0344757ac243c65511392fb41d1c841aphilippe // Platforms having SETREGS 7023c761f0f0344757ac243c65511392fb41d1c841aphilippe long res; 7033c761f0f0344757ac243c65511392fb41d1c841aphilippe // setregs can never be called before getregs has done a runtime check. 7043c761f0f0344757ac243c65511392fb41d1c841aphilippe assert (has_working_ptrace_getregs == 1); 7053c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "setregs PTRACE_SETREGS\n"); 7063c761f0f0344757ac243c65511392fb41d1c841aphilippe res = ptrace (PTRACE_SETREGS, pid, NULL, regs); 7073c761f0f0344757ac243c65511392fb41d1c841aphilippe if (res != 0) { 7083c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(errno, "PTRACE_SETREGS %ld\n", res); 7093c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 7103c761f0f0344757ac243c65511392fb41d1c841aphilippe } 7113c761f0f0344757ac243c65511392fb41d1c841aphilippe return True; 7123c761f0f0344757ac243c65511392fb41d1c841aphilippe } 7133c761f0f0344757ac243c65511392fb41d1c841aphilippe# endif 7143c761f0f0344757ac243c65511392fb41d1c841aphilippe 7153c761f0f0344757ac243c65511392fb41d1c841aphilippe { 7163c761f0f0344757ac243c65511392fb41d1c841aphilippe char *pregs = (char *) regs; 7173c761f0f0344757ac243c65511392fb41d1c841aphilippe long offset; 7183c761f0f0344757ac243c65511392fb41d1c841aphilippe long res; 7193c761f0f0344757ac243c65511392fb41d1c841aphilippe# ifdef PT_ENDREGS 7203c761f0f0344757ac243c65511392fb41d1c841aphilippe long peek_bsz = PT_ENDREGS; 7213c761f0f0344757ac243c65511392fb41d1c841aphilippe assert (peek_bsz <= regs_bsz); 7223c761f0f0344757ac243c65511392fb41d1c841aphilippe# else 7233c761f0f0344757ac243c65511392fb41d1c841aphilippe long peek_bsz = regs_bsz-1; 7243c761f0f0344757ac243c65511392fb41d1c841aphilippe# endif 7253c761f0f0344757ac243c65511392fb41d1c841aphilippe errno = 0; 7263c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "setregs PTRACE_POKEUSER(s) %ld\n", peek_bsz); 7273c761f0f0344757ac243c65511392fb41d1c841aphilippe for (offset = 0; offset < peek_bsz; offset = offset + sizeof(long)) { 7283c761f0f0344757ac243c65511392fb41d1c841aphilippe res = ptrace(PTRACE_POKEUSER, pid, offset, *(long*)(pregs+offset)); 7293c761f0f0344757ac243c65511392fb41d1c841aphilippe if (errno != 0) { 7303c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(errno, "PTRACE_POKEUSER offset %ld res %ld\n", offset, res); 7313c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 7323c761f0f0344757ac243c65511392fb41d1c841aphilippe } 7333c761f0f0344757ac243c65511392fb41d1c841aphilippe } 7343c761f0f0344757ac243c65511392fb41d1c841aphilippe return True; 7353c761f0f0344757ac243c65511392fb41d1c841aphilippe } 7363c761f0f0344757ac243c65511392fb41d1c841aphilippe 7373c761f0f0344757ac243c65511392fb41d1c841aphilippe // If neither PTRACE_SETREGS not PTRACE_POKEUSER have returned, 7383c761f0f0344757ac243c65511392fb41d1c841aphilippe // then we are in serious trouble. 7393c761f0f0344757ac243c65511392fb41d1c841aphilippe assert (0); 7403c761f0f0344757ac243c65511392fb41d1c841aphilippe} 7413c761f0f0344757ac243c65511392fb41d1c841aphilippe 7423c761f0f0344757ac243c65511392fb41d1c841aphilippe/* Restore the registers to the saved value, then detaches from all threads */ 7433c761f0f0344757ac243c65511392fb41d1c841aphilippestatic 7443c761f0f0344757ac243c65511392fb41d1c841aphilippevoid restore_and_detach (pid_t pid) 7453c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 7466654de8547d2e420c20e21980669b807aa80710ephilippe int res; 7476654de8547d2e420c20e21980669b807aa80710ephilippe 7486654de8547d2e420c20e21980669b807aa80710ephilippe DEBUG(1, "restore_and_detach pid %d pid_of_save_regs %d\n", 7496654de8547d2e420c20e21980669b807aa80710ephilippe pid, pid_of_save_regs); 7506654de8547d2e420c20e21980669b807aa80710ephilippe 7513c761f0f0344757ac243c65511392fb41d1c841aphilippe if (pid_of_save_regs) { 7523c761f0f0344757ac243c65511392fb41d1c841aphilippe /* In case the 'main pid' has been continued, we need to stop it 7533c761f0f0344757ac243c65511392fb41d1c841aphilippe before resetting the registers. */ 7543c761f0f0344757ac243c65511392fb41d1c841aphilippe if (pid_of_save_regs_continued) { 7553c761f0f0344757ac243c65511392fb41d1c841aphilippe pid_of_save_regs_continued = False; 7563c761f0f0344757ac243c65511392fb41d1c841aphilippe if (!stop(pid_of_save_regs, "sigstop before reset regs")) 7573c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(0, "Could not sigstop before reset"); 7583c761f0f0344757ac243c65511392fb41d1c841aphilippe } 7593c761f0f0344757ac243c65511392fb41d1c841aphilippe 7603c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "setregs restore registers pid %d\n", pid_of_save_regs); 7613c761f0f0344757ac243c65511392fb41d1c841aphilippe if (!setregs(pid_of_save_regs, &user_save.regs, sizeof(user_save.regs))) { 7623c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(errno, "setregs restore registers pid %d after cont\n", 7633c761f0f0344757ac243c65511392fb41d1c841aphilippe pid_of_save_regs); 7643c761f0f0344757ac243c65511392fb41d1c841aphilippe } 7656654de8547d2e420c20e21980669b807aa80710ephilippe 7666654de8547d2e420c20e21980669b807aa80710ephilippe /* Now, we transmit all the signals we have queued. */ 7676654de8547d2e420c20e21980669b807aa80710ephilippe if (signal_queue_sz > 0) { 7686654de8547d2e420c20e21980669b807aa80710ephilippe int i; 7696654de8547d2e420c20e21980669b807aa80710ephilippe for (i = 0; i < signal_queue_sz; i++) { 7706654de8547d2e420c20e21980669b807aa80710ephilippe DEBUG(1, "PTRACE_CONT to transmit queued signal %d\n", 7716654de8547d2e420c20e21980669b807aa80710ephilippe signal_queue[i].si_signo); 7726654de8547d2e420c20e21980669b807aa80710ephilippe res = ptrace (PTRACE_CONT, pid_of_save_regs, NULL, 7736654de8547d2e420c20e21980669b807aa80710ephilippe signal_queue[i].si_signo); 7746654de8547d2e420c20e21980669b807aa80710ephilippe if (res != 0) 7756654de8547d2e420c20e21980669b807aa80710ephilippe ERROR(errno, "PTRACE_CONT with signal %d\n", 7766654de8547d2e420c20e21980669b807aa80710ephilippe signal_queue[i].si_signo); 7776654de8547d2e420c20e21980669b807aa80710ephilippe if (!stop(pid_of_save_regs, "sigstop after transmit sig")) 7786654de8547d2e420c20e21980669b807aa80710ephilippe DEBUG(0, "Could not sigstop after transmit sig"); 7796654de8547d2e420c20e21980669b807aa80710ephilippe } 7806654de8547d2e420c20e21980669b807aa80710ephilippe free (signal_queue); 7816654de8547d2e420c20e21980669b807aa80710ephilippe signal_queue = NULL; 7826654de8547d2e420c20e21980669b807aa80710ephilippe signal_queue_sz = 0; 7836654de8547d2e420c20e21980669b807aa80710ephilippe } 7843c761f0f0344757ac243c65511392fb41d1c841aphilippe pid_of_save_regs = 0; 7853c761f0f0344757ac243c65511392fb41d1c841aphilippe } else { 7863c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "PTRACE_SETREGS restore registers: no pid\n"); 7873c761f0f0344757ac243c65511392fb41d1c841aphilippe } 7886654de8547d2e420c20e21980669b807aa80710ephilippe if (signal_queue) 7896654de8547d2e420c20e21980669b807aa80710ephilippe ERROR (0, "One or more signals queued were not delivered. " 7907136e5f14ebcb8117f629becf48bc8a49ab0b5afcarll "First signal: %d\n", signal_queue[0].si_signo); 7913c761f0f0344757ac243c65511392fb41d1c841aphilippe detach_from_all_threads(pid); 7923c761f0f0344757ac243c65511392fb41d1c841aphilippe} 7933c761f0f0344757ac243c65511392fb41d1c841aphilippe 7943c761f0f0344757ac243c65511392fb41d1c841aphilippeBool invoker_invoke_gdbserver (pid_t pid) 7953c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 7963c761f0f0344757ac243c65511392fb41d1c841aphilippe long res; 7973c761f0f0344757ac243c65511392fb41d1c841aphilippe Bool stopped; 798c07369bc8be6f6a26adfdbe391be7fe64a211829philippe# if defined(VGA_arm64) 7992a429f5d70a41ab1673c9f2ec220e8a10d8c90d5mjw/* arm64 is extra special, old glibc defined kernel user_pt_regs, but 8002a429f5d70a41ab1673c9f2ec220e8a10d8c90d5mjw newer glibc instead define user_regs_struct. */ 8012a429f5d70a41ab1673c9f2ec220e8a10d8c90d5mjw# ifdef HAVE_SYS_USER_REGS 8022a429f5d70a41ab1673c9f2ec220e8a10d8c90d5mjw struct user_regs_struct user_mod; 8032a429f5d70a41ab1673c9f2ec220e8a10d8c90d5mjw# else 804c07369bc8be6f6a26adfdbe391be7fe64a211829philippe struct user_pt_regs user_mod; 8052a429f5d70a41ab1673c9f2ec220e8a10d8c90d5mjw# endif 806c07369bc8be6f6a26adfdbe391be7fe64a211829philippe# else 8073c761f0f0344757ac243c65511392fb41d1c841aphilippe struct user user_mod; 808c07369bc8be6f6a26adfdbe391be7fe64a211829philippe# endif 8093c761f0f0344757ac243c65511392fb41d1c841aphilippe Addr sp; 8103c761f0f0344757ac243c65511392fb41d1c841aphilippe /* A specific int value is passed to invoke_gdbserver, to check 8113c761f0f0344757ac243c65511392fb41d1c841aphilippe everything goes according to the plan. */ 8123c761f0f0344757ac243c65511392fb41d1c841aphilippe const int check = 0x8BADF00D; // ate bad food. 8133c761f0f0344757ac243c65511392fb41d1c841aphilippe 8143c761f0f0344757ac243c65511392fb41d1c841aphilippe const Addr bad_return = 0; 8153c761f0f0344757ac243c65511392fb41d1c841aphilippe // A bad return address will be pushed on the stack. 8163c761f0f0344757ac243c65511392fb41d1c841aphilippe // The function invoke_gdbserver cannot return. If ever it returns, a NULL 8173c761f0f0344757ac243c65511392fb41d1c841aphilippe // address pushed on the stack should ensure this is detected. 8183c761f0f0344757ac243c65511392fb41d1c841aphilippe 8193c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Not yet attached. If problem, vgdb can abort, 8203c761f0f0344757ac243c65511392fb41d1c841aphilippe no cleanup needed. */ 8213c761f0f0344757ac243c65511392fb41d1c841aphilippe 8223c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "attach to 'main' pid %d\n", pid); 8233c761f0f0344757ac243c65511392fb41d1c841aphilippe if (!attach(pid, "attach main pid")) { 8243c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(0, "error attach main pid %d\n", pid); 8253c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 8263c761f0f0344757ac243c65511392fb41d1c841aphilippe } 8273c761f0f0344757ac243c65511392fb41d1c841aphilippe 8283c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Now, we are attached. If problem, detach and return. */ 8293c761f0f0344757ac243c65511392fb41d1c841aphilippe 8303c761f0f0344757ac243c65511392fb41d1c841aphilippe if (!acquire_and_suspend_threads(pid)) { 8313c761f0f0344757ac243c65511392fb41d1c841aphilippe detach_from_all_threads(pid); 8323c761f0f0344757ac243c65511392fb41d1c841aphilippe /* if the pid does not exist anymore, we better stop */ 8333c761f0f0344757ac243c65511392fb41d1c841aphilippe if (kill(pid, 0) != 0) 8343c761f0f0344757ac243c65511392fb41d1c841aphilippe XERROR (errno, "invoke_gdbserver: check for pid %d existence failed\n", 8353c761f0f0344757ac243c65511392fb41d1c841aphilippe pid); 8363c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 8373c761f0f0344757ac243c65511392fb41d1c841aphilippe } 8383c761f0f0344757ac243c65511392fb41d1c841aphilippe 8393c761f0f0344757ac243c65511392fb41d1c841aphilippe if (!getregs(pid, &user_mod.regs, sizeof(user_mod.regs))) { 8403c761f0f0344757ac243c65511392fb41d1c841aphilippe detach_from_all_threads(pid); 8413c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 8423c761f0f0344757ac243c65511392fb41d1c841aphilippe } 8433c761f0f0344757ac243c65511392fb41d1c841aphilippe user_save = user_mod; 8443c761f0f0344757ac243c65511392fb41d1c841aphilippe 8453c761f0f0344757ac243c65511392fb41d1c841aphilippe#if defined(VGA_x86) 8463c761f0f0344757ac243c65511392fb41d1c841aphilippe sp = user_mod.regs.esp; 8473c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_amd64) 8483c761f0f0344757ac243c65511392fb41d1c841aphilippe sp = user_mod.regs.rsp; 8493c761f0f0344757ac243c65511392fb41d1c841aphilippe if (shared32 != NULL) { 8503c761f0f0344757ac243c65511392fb41d1c841aphilippe /* 64bit vgdb speaking with a 32bit executable. 8513c761f0f0344757ac243c65511392fb41d1c841aphilippe To have system call restart properly, we need to sign extend rax. 8523c761f0f0344757ac243c65511392fb41d1c841aphilippe For more info: 8533c761f0f0344757ac243c65511392fb41d1c841aphilippe web search '[patch] Fix syscall restarts for amd64->i386 biarch' 8543c761f0f0344757ac243c65511392fb41d1c841aphilippe e.g. http://sourceware.org/ml/gdb-patches/2009-11/msg00592.html */ 8553c761f0f0344757ac243c65511392fb41d1c841aphilippe *(long *)&user_save.regs.rax = *(int*)&user_save.regs.rax; 8563c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "Sign extending %8.8lx to %8.8lx\n", 8573c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.rax, user_save.regs.rax); 8583c761f0f0344757ac243c65511392fb41d1c841aphilippe } 8593c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_arm) 8603c761f0f0344757ac243c65511392fb41d1c841aphilippe sp = user_mod.regs.uregs[13]; 861c07369bc8be6f6a26adfdbe391be7fe64a211829philippe#elif defined(VGA_arm64) 862c07369bc8be6f6a26adfdbe391be7fe64a211829philippe sp = user_mod.sp; 8633c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_ppc32) 8643c761f0f0344757ac243c65511392fb41d1c841aphilippe sp = user_mod.regs.gpr[1]; 865cae0cc22b83ffb260ee8379e92099c5a701944cbcarll#elif defined(VGA_ppc64be) || defined(VGA_ppc64le) 8663c761f0f0344757ac243c65511392fb41d1c841aphilippe sp = user_mod.regs.gpr[1]; 8673c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_s390x) 8683c761f0f0344757ac243c65511392fb41d1c841aphilippe sp = user_mod.regs.gprs[15]; 8693c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_mips32) 8703c761f0f0344757ac243c65511392fb41d1c841aphilippe long long *p = (long long *)user_mod.regs; 8713c761f0f0344757ac243c65511392fb41d1c841aphilippe sp = p[29]; 8723c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_mips64) 8733c761f0f0344757ac243c65511392fb41d1c841aphilippe sp = user_mod.regs[29]; 8743c761f0f0344757ac243c65511392fb41d1c841aphilippe#else 8753c761f0f0344757ac243c65511392fb41d1c841aphilippe I_die_here : (sp) architecture missing in vgdb.c 8763c761f0f0344757ac243c65511392fb41d1c841aphilippe#endif 8773c761f0f0344757ac243c65511392fb41d1c841aphilippe 8783c761f0f0344757ac243c65511392fb41d1c841aphilippe 8793c761f0f0344757ac243c65511392fb41d1c841aphilippe // the magic below is derived from spying what gdb sends to 8803c761f0f0344757ac243c65511392fb41d1c841aphilippe // the (classical) gdbserver when invoking a C function. 8813c761f0f0344757ac243c65511392fb41d1c841aphilippe if (shared32 != NULL) { 8823c761f0f0344757ac243c65511392fb41d1c841aphilippe // vgdb speaking with a 32bit executable. 8833c761f0f0344757ac243c65511392fb41d1c841aphilippe#if defined(VGA_x86) || defined(VGA_amd64) 8843c761f0f0344757ac243c65511392fb41d1c841aphilippe const int regsize = 4; 8853c761f0f0344757ac243c65511392fb41d1c841aphilippe int rw; 8863c761f0f0344757ac243c65511392fb41d1c841aphilippe /* push check arg on the stack */ 8873c761f0f0344757ac243c65511392fb41d1c841aphilippe sp = sp - regsize; 8883c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "push check arg ptrace_write_memory\n"); 8893c761f0f0344757ac243c65511392fb41d1c841aphilippe assert(regsize == sizeof(check)); 8903c761f0f0344757ac243c65511392fb41d1c841aphilippe rw = ptrace_write_memory(pid, sp, 8913c761f0f0344757ac243c65511392fb41d1c841aphilippe &check, 8923c761f0f0344757ac243c65511392fb41d1c841aphilippe regsize); 8933c761f0f0344757ac243c65511392fb41d1c841aphilippe if (rw != 0) { 8943c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(rw, "push check arg ptrace_write_memory"); 8953c761f0f0344757ac243c65511392fb41d1c841aphilippe detach_from_all_threads(pid); 8963c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 8973c761f0f0344757ac243c65511392fb41d1c841aphilippe } 8983c761f0f0344757ac243c65511392fb41d1c841aphilippe 8993c761f0f0344757ac243c65511392fb41d1c841aphilippe sp = sp - regsize; 9003c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "push bad_return return address ptrace_write_memory\n"); 9013c761f0f0344757ac243c65511392fb41d1c841aphilippe // Note that for a 64 bits vgdb, only 4 bytes of NULL bad_return 9023c761f0f0344757ac243c65511392fb41d1c841aphilippe // are written. 9033c761f0f0344757ac243c65511392fb41d1c841aphilippe rw = ptrace_write_memory(pid, sp, 9043c761f0f0344757ac243c65511392fb41d1c841aphilippe &bad_return, 9053c761f0f0344757ac243c65511392fb41d1c841aphilippe regsize); 9063c761f0f0344757ac243c65511392fb41d1c841aphilippe if (rw != 0) { 9073c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(rw, "push bad_return return address ptrace_write_memory"); 9083c761f0f0344757ac243c65511392fb41d1c841aphilippe detach_from_all_threads(pid); 9093c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 9103c761f0f0344757ac243c65511392fb41d1c841aphilippe } 9113c761f0f0344757ac243c65511392fb41d1c841aphilippe#if defined(VGA_x86) 9123c761f0f0344757ac243c65511392fb41d1c841aphilippe /* set ebp, esp, eip and orig_eax to invoke gdbserver */ 9133c761f0f0344757ac243c65511392fb41d1c841aphilippe // compiled in 32bits, speaking with a 32bits exe 9143c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.ebp = sp; // bp set to sp 9153c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.esp = sp; 9163c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.eip = shared32->invoke_gdbserver; 9173c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.orig_eax = -1L; 9183c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_amd64) 9193c761f0f0344757ac243c65511392fb41d1c841aphilippe /* set ebp, esp, eip and orig_eax to invoke gdbserver */ 9203c761f0f0344757ac243c65511392fb41d1c841aphilippe // compiled in 64bits, speaking with a 32bits exe 9213c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.rbp = sp; // bp set to sp 9223c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.rsp = sp; 9233c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.rip = shared32->invoke_gdbserver; 9243c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.orig_rax = -1L; 9253c761f0f0344757ac243c65511392fb41d1c841aphilippe#else 9263c761f0f0344757ac243c65511392fb41d1c841aphilippe I_die_here : not x86 or amd64 in x86/amd64 section/ 9273c761f0f0344757ac243c65511392fb41d1c841aphilippe#endif 9283c761f0f0344757ac243c65511392fb41d1c841aphilippe 929cae0cc22b83ffb260ee8379e92099c5a701944cbcarll#elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le) 9303c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.nip = shared32->invoke_gdbserver; 9313c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.trap = -1L; 9323c761f0f0344757ac243c65511392fb41d1c841aphilippe /* put check arg in register 3 */ 9333c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.gpr[3] = check; 9343c761f0f0344757ac243c65511392fb41d1c841aphilippe /* put NULL return address in Link Register */ 9353c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.link = bad_return; 9363c761f0f0344757ac243c65511392fb41d1c841aphilippe 9373c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_arm) 9383c761f0f0344757ac243c65511392fb41d1c841aphilippe /* put check arg in register 0 */ 9393c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.uregs[0] = check; 9403c761f0f0344757ac243c65511392fb41d1c841aphilippe /* put NULL return address in Link Register */ 9413c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.uregs[14] = bad_return; 9423c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.uregs[15] = shared32->invoke_gdbserver; 9433c761f0f0344757ac243c65511392fb41d1c841aphilippe 944c07369bc8be6f6a26adfdbe391be7fe64a211829philippe#elif defined(VGA_arm64) 945c07369bc8be6f6a26adfdbe391be7fe64a211829philippe XERROR(0, "TBD arm64: vgdb a 32 bits executable with a 64 bits exe"); 946c07369bc8be6f6a26adfdbe391be7fe64a211829philippe 9473c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_s390x) 9483c761f0f0344757ac243c65511392fb41d1c841aphilippe XERROR(0, "(fn32) s390x has no 32bits implementation"); 9493c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_mips32) 9503c761f0f0344757ac243c65511392fb41d1c841aphilippe /* put check arg in register 4 */ 9513c761f0f0344757ac243c65511392fb41d1c841aphilippe p[4] = check; 9523c761f0f0344757ac243c65511392fb41d1c841aphilippe /* put NULL return address in ra */ 9533c761f0f0344757ac243c65511392fb41d1c841aphilippe p[31] = bad_return; 9543c761f0f0344757ac243c65511392fb41d1c841aphilippe p[34] = shared32->invoke_gdbserver; 9553c761f0f0344757ac243c65511392fb41d1c841aphilippe p[25] = shared32->invoke_gdbserver; 9563c761f0f0344757ac243c65511392fb41d1c841aphilippe /* make stack space for args */ 9573c761f0f0344757ac243c65511392fb41d1c841aphilippe p[29] = sp - 32; 9583c761f0f0344757ac243c65511392fb41d1c841aphilippe 9593c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_mips64) 9603c761f0f0344757ac243c65511392fb41d1c841aphilippe assert(0); // cannot vgdb a 32 bits executable with a 64 bits exe 9613c761f0f0344757ac243c65511392fb41d1c841aphilippe#else 9623c761f0f0344757ac243c65511392fb41d1c841aphilippe I_die_here : architecture missing in vgdb.c 9633c761f0f0344757ac243c65511392fb41d1c841aphilippe#endif 9643c761f0f0344757ac243c65511392fb41d1c841aphilippe } 9653c761f0f0344757ac243c65511392fb41d1c841aphilippe 9663c761f0f0344757ac243c65511392fb41d1c841aphilippe else if (shared64 != NULL) { 9673c761f0f0344757ac243c65511392fb41d1c841aphilippe#if defined(VGA_x86) 9683c761f0f0344757ac243c65511392fb41d1c841aphilippe assert(0); // cannot vgdb a 64 bits executable with a 32 bits exe 9693c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_amd64) 9703c761f0f0344757ac243c65511392fb41d1c841aphilippe // vgdb speaking with a 64 bit executable. 9713c761f0f0344757ac243c65511392fb41d1c841aphilippe const int regsize = 8; 9723c761f0f0344757ac243c65511392fb41d1c841aphilippe int rw; 9733c761f0f0344757ac243c65511392fb41d1c841aphilippe 9743c761f0f0344757ac243c65511392fb41d1c841aphilippe /* give check arg in rdi */ 9753c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.rdi = check; 9763c761f0f0344757ac243c65511392fb41d1c841aphilippe 9773c761f0f0344757ac243c65511392fb41d1c841aphilippe /* push return address on stack : return to breakaddr */ 9783c761f0f0344757ac243c65511392fb41d1c841aphilippe sp = sp - regsize; 9793c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "push bad_return return address ptrace_write_memory\n"); 9803c761f0f0344757ac243c65511392fb41d1c841aphilippe rw = ptrace_write_memory(pid, sp, 9813c761f0f0344757ac243c65511392fb41d1c841aphilippe &bad_return, 9823c761f0f0344757ac243c65511392fb41d1c841aphilippe sizeof(bad_return)); 9833c761f0f0344757ac243c65511392fb41d1c841aphilippe if (rw != 0) { 9843c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(rw, "push bad_return return address ptrace_write_memory"); 9853c761f0f0344757ac243c65511392fb41d1c841aphilippe detach_from_all_threads(pid); 9863c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 9873c761f0f0344757ac243c65511392fb41d1c841aphilippe } 9883c761f0f0344757ac243c65511392fb41d1c841aphilippe 9893c761f0f0344757ac243c65511392fb41d1c841aphilippe /* set rbp, rsp, rip and orig_rax to invoke gdbserver */ 9903c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.rbp = sp; // bp set to sp 9913c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.rsp = sp; 9923c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.rip = shared64->invoke_gdbserver; 9933c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.orig_rax = -1L; 9943c761f0f0344757ac243c65511392fb41d1c841aphilippe 9953c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_arm) 9963c761f0f0344757ac243c65511392fb41d1c841aphilippe assert(0); // cannot vgdb a 64 bits executable with a 32 bits exe 997c07369bc8be6f6a26adfdbe391be7fe64a211829philippe#elif defined(VGA_arm64) 998c07369bc8be6f6a26adfdbe391be7fe64a211829philippe user_mod.regs[0] = check; 999c07369bc8be6f6a26adfdbe391be7fe64a211829philippe user_mod.sp = sp; 1000c07369bc8be6f6a26adfdbe391be7fe64a211829philippe user_mod.pc = shared64->invoke_gdbserver; 1001c07369bc8be6f6a26adfdbe391be7fe64a211829philippe /* put NULL return address in Link Register */ 1002c07369bc8be6f6a26adfdbe391be7fe64a211829philippe user_mod.regs[30] = bad_return; 1003c07369bc8be6f6a26adfdbe391be7fe64a211829philippe 10043c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_ppc32) 10053c761f0f0344757ac243c65511392fb41d1c841aphilippe assert(0); // cannot vgdb a 64 bits executable with a 32 bits exe 1006cae0cc22b83ffb260ee8379e92099c5a701944cbcarll#elif defined(VGA_ppc64be) 10073c761f0f0344757ac243c65511392fb41d1c841aphilippe Addr64 func_addr; 10083c761f0f0344757ac243c65511392fb41d1c841aphilippe Addr64 toc_addr; 10093c761f0f0344757ac243c65511392fb41d1c841aphilippe int rw; 10103c761f0f0344757ac243c65511392fb41d1c841aphilippe rw = ptrace_read_memory(pid, shared64->invoke_gdbserver, 10113c761f0f0344757ac243c65511392fb41d1c841aphilippe &func_addr, 10123c761f0f0344757ac243c65511392fb41d1c841aphilippe sizeof(Addr64)); 10133c761f0f0344757ac243c65511392fb41d1c841aphilippe if (rw != 0) { 10143c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(rw, "ppc64 read func_addr\n"); 10153c761f0f0344757ac243c65511392fb41d1c841aphilippe detach_from_all_threads(pid); 10163c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 10173c761f0f0344757ac243c65511392fb41d1c841aphilippe } 10183c761f0f0344757ac243c65511392fb41d1c841aphilippe rw = ptrace_read_memory(pid, shared64->invoke_gdbserver+8, 10193c761f0f0344757ac243c65511392fb41d1c841aphilippe &toc_addr, 10203c761f0f0344757ac243c65511392fb41d1c841aphilippe sizeof(Addr64)); 10213c761f0f0344757ac243c65511392fb41d1c841aphilippe if (rw != 0) { 10223c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(rw, "ppc64 read toc_addr\n"); 10233c761f0f0344757ac243c65511392fb41d1c841aphilippe detach_from_all_threads(pid); 10243c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 10253c761f0f0344757ac243c65511392fb41d1c841aphilippe } 10263c761f0f0344757ac243c65511392fb41d1c841aphilippe // We are not pushing anything on the stack, so it is not 10273c761f0f0344757ac243c65511392fb41d1c841aphilippe // very clear why the sp has to be decreased, but it seems 10283c761f0f0344757ac243c65511392fb41d1c841aphilippe // needed. The ppc64 ABI might give some lights on this ? 10293c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.gpr[1] = sp - 220; 10303c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.gpr[2] = toc_addr; 10313c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.nip = func_addr; 10323c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.trap = -1L; 10333c761f0f0344757ac243c65511392fb41d1c841aphilippe /* put check arg in register 3 */ 10343c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.gpr[3] = check; 10353c761f0f0344757ac243c65511392fb41d1c841aphilippe /* put bad_return return address in Link Register */ 10363c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.link = bad_return; 1037582d58245637ab05272d89fb94b12fd0f18fa0f8carll#elif defined(VGA_ppc64le) 1038582d58245637ab05272d89fb94b12fd0f18fa0f8carll /* LE does not use the function pointer structure used in BE */ 1039582d58245637ab05272d89fb94b12fd0f18fa0f8carll user_mod.regs.nip = shared64->invoke_gdbserver; 1040582d58245637ab05272d89fb94b12fd0f18fa0f8carll user_mod.regs.gpr[1] = sp - 512; 1041582d58245637ab05272d89fb94b12fd0f18fa0f8carll user_mod.regs.gpr[12] = user_mod.regs.nip; 1042582d58245637ab05272d89fb94b12fd0f18fa0f8carll user_mod.regs.trap = -1L; 1043582d58245637ab05272d89fb94b12fd0f18fa0f8carll /* put check arg in register 3 */ 1044582d58245637ab05272d89fb94b12fd0f18fa0f8carll user_mod.regs.gpr[3] = check; 1045582d58245637ab05272d89fb94b12fd0f18fa0f8carll /* put bad_return return address in Link Register */ 1046582d58245637ab05272d89fb94b12fd0f18fa0f8carll user_mod.regs.link = bad_return; 10473c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_s390x) 10483c761f0f0344757ac243c65511392fb41d1c841aphilippe /* put check arg in register r2 */ 10493c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.gprs[2] = check; 10503c761f0f0344757ac243c65511392fb41d1c841aphilippe /* bad_return Return address is in r14 */ 10513c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.gprs[14] = bad_return; 10523c761f0f0344757ac243c65511392fb41d1c841aphilippe /* minimum stack frame */ 10533c761f0f0344757ac243c65511392fb41d1c841aphilippe sp = sp - 160; 10543c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.gprs[15] = sp; 10553c761f0f0344757ac243c65511392fb41d1c841aphilippe /* set program counter */ 10563c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.psw.addr = shared64->invoke_gdbserver; 10573c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_mips32) 10583c761f0f0344757ac243c65511392fb41d1c841aphilippe assert(0); // cannot vgdb a 64 bits executable with a 32 bits exe 10593c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_mips64) 10603c761f0f0344757ac243c65511392fb41d1c841aphilippe /* put check arg in register 4 */ 10613c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs[4] = check; 10623c761f0f0344757ac243c65511392fb41d1c841aphilippe /* put NULL return address in ra */ 10633c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs[31] = bad_return; 10643c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs[34] = shared64->invoke_gdbserver; 10653c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs[25] = shared64->invoke_gdbserver; 10663c761f0f0344757ac243c65511392fb41d1c841aphilippe#else 10673c761f0f0344757ac243c65511392fb41d1c841aphilippe I_die_here: architecture missing in vgdb.c 10683c761f0f0344757ac243c65511392fb41d1c841aphilippe#endif 10693c761f0f0344757ac243c65511392fb41d1c841aphilippe } 10703c761f0f0344757ac243c65511392fb41d1c841aphilippe else { 10713c761f0f0344757ac243c65511392fb41d1c841aphilippe assert(0); 10723c761f0f0344757ac243c65511392fb41d1c841aphilippe } 10733c761f0f0344757ac243c65511392fb41d1c841aphilippe 10743c761f0f0344757ac243c65511392fb41d1c841aphilippe if (!setregs(pid, &user_mod.regs, sizeof(user_mod.regs))) { 10753c761f0f0344757ac243c65511392fb41d1c841aphilippe detach_from_all_threads(pid); 10763c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 10773c761f0f0344757ac243c65511392fb41d1c841aphilippe } 10783c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Now that we have modified the registers, we set 10793c761f0f0344757ac243c65511392fb41d1c841aphilippe pid_of_save_regs to indicate that restore_and_detach 10803c761f0f0344757ac243c65511392fb41d1c841aphilippe must restore the registers in case of cleanup. */ 10813c761f0f0344757ac243c65511392fb41d1c841aphilippe pid_of_save_regs = pid; 10823c761f0f0344757ac243c65511392fb41d1c841aphilippe pid_of_save_regs_continued = False; 10833c761f0f0344757ac243c65511392fb41d1c841aphilippe 10843c761f0f0344757ac243c65511392fb41d1c841aphilippe 10853c761f0f0344757ac243c65511392fb41d1c841aphilippe /* We PTRACE_CONT-inue pid. 10863c761f0f0344757ac243c65511392fb41d1c841aphilippe Either gdbserver will be invoked directly (if all 10873c761f0f0344757ac243c65511392fb41d1c841aphilippe threads are interruptible) or gdbserver will be 10883c761f0f0344757ac243c65511392fb41d1c841aphilippe called soon by the scheduler. In the first case, 10893c761f0f0344757ac243c65511392fb41d1c841aphilippe pid will stop on the break inserted above when 10903c761f0f0344757ac243c65511392fb41d1c841aphilippe gdbserver returns. In the 2nd case, the break will 10913c761f0f0344757ac243c65511392fb41d1c841aphilippe be encountered directly. */ 10923c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "PTRACE_CONT to invoke\n"); 10933c761f0f0344757ac243c65511392fb41d1c841aphilippe res = ptrace (PTRACE_CONT, pid, NULL, NULL); 10943c761f0f0344757ac243c65511392fb41d1c841aphilippe if (res != 0) { 10953c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(errno, "PTRACE_CONT\n"); 10963c761f0f0344757ac243c65511392fb41d1c841aphilippe restore_and_detach(pid); 10973c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 10983c761f0f0344757ac243c65511392fb41d1c841aphilippe } 10993c761f0f0344757ac243c65511392fb41d1c841aphilippe pid_of_save_regs_continued = True; 11003c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Wait for SIGSTOP generated by m_gdbserver.c give_control_back_to_vgdb */ 11013c761f0f0344757ac243c65511392fb41d1c841aphilippe stopped = waitstopped (pid, SIGSTOP, 11023c761f0f0344757ac243c65511392fb41d1c841aphilippe "waitpid status after PTRACE_CONT to invoke"); 11033c761f0f0344757ac243c65511392fb41d1c841aphilippe if (stopped) { 11043c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Here pid has properly stopped on the break. */ 11053c761f0f0344757ac243c65511392fb41d1c841aphilippe pid_of_save_regs_continued = False; 11063c761f0f0344757ac243c65511392fb41d1c841aphilippe restore_and_detach(pid); 11073c761f0f0344757ac243c65511392fb41d1c841aphilippe return True; 11083c761f0f0344757ac243c65511392fb41d1c841aphilippe } else { 11093c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Whatever kind of problem happened. We shutdown. */ 11103c761f0f0344757ac243c65511392fb41d1c841aphilippe shutting_down = True; 11113c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 11123c761f0f0344757ac243c65511392fb41d1c841aphilippe } 11133c761f0f0344757ac243c65511392fb41d1c841aphilippe} 11143c761f0f0344757ac243c65511392fb41d1c841aphilippe 11153c761f0f0344757ac243c65511392fb41d1c841aphilippevoid invoker_cleanup_restore_and_detach(void *v_pid) 11163c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 11173c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "invoker_cleanup_restore_and_detach dying: %d\n", dying); 11183c761f0f0344757ac243c65511392fb41d1c841aphilippe if (!dying) 11193c761f0f0344757ac243c65511392fb41d1c841aphilippe restore_and_detach(*(int*)v_pid); 11203c761f0f0344757ac243c65511392fb41d1c841aphilippe} 11213c761f0f0344757ac243c65511392fb41d1c841aphilippe 11223c761f0f0344757ac243c65511392fb41d1c841aphilippevoid invoker_restrictions_msg(void) 11233c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 11243c761f0f0344757ac243c65511392fb41d1c841aphilippe} 11253c761f0f0344757ac243c65511392fb41d1c841aphilippe 11263c761f0f0344757ac243c65511392fb41d1c841aphilippevoid invoker_valgrind_dying(void) 11273c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 11283c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Avoid messing up with registers of valgrind when it is dying. */ 11293c761f0f0344757ac243c65511392fb41d1c841aphilippe pid_of_save_regs_continued = False; 11303c761f0f0344757ac243c65511392fb41d1c841aphilippe dying = True; 11313c761f0f0344757ac243c65511392fb41d1c841aphilippe} 1132