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 673629f4a3d4a0237421da38f5f5cdf6fcfa368d03florian// glibc versions prior to 2.5 do not define PTRACE_GETSIGINFO on 683629f4a3d4a0237421da38f5f5cdf6fcfa368d03florian// the platforms we support. 693629f4a3d4a0237421da38f5f5cdf6fcfa368d03florian#if !((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 5)) 703b4ef11d87596b6d63d690caf517a3abf62d39d4florian# ifndef PTRACE_GETSIGINFO 713b4ef11d87596b6d63d690caf517a3abf62d39d4florian# define PTRACE_GETSIGINFO 0x4202 723b4ef11d87596b6d63d690caf517a3abf62d39d4florian# endif 733b4ef11d87596b6d63d690caf517a3abf62d39d4florian#endif 743b4ef11d87596b6d63d690caf517a3abf62d39d4florian 754769c3c0594bb0cbfd31a953ed39dafbe108605cphilippe// 32-bit or 64-bit wide, depending on primary architecture. 764769c3c0594bb0cbfd31a953ed39dafbe108605cphilippetypedef Addr CORE_ADDR; 774769c3c0594bb0cbfd31a953ed39dafbe108605cphilippetypedef Addr PTRACE_XFER_TYPE; 783c761f0f0344757ac243c65511392fb41d1c841aphilippetypedef void* PTRACE_ARG3_TYPE; 793c761f0f0344757ac243c65511392fb41d1c841aphilippe 806654de8547d2e420c20e21980669b807aa80710ephilippe// if > 0, pid for which registers have to be restored. 816654de8547d2e420c20e21980669b807aa80710ephilippe// if == 0, means we have not yet called setregs (or have already 826654de8547d2e420c20e21980669b807aa80710ephilippe// restored the registers). 836654de8547d2e420c20e21980669b807aa80710ephilippestatic int pid_of_save_regs = 0; 843c761f0f0344757ac243c65511392fb41d1c841aphilippe/* True if we have continued pid_of_save_regs after PTRACE_ATTACH. */ 853c761f0f0344757ac243c65511392fb41d1c841aphilippestatic Bool pid_of_save_regs_continued = False; 866654de8547d2e420c20e21980669b807aa80710ephilippe// When setregs has been called to change the registers of pid_of_save_regs, 876654de8547d2e420c20e21980669b807aa80710ephilippe// vgdb cannot transmit the signals intercepted during ptrace. 886654de8547d2e420c20e21980669b807aa80710ephilippe// So, we queue them, and will deliver them when detaching. 896654de8547d2e420c20e21980669b807aa80710ephilippe// See function waitstopped for more info. 906654de8547d2e420c20e21980669b807aa80710ephilippestatic int signal_queue_sz = 0; 916654de8547d2e420c20e21980669b807aa80710ephilippestatic siginfo_t *signal_queue; 923c761f0f0344757ac243c65511392fb41d1c841aphilippe 933c761f0f0344757ac243c65511392fb41d1c841aphilippe/* True when loss of connection indicating that the Valgrind 943c761f0f0344757ac243c65511392fb41d1c841aphilippe process is dying. */ 953c761f0f0344757ac243c65511392fb41d1c841aphilippestatic Bool dying = False; 963c761f0f0344757ac243c65511392fb41d1c841aphilippe 973c761f0f0344757ac243c65511392fb41d1c841aphilippe/* ptrace_(read|write)_memory are modified extracts of linux-low.c 983c761f0f0344757ac243c65511392fb41d1c841aphilippe from gdb 6.6. Copyrighted FSF */ 993c761f0f0344757ac243c65511392fb41d1c841aphilippe/* Copy LEN bytes from valgrind memory starting at MEMADDR 1003c761f0f0344757ac243c65511392fb41d1c841aphilippe to vgdb memory starting at MYADDR. */ 1013c761f0f0344757ac243c65511392fb41d1c841aphilippestatic 1023c761f0f0344757ac243c65511392fb41d1c841aphilippeint ptrace_read_memory (pid_t inferior_pid, CORE_ADDR memaddr, 1033c761f0f0344757ac243c65511392fb41d1c841aphilippe void *myaddr, size_t len) 1043c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 1053c761f0f0344757ac243c65511392fb41d1c841aphilippe register int i; 1063c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Round starting address down to longword boundary. */ 1073c761f0f0344757ac243c65511392fb41d1c841aphilippe register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE); 1083c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Round ending address up; get number of longwords that makes. */ 1093c761f0f0344757ac243c65511392fb41d1c841aphilippe register int count 1103c761f0f0344757ac243c65511392fb41d1c841aphilippe = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) 1113c761f0f0344757ac243c65511392fb41d1c841aphilippe / sizeof (PTRACE_XFER_TYPE); 1123c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Allocate buffer of that many longwords. */ 1133c761f0f0344757ac243c65511392fb41d1c841aphilippe register PTRACE_XFER_TYPE *buffer 1143c761f0f0344757ac243c65511392fb41d1c841aphilippe = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE)); 1153c761f0f0344757ac243c65511392fb41d1c841aphilippe 1163c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Read all the longwords */ 1173c761f0f0344757ac243c65511392fb41d1c841aphilippe for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) { 1183c761f0f0344757ac243c65511392fb41d1c841aphilippe errno = 0; 1193c761f0f0344757ac243c65511392fb41d1c841aphilippe buffer[i] = ptrace (PTRACE_PEEKTEXT, inferior_pid, 1203c761f0f0344757ac243c65511392fb41d1c841aphilippe (PTRACE_ARG3_TYPE) addr, 0); 1213c761f0f0344757ac243c65511392fb41d1c841aphilippe if (errno) 1223c761f0f0344757ac243c65511392fb41d1c841aphilippe return errno; 1233c761f0f0344757ac243c65511392fb41d1c841aphilippe } 1243c761f0f0344757ac243c65511392fb41d1c841aphilippe 1253c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Copy appropriate bytes out of the buffer. */ 1263c761f0f0344757ac243c65511392fb41d1c841aphilippe memcpy (myaddr, 1273c761f0f0344757ac243c65511392fb41d1c841aphilippe (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), len); 1283c761f0f0344757ac243c65511392fb41d1c841aphilippe 1293c761f0f0344757ac243c65511392fb41d1c841aphilippe return 0; 1303c761f0f0344757ac243c65511392fb41d1c841aphilippe} 1313c761f0f0344757ac243c65511392fb41d1c841aphilippe 1323c761f0f0344757ac243c65511392fb41d1c841aphilippe/* Copy LEN bytes of data from vgdb memory at MYADDR 1333c761f0f0344757ac243c65511392fb41d1c841aphilippe to valgrind memory at MEMADDR. 1343c761f0f0344757ac243c65511392fb41d1c841aphilippe On failure (cannot write the valgrind memory) 1353c761f0f0344757ac243c65511392fb41d1c841aphilippe returns the value of errno. */ 1363c761f0f0344757ac243c65511392fb41d1c841aphilippe__attribute__((unused)) /* not used on all platforms */ 1373c761f0f0344757ac243c65511392fb41d1c841aphilippestatic 1383c761f0f0344757ac243c65511392fb41d1c841aphilippeint ptrace_write_memory (pid_t inferior_pid, CORE_ADDR memaddr, 1393c761f0f0344757ac243c65511392fb41d1c841aphilippe const void *myaddr, size_t len) 1403c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 1413c761f0f0344757ac243c65511392fb41d1c841aphilippe register int i; 1423c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Round starting address down to longword boundary. */ 1433c761f0f0344757ac243c65511392fb41d1c841aphilippe register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE); 1443c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Round ending address up; get number of longwords that makes. */ 1453c761f0f0344757ac243c65511392fb41d1c841aphilippe register int count 1463c761f0f0344757ac243c65511392fb41d1c841aphilippe = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) 1473c761f0f0344757ac243c65511392fb41d1c841aphilippe / sizeof (PTRACE_XFER_TYPE); 1483c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Allocate buffer of that many longwords. */ 1493c761f0f0344757ac243c65511392fb41d1c841aphilippe register PTRACE_XFER_TYPE *buffer 1503c761f0f0344757ac243c65511392fb41d1c841aphilippe = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE)); 1513c761f0f0344757ac243c65511392fb41d1c841aphilippe 1523c761f0f0344757ac243c65511392fb41d1c841aphilippe if (debuglevel >= 1) { 1533c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG (1, "Writing "); 1543c761f0f0344757ac243c65511392fb41d1c841aphilippe for (i = 0; i < len; i++) 1553c761f0f0344757ac243c65511392fb41d1c841aphilippe PDEBUG (1, "%02x", ((const unsigned char*)myaddr)[i]); 1563c761f0f0344757ac243c65511392fb41d1c841aphilippe PDEBUG(1, " to %p\n", (void *) memaddr); 1573c761f0f0344757ac243c65511392fb41d1c841aphilippe } 1583c761f0f0344757ac243c65511392fb41d1c841aphilippe 1593c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Fill start and end extra bytes of buffer with existing memory data. */ 1603c761f0f0344757ac243c65511392fb41d1c841aphilippe 1613c761f0f0344757ac243c65511392fb41d1c841aphilippe buffer[0] = ptrace (PTRACE_PEEKTEXT, inferior_pid, 1623c761f0f0344757ac243c65511392fb41d1c841aphilippe (PTRACE_ARG3_TYPE) addr, 0); 1633c761f0f0344757ac243c65511392fb41d1c841aphilippe 1643c761f0f0344757ac243c65511392fb41d1c841aphilippe if (count > 1) { 1653c761f0f0344757ac243c65511392fb41d1c841aphilippe buffer[count - 1] 1663c761f0f0344757ac243c65511392fb41d1c841aphilippe = ptrace (PTRACE_PEEKTEXT, inferior_pid, 1673c761f0f0344757ac243c65511392fb41d1c841aphilippe (PTRACE_ARG3_TYPE) (addr + (count - 1) 1683c761f0f0344757ac243c65511392fb41d1c841aphilippe * sizeof (PTRACE_XFER_TYPE)), 1693c761f0f0344757ac243c65511392fb41d1c841aphilippe 0); 1703c761f0f0344757ac243c65511392fb41d1c841aphilippe } 1713c761f0f0344757ac243c65511392fb41d1c841aphilippe 1723c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Copy data to be written over corresponding part of buffer */ 1733c761f0f0344757ac243c65511392fb41d1c841aphilippe 1743c761f0f0344757ac243c65511392fb41d1c841aphilippe memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), 1753c761f0f0344757ac243c65511392fb41d1c841aphilippe myaddr, len); 1763c761f0f0344757ac243c65511392fb41d1c841aphilippe 1773c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Write the entire buffer. */ 1783c761f0f0344757ac243c65511392fb41d1c841aphilippe 1793c761f0f0344757ac243c65511392fb41d1c841aphilippe for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) { 1803c761f0f0344757ac243c65511392fb41d1c841aphilippe errno = 0; 1813c761f0f0344757ac243c65511392fb41d1c841aphilippe ptrace (PTRACE_POKETEXT, inferior_pid, 1823c761f0f0344757ac243c65511392fb41d1c841aphilippe (PTRACE_ARG3_TYPE) addr, buffer[i]); 1833c761f0f0344757ac243c65511392fb41d1c841aphilippe if (errno) 1843c761f0f0344757ac243c65511392fb41d1c841aphilippe return errno; 1853c761f0f0344757ac243c65511392fb41d1c841aphilippe } 1863c761f0f0344757ac243c65511392fb41d1c841aphilippe 1873c761f0f0344757ac243c65511392fb41d1c841aphilippe return 0; 1883c761f0f0344757ac243c65511392fb41d1c841aphilippe} 1893c761f0f0344757ac243c65511392fb41d1c841aphilippe 1903c761f0f0344757ac243c65511392fb41d1c841aphilippe/* subset of VG_(threads) needed for vgdb ptrace. 1913c761f0f0344757ac243c65511392fb41d1c841aphilippe This is initialized when process is attached. */ 1923c761f0f0344757ac243c65511392fb41d1c841aphilippetypedef struct { 1933c761f0f0344757ac243c65511392fb41d1c841aphilippe ThreadStatus status; 1943c761f0f0344757ac243c65511392fb41d1c841aphilippe Int lwpid; 1953c761f0f0344757ac243c65511392fb41d1c841aphilippe} 1963c761f0f0344757ac243c65511392fb41d1c841aphilippeVgdbThreadState; 197b12f502f96dee3ead809420943ce5386ded4775aphilippestatic VgdbThreadState *vgdb_threads; 198b12f502f96dee3ead809420943ce5386ded4775aphilippestatic int vg_n_threads; 1993c761f0f0344757ac243c65511392fb41d1c841aphilippe 2003c761f0f0344757ac243c65511392fb41d1c841aphilippestatic const 2013c761f0f0344757ac243c65511392fb41d1c841aphilippeHChar* name_of_ThreadStatus ( ThreadStatus status ) 2023c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 2033c761f0f0344757ac243c65511392fb41d1c841aphilippe switch (status) { 2043c761f0f0344757ac243c65511392fb41d1c841aphilippe case VgTs_Empty: return "VgTs_Empty"; 2053c761f0f0344757ac243c65511392fb41d1c841aphilippe case VgTs_Init: return "VgTs_Init"; 2063c761f0f0344757ac243c65511392fb41d1c841aphilippe case VgTs_Runnable: return "VgTs_Runnable"; 2073c761f0f0344757ac243c65511392fb41d1c841aphilippe case VgTs_WaitSys: return "VgTs_WaitSys"; 2083c761f0f0344757ac243c65511392fb41d1c841aphilippe case VgTs_Yielding: return "VgTs_Yielding"; 2093c761f0f0344757ac243c65511392fb41d1c841aphilippe case VgTs_Zombie: return "VgTs_Zombie"; 2103c761f0f0344757ac243c65511392fb41d1c841aphilippe default: return "VgTs_???"; 2113c761f0f0344757ac243c65511392fb41d1c841aphilippe } 2123c761f0f0344757ac243c65511392fb41d1c841aphilippe} 2133c761f0f0344757ac243c65511392fb41d1c841aphilippe 2143c761f0f0344757ac243c65511392fb41d1c841aphilippestatic 2153c761f0f0344757ac243c65511392fb41d1c841aphilippechar *status_image (int status) 2163c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 2177b7d59405204f88cb944155d6bc5114025ebda98florian static char result[256]; // large enough 2183c761f0f0344757ac243c65511392fb41d1c841aphilippe int sz = 0; 2193c761f0f0344757ac243c65511392fb41d1c841aphilippe#define APPEND(...) sz += snprintf (result+sz, 256 - sz - 1, __VA_ARGS__) 2203c761f0f0344757ac243c65511392fb41d1c841aphilippe 2213c761f0f0344757ac243c65511392fb41d1c841aphilippe result[0] = 0; 2223c761f0f0344757ac243c65511392fb41d1c841aphilippe 2233c761f0f0344757ac243c65511392fb41d1c841aphilippe if (WIFEXITED(status)) 2243c761f0f0344757ac243c65511392fb41d1c841aphilippe APPEND ("WIFEXITED %d ", WEXITSTATUS(status)); 2253c761f0f0344757ac243c65511392fb41d1c841aphilippe 2263c761f0f0344757ac243c65511392fb41d1c841aphilippe if (WIFSIGNALED(status)) { 2273c761f0f0344757ac243c65511392fb41d1c841aphilippe APPEND ("WIFSIGNALED %d ", WTERMSIG(status)); 2283c761f0f0344757ac243c65511392fb41d1c841aphilippe if (WCOREDUMP(status)) APPEND ("WCOREDUMP "); 2293c761f0f0344757ac243c65511392fb41d1c841aphilippe } 2303c761f0f0344757ac243c65511392fb41d1c841aphilippe 2313c761f0f0344757ac243c65511392fb41d1c841aphilippe if (WIFSTOPPED(status)) 2323c761f0f0344757ac243c65511392fb41d1c841aphilippe APPEND ("WIFSTOPPED %d ", WSTOPSIG(status)); 2333c761f0f0344757ac243c65511392fb41d1c841aphilippe 2343c761f0f0344757ac243c65511392fb41d1c841aphilippe#ifdef WIFCONTINUED 2353c761f0f0344757ac243c65511392fb41d1c841aphilippe if (WIFCONTINUED(status)) 2363c761f0f0344757ac243c65511392fb41d1c841aphilippe APPEND ("WIFCONTINUED "); 2373c761f0f0344757ac243c65511392fb41d1c841aphilippe#endif 2383c761f0f0344757ac243c65511392fb41d1c841aphilippe 2393c761f0f0344757ac243c65511392fb41d1c841aphilippe return result; 2403c761f0f0344757ac243c65511392fb41d1c841aphilippe#undef APPEND 2413c761f0f0344757ac243c65511392fb41d1c841aphilippe} 2423c761f0f0344757ac243c65511392fb41d1c841aphilippe 2433c761f0f0344757ac243c65511392fb41d1c841aphilippe/* Wait till the process pid is reported as stopped with signal_expected. 2443c761f0f0344757ac243c65511392fb41d1c841aphilippe If other signal(s) than signal_expected are received, waitstopped 2453c761f0f0344757ac243c65511392fb41d1c841aphilippe will pass them to pid, waiting for signal_expected to stop pid. 2463c761f0f0344757ac243c65511392fb41d1c841aphilippe Returns True when process is in stopped state with signal_expected. 2473c761f0f0344757ac243c65511392fb41d1c841aphilippe Returns False if a problem was encountered while waiting for pid 2483c761f0f0344757ac243c65511392fb41d1c841aphilippe to be stopped. 2493c761f0f0344757ac243c65511392fb41d1c841aphilippe 2503c761f0f0344757ac243c65511392fb41d1c841aphilippe If pid is reported as being dead/exited, waitstopped will return False. 2513c761f0f0344757ac243c65511392fb41d1c841aphilippe*/ 2523c761f0f0344757ac243c65511392fb41d1c841aphilippestatic 2533c761f0f0344757ac243c65511392fb41d1c841aphilippeBool waitstopped (pid_t pid, int signal_expected, const char *msg) 2543c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 2553c761f0f0344757ac243c65511392fb41d1c841aphilippe pid_t p; 2563c761f0f0344757ac243c65511392fb41d1c841aphilippe int status = 0; 2573c761f0f0344757ac243c65511392fb41d1c841aphilippe int signal_received; 2583c761f0f0344757ac243c65511392fb41d1c841aphilippe int res; 2593c761f0f0344757ac243c65511392fb41d1c841aphilippe 2603c761f0f0344757ac243c65511392fb41d1c841aphilippe while (1) { 2613c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "waitstopped %s before waitpid signal_expected %d\n", 2623c761f0f0344757ac243c65511392fb41d1c841aphilippe msg, signal_expected); 2633c761f0f0344757ac243c65511392fb41d1c841aphilippe p = waitpid(pid, &status, __WALL); 2643c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "after waitpid pid %d p %d status 0x%x %s\n", pid, p, 2653c761f0f0344757ac243c65511392fb41d1c841aphilippe status, status_image (status)); 2663c761f0f0344757ac243c65511392fb41d1c841aphilippe if (p != pid) { 2673c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(errno, "%s waitpid pid %d in waitstopped %d status 0x%x %s\n", 2683c761f0f0344757ac243c65511392fb41d1c841aphilippe msg, pid, p, status, status_image (status)); 2693c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 2703c761f0f0344757ac243c65511392fb41d1c841aphilippe } 2713c761f0f0344757ac243c65511392fb41d1c841aphilippe 2723c761f0f0344757ac243c65511392fb41d1c841aphilippe if (WIFEXITED(status)) { 2733c761f0f0344757ac243c65511392fb41d1c841aphilippe shutting_down = True; 2743c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 2753c761f0f0344757ac243c65511392fb41d1c841aphilippe } 2763c761f0f0344757ac243c65511392fb41d1c841aphilippe 2773c761f0f0344757ac243c65511392fb41d1c841aphilippe assert (WIFSTOPPED(status)); 2783c761f0f0344757ac243c65511392fb41d1c841aphilippe signal_received = WSTOPSIG(status); 2793c761f0f0344757ac243c65511392fb41d1c841aphilippe if (signal_received == signal_expected) 2803c761f0f0344757ac243c65511392fb41d1c841aphilippe break; 2813c761f0f0344757ac243c65511392fb41d1c841aphilippe 2823c761f0f0344757ac243c65511392fb41d1c841aphilippe /* pid received a signal which is not the signal we are waiting for. 2836654de8547d2e420c20e21980669b807aa80710ephilippe If we have not (yet) changed the registers of the inferior 2846654de8547d2e420c20e21980669b807aa80710ephilippe or we have (already) reset them, we can transmit the signal. 2856654de8547d2e420c20e21980669b807aa80710ephilippe 2866654de8547d2e420c20e21980669b807aa80710ephilippe If we have already set the registers of the inferior, we cannot 2876654de8547d2e420c20e21980669b807aa80710ephilippe transmit the signal, as this signal would arrive when the 2886654de8547d2e420c20e21980669b807aa80710ephilippe gdbserver code runs. And valgrind only expects signals to 2896654de8547d2e420c20e21980669b807aa80710ephilippe arrive in a small code portion around 2906654de8547d2e420c20e21980669b807aa80710ephilippe client syscall logic, where signal are unmasked (see e.g. 2916654de8547d2e420c20e21980669b807aa80710ephilippe m_syswrap/syscall-x86-linux.S ML_(do_syscall_for_client_WRK). 2926654de8547d2e420c20e21980669b807aa80710ephilippe 2936654de8547d2e420c20e21980669b807aa80710ephilippe As ptrace is forcing a call to gdbserver by jumping 2946654de8547d2e420c20e21980669b807aa80710ephilippe 'out of this region', signals are not masked, but 2956654de8547d2e420c20e21980669b807aa80710ephilippe will arrive outside of the allowed/expected code region. 2966654de8547d2e420c20e21980669b807aa80710ephilippe So, if we have changed the registers of the inferior, we 2976654de8547d2e420c20e21980669b807aa80710ephilippe rather queue the signal to transmit them when detaching, 2986654de8547d2e420c20e21980669b807aa80710ephilippe after having restored the registers to the initial values. */ 2996654de8547d2e420c20e21980669b807aa80710ephilippe if (pid_of_save_regs) { 3006654de8547d2e420c20e21980669b807aa80710ephilippe siginfo_t *newsiginfo; 3016654de8547d2e420c20e21980669b807aa80710ephilippe 3026654de8547d2e420c20e21980669b807aa80710ephilippe // realloc a bigger queue, and store new signal at the end. 3036654de8547d2e420c20e21980669b807aa80710ephilippe // This is not very efficient but we assume not many sigs are queued. 3046654de8547d2e420c20e21980669b807aa80710ephilippe signal_queue_sz++; 3054769c3c0594bb0cbfd31a953ed39dafbe108605cphilippe signal_queue = vrealloc(signal_queue, 3064769c3c0594bb0cbfd31a953ed39dafbe108605cphilippe sizeof(siginfo_t) * signal_queue_sz); 3076654de8547d2e420c20e21980669b807aa80710ephilippe newsiginfo = signal_queue + (signal_queue_sz - 1); 3086654de8547d2e420c20e21980669b807aa80710ephilippe 3096654de8547d2e420c20e21980669b807aa80710ephilippe res = ptrace (PTRACE_GETSIGINFO, pid, NULL, newsiginfo); 3106654de8547d2e420c20e21980669b807aa80710ephilippe if (res != 0) { 3116654de8547d2e420c20e21980669b807aa80710ephilippe ERROR(errno, "PTRACE_GETSIGINFO failed: signal lost !!!!\n"); 3126654de8547d2e420c20e21980669b807aa80710ephilippe signal_queue_sz--; 3136654de8547d2e420c20e21980669b807aa80710ephilippe } else 3146654de8547d2e420c20e21980669b807aa80710ephilippe DEBUG(1, "waitstopped PTRACE_CONT, queuing signal %d" 3156654de8547d2e420c20e21980669b807aa80710ephilippe " si_signo %d si_pid %d\n", 3166654de8547d2e420c20e21980669b807aa80710ephilippe signal_received, newsiginfo->si_signo, newsiginfo->si_pid); 3176654de8547d2e420c20e21980669b807aa80710ephilippe res = ptrace (PTRACE_CONT, pid, NULL, 0); 3186654de8547d2e420c20e21980669b807aa80710ephilippe } else { 3196654de8547d2e420c20e21980669b807aa80710ephilippe DEBUG(1, "waitstopped PTRACE_CONT with signal %d\n", signal_received); 3206654de8547d2e420c20e21980669b807aa80710ephilippe res = ptrace (PTRACE_CONT, pid, NULL, signal_received); 3216654de8547d2e420c20e21980669b807aa80710ephilippe } 3223c761f0f0344757ac243c65511392fb41d1c841aphilippe if (res != 0) { 3233c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(errno, "waitstopped PTRACE_CONT\n"); 3243c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 3253c761f0f0344757ac243c65511392fb41d1c841aphilippe } 3263c761f0f0344757ac243c65511392fb41d1c841aphilippe } 3273c761f0f0344757ac243c65511392fb41d1c841aphilippe 3283c761f0f0344757ac243c65511392fb41d1c841aphilippe return True; 3293c761f0f0344757ac243c65511392fb41d1c841aphilippe} 3303c761f0f0344757ac243c65511392fb41d1c841aphilippe 3313c761f0f0344757ac243c65511392fb41d1c841aphilippe/* Stops the given pid, wait for the process to be stopped. 3323c761f0f0344757ac243c65511392fb41d1c841aphilippe Returns True if succesful, False otherwise. 3333c761f0f0344757ac243c65511392fb41d1c841aphilippe msg is used in tracing and error reporting. */ 3343c761f0f0344757ac243c65511392fb41d1c841aphilippestatic 3353c761f0f0344757ac243c65511392fb41d1c841aphilippeBool stop (pid_t pid, const char *msg) 3363c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 3373c761f0f0344757ac243c65511392fb41d1c841aphilippe long res; 3383c761f0f0344757ac243c65511392fb41d1c841aphilippe 3393c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "%s SIGSTOP pid %d\n", msg, pid); 3403c761f0f0344757ac243c65511392fb41d1c841aphilippe res = kill (pid, SIGSTOP); 3413c761f0f0344757ac243c65511392fb41d1c841aphilippe if (res != 0) { 3423c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(errno, "%s SIGSTOP pid %d %ld\n", msg, pid, res); 3433c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 3443c761f0f0344757ac243c65511392fb41d1c841aphilippe } 3453c761f0f0344757ac243c65511392fb41d1c841aphilippe 3463c761f0f0344757ac243c65511392fb41d1c841aphilippe return waitstopped (pid, SIGSTOP, msg); 3473c761f0f0344757ac243c65511392fb41d1c841aphilippe 3483c761f0f0344757ac243c65511392fb41d1c841aphilippe} 3493c761f0f0344757ac243c65511392fb41d1c841aphilippe 3503c761f0f0344757ac243c65511392fb41d1c841aphilippe/* Attaches to given pid, wait for the process to be stopped. 3513c761f0f0344757ac243c65511392fb41d1c841aphilippe Returns True if succesful, False otherwise. 3523c761f0f0344757ac243c65511392fb41d1c841aphilippe msg is used in tracing and error reporting. */ 3533c761f0f0344757ac243c65511392fb41d1c841aphilippestatic 3543c761f0f0344757ac243c65511392fb41d1c841aphilippeBool attach (pid_t pid, const char *msg) 3553c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 3563c761f0f0344757ac243c65511392fb41d1c841aphilippe long res; 3573c761f0f0344757ac243c65511392fb41d1c841aphilippe static Bool output_error = True; 3583c761f0f0344757ac243c65511392fb41d1c841aphilippe static Bool initial_attach = True; 3593c761f0f0344757ac243c65511392fb41d1c841aphilippe // For a ptrace_scope protected system, we do not want to output 3603c761f0f0344757ac243c65511392fb41d1c841aphilippe // repetitively attach error. We will output once an error 3613c761f0f0344757ac243c65511392fb41d1c841aphilippe // for the initial_attach. Once the 1st attach has succeeded, we 3623c761f0f0344757ac243c65511392fb41d1c841aphilippe // again show all errors. 3633c761f0f0344757ac243c65511392fb41d1c841aphilippe 3643c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "%s PTRACE_ATTACH pid %d\n", msg, pid); 3653c761f0f0344757ac243c65511392fb41d1c841aphilippe res = ptrace (PTRACE_ATTACH, pid, NULL, NULL); 3663c761f0f0344757ac243c65511392fb41d1c841aphilippe if (res != 0) { 3673c761f0f0344757ac243c65511392fb41d1c841aphilippe if (output_error || debuglevel > 0) { 3683c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(errno, "%s PTRACE_ATTACH pid %d %ld\n", msg, pid, res); 3693c761f0f0344757ac243c65511392fb41d1c841aphilippe if (initial_attach) 3703c761f0f0344757ac243c65511392fb41d1c841aphilippe output_error = False; 3713c761f0f0344757ac243c65511392fb41d1c841aphilippe } 3723c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 3733c761f0f0344757ac243c65511392fb41d1c841aphilippe } 3743c761f0f0344757ac243c65511392fb41d1c841aphilippe 3753c761f0f0344757ac243c65511392fb41d1c841aphilippe initial_attach = False; 3763c761f0f0344757ac243c65511392fb41d1c841aphilippe output_error = True; 3773c761f0f0344757ac243c65511392fb41d1c841aphilippe return waitstopped(pid, SIGSTOP, msg); 3783c761f0f0344757ac243c65511392fb41d1c841aphilippe} 3793c761f0f0344757ac243c65511392fb41d1c841aphilippe 3803c761f0f0344757ac243c65511392fb41d1c841aphilippe/* once we are attached to the pid, get the list of threads and stop 3813c761f0f0344757ac243c65511392fb41d1c841aphilippe them all. 3823c761f0f0344757ac243c65511392fb41d1c841aphilippe Returns True if all threads properly suspended, False otherwise. */ 3833c761f0f0344757ac243c65511392fb41d1c841aphilippestatic 3843c761f0f0344757ac243c65511392fb41d1c841aphilippeBool acquire_and_suspend_threads (pid_t pid) 3853c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 3863c761f0f0344757ac243c65511392fb41d1c841aphilippe int i; 3873c761f0f0344757ac243c65511392fb41d1c841aphilippe int rw; 3883c761f0f0344757ac243c65511392fb41d1c841aphilippe Bool pid_found = False; 3893c761f0f0344757ac243c65511392fb41d1c841aphilippe Addr vgt; 3903c761f0f0344757ac243c65511392fb41d1c841aphilippe int sz_tst; 3913c761f0f0344757ac243c65511392fb41d1c841aphilippe int off_status; 3923c761f0f0344757ac243c65511392fb41d1c841aphilippe int off_lwpid; 3933c761f0f0344757ac243c65511392fb41d1c841aphilippe int nr_live_threads = 0; 3943c761f0f0344757ac243c65511392fb41d1c841aphilippe 3953c761f0f0344757ac243c65511392fb41d1c841aphilippe if (shared32 != NULL) { 3963c761f0f0344757ac243c65511392fb41d1c841aphilippe vgt = shared32->threads; 397b12f502f96dee3ead809420943ce5386ded4775aphilippe vg_n_threads = shared32->vg_n_threads; 3983c761f0f0344757ac243c65511392fb41d1c841aphilippe sz_tst = shared32->sizeof_ThreadState; 3993c761f0f0344757ac243c65511392fb41d1c841aphilippe off_status = shared32->offset_status; 4003c761f0f0344757ac243c65511392fb41d1c841aphilippe off_lwpid = shared32->offset_lwpid; 4013c761f0f0344757ac243c65511392fb41d1c841aphilippe } 4023c761f0f0344757ac243c65511392fb41d1c841aphilippe else if (shared64 != NULL) { 4033c761f0f0344757ac243c65511392fb41d1c841aphilippe vgt = shared64->threads; 404b12f502f96dee3ead809420943ce5386ded4775aphilippe vg_n_threads = shared64->vg_n_threads; 4053c761f0f0344757ac243c65511392fb41d1c841aphilippe sz_tst = shared64->sizeof_ThreadState; 4063c761f0f0344757ac243c65511392fb41d1c841aphilippe off_status = shared64->offset_status; 4073c761f0f0344757ac243c65511392fb41d1c841aphilippe off_lwpid = shared64->offset_lwpid; 4083c761f0f0344757ac243c65511392fb41d1c841aphilippe } else { 4093c761f0f0344757ac243c65511392fb41d1c841aphilippe assert (0); 4103c761f0f0344757ac243c65511392fb41d1c841aphilippe } 4113c761f0f0344757ac243c65511392fb41d1c841aphilippe 412b12f502f96dee3ead809420943ce5386ded4775aphilippe vgdb_threads = vmalloc(vg_n_threads * sizeof vgdb_threads[0]); 413b12f502f96dee3ead809420943ce5386ded4775aphilippe 4143c761f0f0344757ac243c65511392fb41d1c841aphilippe /* note: the entry 0 is unused */ 415b12f502f96dee3ead809420943ce5386ded4775aphilippe DEBUG(1, "examining thread entries from tid 1 to tid %d\n", vg_n_threads-1); 416b12f502f96dee3ead809420943ce5386ded4775aphilippe for (i = 1; i < vg_n_threads; i++) { 4173c761f0f0344757ac243c65511392fb41d1c841aphilippe vgt += sz_tst; 4183c761f0f0344757ac243c65511392fb41d1c841aphilippe rw = ptrace_read_memory(pid, vgt+off_status, 4193c761f0f0344757ac243c65511392fb41d1c841aphilippe &(vgdb_threads[i].status), 4203c761f0f0344757ac243c65511392fb41d1c841aphilippe sizeof(ThreadStatus)); 4213c761f0f0344757ac243c65511392fb41d1c841aphilippe if (rw != 0) { 4223c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(rw, "status ptrace_read_memory\n"); 4233c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 4243c761f0f0344757ac243c65511392fb41d1c841aphilippe } 4253c761f0f0344757ac243c65511392fb41d1c841aphilippe 4263c761f0f0344757ac243c65511392fb41d1c841aphilippe rw = ptrace_read_memory(pid, vgt+off_lwpid, 4273c761f0f0344757ac243c65511392fb41d1c841aphilippe &(vgdb_threads[i].lwpid), 4283c761f0f0344757ac243c65511392fb41d1c841aphilippe sizeof(Int)); 4293c761f0f0344757ac243c65511392fb41d1c841aphilippe if (rw != 0) { 4303c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(rw, "lwpid ptrace_read_memory\n"); 4313c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 4323c761f0f0344757ac243c65511392fb41d1c841aphilippe } 4333c761f0f0344757ac243c65511392fb41d1c841aphilippe 4343c761f0f0344757ac243c65511392fb41d1c841aphilippe if (vgdb_threads[i].status != VgTs_Empty) { 4353c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "found tid %d status %s lwpid %d\n", 4363c761f0f0344757ac243c65511392fb41d1c841aphilippe i, name_of_ThreadStatus(vgdb_threads[i].status), 4373c761f0f0344757ac243c65511392fb41d1c841aphilippe vgdb_threads[i].lwpid); 4383c761f0f0344757ac243c65511392fb41d1c841aphilippe nr_live_threads++; 4393c761f0f0344757ac243c65511392fb41d1c841aphilippe if (vgdb_threads[i].lwpid <= 1) { 4403c761f0f0344757ac243c65511392fb41d1c841aphilippe if (vgdb_threads[i].lwpid == 0 4413c761f0f0344757ac243c65511392fb41d1c841aphilippe && vgdb_threads[i].status == VgTs_Init) { 4423c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "not set lwpid tid %d status %s lwpid %d\n", 4433c761f0f0344757ac243c65511392fb41d1c841aphilippe i, name_of_ThreadStatus(vgdb_threads[i].status), 4443c761f0f0344757ac243c65511392fb41d1c841aphilippe vgdb_threads[i].lwpid); 4453c761f0f0344757ac243c65511392fb41d1c841aphilippe } else { 4463c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(1, "unexpected lwpid tid %d status %s lwpid %d\n", 4473c761f0f0344757ac243c65511392fb41d1c841aphilippe i, name_of_ThreadStatus(vgdb_threads[i].status), 4483c761f0f0344757ac243c65511392fb41d1c841aphilippe vgdb_threads[i].lwpid); 4493c761f0f0344757ac243c65511392fb41d1c841aphilippe } 4503c761f0f0344757ac243c65511392fb41d1c841aphilippe /* in case we have a VtTs_Init thread with lwpid not yet set, 4513c761f0f0344757ac243c65511392fb41d1c841aphilippe we try again later. */ 4523c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 4533c761f0f0344757ac243c65511392fb41d1c841aphilippe } 4543c761f0f0344757ac243c65511392fb41d1c841aphilippe if (vgdb_threads[i].lwpid == pid) { 4553c761f0f0344757ac243c65511392fb41d1c841aphilippe assert (!pid_found); 4563c761f0f0344757ac243c65511392fb41d1c841aphilippe assert (i == 1); 4573c761f0f0344757ac243c65511392fb41d1c841aphilippe pid_found = True; 4583c761f0f0344757ac243c65511392fb41d1c841aphilippe } else { 4593c761f0f0344757ac243c65511392fb41d1c841aphilippe if (!attach(vgdb_threads[i].lwpid, "attach_thread")) { 4603c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(0, "ERROR attach pid %d tid %d\n", 4613c761f0f0344757ac243c65511392fb41d1c841aphilippe vgdb_threads[i].lwpid, i); 4623c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 4633c761f0f0344757ac243c65511392fb41d1c841aphilippe } 4643c761f0f0344757ac243c65511392fb41d1c841aphilippe } 4653c761f0f0344757ac243c65511392fb41d1c841aphilippe } 4663c761f0f0344757ac243c65511392fb41d1c841aphilippe } 4673c761f0f0344757ac243c65511392fb41d1c841aphilippe /* If we found no thread, it means the process is stopping, and 4683c761f0f0344757ac243c65511392fb41d1c841aphilippe we better do not force anything to happen during that. */ 4693c761f0f0344757ac243c65511392fb41d1c841aphilippe if (nr_live_threads > 0) 4703c761f0f0344757ac243c65511392fb41d1c841aphilippe return True; 4713c761f0f0344757ac243c65511392fb41d1c841aphilippe else 4723c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 4733c761f0f0344757ac243c65511392fb41d1c841aphilippe} 4743c761f0f0344757ac243c65511392fb41d1c841aphilippe 4753c761f0f0344757ac243c65511392fb41d1c841aphilippestatic 4763c761f0f0344757ac243c65511392fb41d1c841aphilippevoid detach_from_all_threads (pid_t pid) 4773c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 4783c761f0f0344757ac243c65511392fb41d1c841aphilippe int i; 4793c761f0f0344757ac243c65511392fb41d1c841aphilippe long res; 4803c761f0f0344757ac243c65511392fb41d1c841aphilippe Bool pid_found = False; 4813c761f0f0344757ac243c65511392fb41d1c841aphilippe 4823c761f0f0344757ac243c65511392fb41d1c841aphilippe /* detach from all the threads */ 483b12f502f96dee3ead809420943ce5386ded4775aphilippe for (i = 1; i < vg_n_threads; i++) { 4843c761f0f0344757ac243c65511392fb41d1c841aphilippe if (vgdb_threads[i].status != VgTs_Empty) { 4853c761f0f0344757ac243c65511392fb41d1c841aphilippe if (vgdb_threads[i].status == VgTs_Init 4863c761f0f0344757ac243c65511392fb41d1c841aphilippe && vgdb_threads[i].lwpid == 0) { 4873c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "skipping PTRACE_DETACH pid %d tid %d status %s\n", 4883c761f0f0344757ac243c65511392fb41d1c841aphilippe vgdb_threads[i].lwpid, i, 4893c761f0f0344757ac243c65511392fb41d1c841aphilippe name_of_ThreadStatus (vgdb_threads[i].status)); 4903c761f0f0344757ac243c65511392fb41d1c841aphilippe } else { 4913c761f0f0344757ac243c65511392fb41d1c841aphilippe if (vgdb_threads[i].lwpid == pid) { 4923c761f0f0344757ac243c65511392fb41d1c841aphilippe assert (!pid_found); 4933c761f0f0344757ac243c65511392fb41d1c841aphilippe pid_found = True; 4943c761f0f0344757ac243c65511392fb41d1c841aphilippe } 4953c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "PTRACE_DETACH pid %d tid %d status %s\n", 4963c761f0f0344757ac243c65511392fb41d1c841aphilippe vgdb_threads[i].lwpid, i, 4973c761f0f0344757ac243c65511392fb41d1c841aphilippe name_of_ThreadStatus (vgdb_threads[i].status)); 4983c761f0f0344757ac243c65511392fb41d1c841aphilippe res = ptrace (PTRACE_DETACH, vgdb_threads[i].lwpid, NULL, NULL); 4993c761f0f0344757ac243c65511392fb41d1c841aphilippe if (res != 0) { 5003c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(errno, "PTRACE_DETACH pid %d tid %d status %s res %ld\n", 5013c761f0f0344757ac243c65511392fb41d1c841aphilippe vgdb_threads[i].lwpid, i, 5023c761f0f0344757ac243c65511392fb41d1c841aphilippe name_of_ThreadStatus (vgdb_threads[i].status), 5033c761f0f0344757ac243c65511392fb41d1c841aphilippe res); 5043c761f0f0344757ac243c65511392fb41d1c841aphilippe } 5053c761f0f0344757ac243c65511392fb41d1c841aphilippe } 5063c761f0f0344757ac243c65511392fb41d1c841aphilippe } 5073c761f0f0344757ac243c65511392fb41d1c841aphilippe } 5083c761f0f0344757ac243c65511392fb41d1c841aphilippe 509b12f502f96dee3ead809420943ce5386ded4775aphilippe free (vgdb_threads); 510b12f502f96dee3ead809420943ce5386ded4775aphilippe 5113c761f0f0344757ac243c65511392fb41d1c841aphilippe if (!pid_found && pid) { 5123c761f0f0344757ac243c65511392fb41d1c841aphilippe /* No threads are live. Process is busy stopping. 5133c761f0f0344757ac243c65511392fb41d1c841aphilippe We need to detach from pid explicitely. */ 5143c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "no thread live => PTRACE_DETACH pid %d\n", pid); 5153c761f0f0344757ac243c65511392fb41d1c841aphilippe res = ptrace (PTRACE_DETACH, pid, NULL, NULL); 5163c761f0f0344757ac243c65511392fb41d1c841aphilippe if (res != 0) 5173c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(errno, "PTRACE_DETACH pid %d res %ld\n", pid, res); 5183c761f0f0344757ac243c65511392fb41d1c841aphilippe } 5193c761f0f0344757ac243c65511392fb41d1c841aphilippe} 5203c761f0f0344757ac243c65511392fb41d1c841aphilippe 521112711afefcfcd43680c7c4aa8d38ef180e8811esewardj# if defined(VGA_arm64) || defined(VGA_tilegx) 5222a429f5d70a41ab1673c9f2ec220e8a10d8c90d5mjw/* arm64 is extra special, old glibc defined kernel user_pt_regs, but 5232a429f5d70a41ab1673c9f2ec220e8a10d8c90d5mjw newer glibc instead define user_regs_struct. */ 5242a429f5d70a41ab1673c9f2ec220e8a10d8c90d5mjw# ifdef HAVE_SYS_USER_REGS 5252a429f5d70a41ab1673c9f2ec220e8a10d8c90d5mjwstatic struct user_regs_struct user_save; 5262a429f5d70a41ab1673c9f2ec220e8a10d8c90d5mjw# else 527c07369bc8be6f6a26adfdbe391be7fe64a211829philippestatic struct user_pt_regs user_save; 5282a429f5d70a41ab1673c9f2ec220e8a10d8c90d5mjw# endif 529c07369bc8be6f6a26adfdbe391be7fe64a211829philippe# else 5303c761f0f0344757ac243c65511392fb41d1c841aphilippestatic struct user user_save; 531c07369bc8be6f6a26adfdbe391be7fe64a211829philippe# endif 5323c761f0f0344757ac243c65511392fb41d1c841aphilippe// The below indicates if ptrace_getregs (and ptrace_setregs) can be used. 5333c761f0f0344757ac243c65511392fb41d1c841aphilippe// Note that some linux versions are defining PTRACE_GETREGS but using 5343c761f0f0344757ac243c65511392fb41d1c841aphilippe// it gives back EIO. 5353c761f0f0344757ac243c65511392fb41d1c841aphilippe// has_working_ptrace_getregs can take the following values: 5363c761f0f0344757ac243c65511392fb41d1c841aphilippe// -1 : PTRACE_GETREGS is defined 5373c761f0f0344757ac243c65511392fb41d1c841aphilippe// runtime check not yet done. 5383c761f0f0344757ac243c65511392fb41d1c841aphilippe// 0 : PTRACE_GETREGS runtime check has failed. 5393c761f0f0344757ac243c65511392fb41d1c841aphilippe// 1 : PTRACE_GETREGS defined and runtime check ok. 5403c761f0f0344757ac243c65511392fb41d1c841aphilippe#ifdef HAVE_PTRACE_GETREGS 5413c761f0f0344757ac243c65511392fb41d1c841aphilippestatic int has_working_ptrace_getregs = -1; 5423c761f0f0344757ac243c65511392fb41d1c841aphilippe#endif 543c07369bc8be6f6a26adfdbe391be7fe64a211829philippe// Similar but for PTRACE_GETREGSET 544c07369bc8be6f6a26adfdbe391be7fe64a211829philippe#ifdef HAVE_PTRACE_GETREGSET 545c07369bc8be6f6a26adfdbe391be7fe64a211829philippestatic int has_working_ptrace_getregset = -1; 546c07369bc8be6f6a26adfdbe391be7fe64a211829philippe#endif 5473c761f0f0344757ac243c65511392fb41d1c841aphilippe 5483c761f0f0344757ac243c65511392fb41d1c841aphilippe/* Get the registers from pid into regs. 5493c761f0f0344757ac243c65511392fb41d1c841aphilippe regs_bsz value gives the length of *regs. 5503c761f0f0344757ac243c65511392fb41d1c841aphilippe Returns True if all ok, otherwise False. */ 5513c761f0f0344757ac243c65511392fb41d1c841aphilippestatic 5523c761f0f0344757ac243c65511392fb41d1c841aphilippeBool getregs (pid_t pid, void *regs, long regs_bsz) 5533c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 5543c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "getregs regs_bsz %ld\n", regs_bsz); 555c07369bc8be6f6a26adfdbe391be7fe64a211829philippe# ifdef HAVE_PTRACE_GETREGSET 556c07369bc8be6f6a26adfdbe391be7fe64a211829philippe# ifndef USE_PTRACE_GETREGSET 557c07369bc8be6f6a26adfdbe391be7fe64a211829philippe if (has_working_ptrace_getregset) 558c07369bc8be6f6a26adfdbe391be7fe64a211829philippe DEBUG(1, "PTRACE_GETREGSET defined, not used (yet?) by vgdb\n"); 559c07369bc8be6f6a26adfdbe391be7fe64a211829philippe has_working_ptrace_getregset = 0; 560c07369bc8be6f6a26adfdbe391be7fe64a211829philippe# endif 561c07369bc8be6f6a26adfdbe391be7fe64a211829philippe if (has_working_ptrace_getregset) { 562c07369bc8be6f6a26adfdbe391be7fe64a211829philippe // Platforms having GETREGSET 563c07369bc8be6f6a26adfdbe391be7fe64a211829philippe long res; 564c07369bc8be6f6a26adfdbe391be7fe64a211829philippe elf_gregset_t elf_regs; 565c07369bc8be6f6a26adfdbe391be7fe64a211829philippe struct iovec iovec; 566c07369bc8be6f6a26adfdbe391be7fe64a211829philippe 567ee0ee03c426c9712903cfa17cdca12bc6134807eflorian DEBUG(1, "getregs PTRACE_GETREGSET sizeof(elf_regs) %zu\n", 568ee0ee03c426c9712903cfa17cdca12bc6134807eflorian sizeof(elf_regs)); 569c07369bc8be6f6a26adfdbe391be7fe64a211829philippe iovec.iov_base = regs; 570c07369bc8be6f6a26adfdbe391be7fe64a211829philippe iovec.iov_len = sizeof(elf_regs); 571c07369bc8be6f6a26adfdbe391be7fe64a211829philippe 572c07369bc8be6f6a26adfdbe391be7fe64a211829philippe res = ptrace (PTRACE_GETREGSET, pid, NT_PRSTATUS, &iovec); 573c07369bc8be6f6a26adfdbe391be7fe64a211829philippe if (res == 0) { 574c07369bc8be6f6a26adfdbe391be7fe64a211829philippe if (has_working_ptrace_getregset == -1) { 575c07369bc8be6f6a26adfdbe391be7fe64a211829philippe // First call to PTRACE_GETREGSET succesful => 576c07369bc8be6f6a26adfdbe391be7fe64a211829philippe has_working_ptrace_getregset = 1; 577c07369bc8be6f6a26adfdbe391be7fe64a211829philippe DEBUG(1, "detected a working PTRACE_GETREGSET\n"); 578c07369bc8be6f6a26adfdbe391be7fe64a211829philippe } 579c07369bc8be6f6a26adfdbe391be7fe64a211829philippe assert (has_working_ptrace_getregset == 1); 580c07369bc8be6f6a26adfdbe391be7fe64a211829philippe return True; 581c07369bc8be6f6a26adfdbe391be7fe64a211829philippe } 582c07369bc8be6f6a26adfdbe391be7fe64a211829philippe else if (has_working_ptrace_getregset == 1) { 583c07369bc8be6f6a26adfdbe391be7fe64a211829philippe // We had a working call, but now it fails. 584c07369bc8be6f6a26adfdbe391be7fe64a211829philippe // This is unexpected. 585c07369bc8be6f6a26adfdbe391be7fe64a211829philippe ERROR(errno, "PTRACE_GETREGSET %ld\n", res); 586c07369bc8be6f6a26adfdbe391be7fe64a211829philippe return False; 587c07369bc8be6f6a26adfdbe391be7fe64a211829philippe } else { 588c07369bc8be6f6a26adfdbe391be7fe64a211829philippe // Check this is the first call: 589c07369bc8be6f6a26adfdbe391be7fe64a211829philippe assert (has_working_ptrace_getregset == -1); 590c07369bc8be6f6a26adfdbe391be7fe64a211829philippe if (errno == EIO) { 591c07369bc8be6f6a26adfdbe391be7fe64a211829philippe DEBUG(1, "detected a broken PTRACE_GETREGSET with EIO\n"); 592c07369bc8be6f6a26adfdbe391be7fe64a211829philippe has_working_ptrace_getregset = 0; 593c07369bc8be6f6a26adfdbe391be7fe64a211829philippe // Fall over to the PTRACE_GETREGS or PTRACE_PEEKUSER case. 594c07369bc8be6f6a26adfdbe391be7fe64a211829philippe } else { 595c07369bc8be6f6a26adfdbe391be7fe64a211829philippe ERROR(errno, "broken PTRACE_GETREGSET unexpected errno %ld\n", res); 596c07369bc8be6f6a26adfdbe391be7fe64a211829philippe return False; 597c07369bc8be6f6a26adfdbe391be7fe64a211829philippe } 598c07369bc8be6f6a26adfdbe391be7fe64a211829philippe } 599c07369bc8be6f6a26adfdbe391be7fe64a211829philippe } 600c07369bc8be6f6a26adfdbe391be7fe64a211829philippe# endif 601c07369bc8be6f6a26adfdbe391be7fe64a211829philippe 6023c761f0f0344757ac243c65511392fb41d1c841aphilippe# ifdef HAVE_PTRACE_GETREGS 6033c761f0f0344757ac243c65511392fb41d1c841aphilippe if (has_working_ptrace_getregs) { 6043c761f0f0344757ac243c65511392fb41d1c841aphilippe // Platforms having GETREGS 6053c761f0f0344757ac243c65511392fb41d1c841aphilippe long res; 6063c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "getregs PTRACE_GETREGS\n"); 6073c761f0f0344757ac243c65511392fb41d1c841aphilippe res = ptrace (PTRACE_GETREGS, pid, NULL, regs); 6083c761f0f0344757ac243c65511392fb41d1c841aphilippe if (res == 0) { 6093c761f0f0344757ac243c65511392fb41d1c841aphilippe if (has_working_ptrace_getregs == -1) { 6103c761f0f0344757ac243c65511392fb41d1c841aphilippe // First call to PTRACE_GETREGS succesful => 6113c761f0f0344757ac243c65511392fb41d1c841aphilippe has_working_ptrace_getregs = 1; 6123c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "detected a working PTRACE_GETREGS\n"); 6133c761f0f0344757ac243c65511392fb41d1c841aphilippe } 6143c761f0f0344757ac243c65511392fb41d1c841aphilippe assert (has_working_ptrace_getregs == 1); 6153c761f0f0344757ac243c65511392fb41d1c841aphilippe return True; 6163c761f0f0344757ac243c65511392fb41d1c841aphilippe } 6173c761f0f0344757ac243c65511392fb41d1c841aphilippe else if (has_working_ptrace_getregs == 1) { 6183c761f0f0344757ac243c65511392fb41d1c841aphilippe // We had a working call, but now it fails. 6193c761f0f0344757ac243c65511392fb41d1c841aphilippe // This is unexpected. 6203c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(errno, "PTRACE_GETREGS %ld\n", res); 6213c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 6223c761f0f0344757ac243c65511392fb41d1c841aphilippe } else { 6233c761f0f0344757ac243c65511392fb41d1c841aphilippe // Check this is the first call: 6243c761f0f0344757ac243c65511392fb41d1c841aphilippe assert (has_working_ptrace_getregs == -1); 6253c761f0f0344757ac243c65511392fb41d1c841aphilippe if (errno == EIO) { 6263c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "detected a broken PTRACE_GETREGS with EIO\n"); 6273c761f0f0344757ac243c65511392fb41d1c841aphilippe has_working_ptrace_getregs = 0; 6283c761f0f0344757ac243c65511392fb41d1c841aphilippe // Fall over to the PTRACE_PEEKUSER case. 6293c761f0f0344757ac243c65511392fb41d1c841aphilippe } else { 6303c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(errno, "broken PTRACE_GETREGS unexpected errno %ld\n", res); 6313c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 6323c761f0f0344757ac243c65511392fb41d1c841aphilippe } 6333c761f0f0344757ac243c65511392fb41d1c841aphilippe } 6343c761f0f0344757ac243c65511392fb41d1c841aphilippe } 6353c761f0f0344757ac243c65511392fb41d1c841aphilippe# endif 6363c761f0f0344757ac243c65511392fb41d1c841aphilippe 6373c761f0f0344757ac243c65511392fb41d1c841aphilippe // We assume PTRACE_PEEKUSER is defined everywhere. 6383c761f0f0344757ac243c65511392fb41d1c841aphilippe { 6393c761f0f0344757ac243c65511392fb41d1c841aphilippe# ifdef PT_ENDREGS 6403c761f0f0344757ac243c65511392fb41d1c841aphilippe long peek_bsz = PT_ENDREGS; 6413c761f0f0344757ac243c65511392fb41d1c841aphilippe assert (peek_bsz <= regs_bsz); 6423c761f0f0344757ac243c65511392fb41d1c841aphilippe# else 6433c761f0f0344757ac243c65511392fb41d1c841aphilippe long peek_bsz = regs_bsz-1; 6443c761f0f0344757ac243c65511392fb41d1c841aphilippe# endif 6453c761f0f0344757ac243c65511392fb41d1c841aphilippe char *pregs = (char *) regs; 6463c761f0f0344757ac243c65511392fb41d1c841aphilippe long offset; 6473c761f0f0344757ac243c65511392fb41d1c841aphilippe errno = 0; 6483c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "getregs PTRACE_PEEKUSER(s) peek_bsz %ld\n", peek_bsz); 6493c761f0f0344757ac243c65511392fb41d1c841aphilippe for (offset = 0; offset < peek_bsz; offset = offset + sizeof(long)) { 6503c761f0f0344757ac243c65511392fb41d1c841aphilippe *(long *)(pregs+offset) = ptrace(PTRACE_PEEKUSER, pid, offset, NULL); 6513c761f0f0344757ac243c65511392fb41d1c841aphilippe if (errno != 0) { 6523c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(errno, "PTRACE_PEEKUSER offset %ld\n", offset); 6533c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 6543c761f0f0344757ac243c65511392fb41d1c841aphilippe } 6553c761f0f0344757ac243c65511392fb41d1c841aphilippe } 6563c761f0f0344757ac243c65511392fb41d1c841aphilippe return True; 6573c761f0f0344757ac243c65511392fb41d1c841aphilippe } 6583c761f0f0344757ac243c65511392fb41d1c841aphilippe 659c07369bc8be6f6a26adfdbe391be7fe64a211829philippe // If neither of PTRACE_GETREGSET PTRACE_GETREGS PTRACE_PEEKUSER have 660c07369bc8be6f6a26adfdbe391be7fe64a211829philippe // returned, then we are in serious trouble. 6613c761f0f0344757ac243c65511392fb41d1c841aphilippe assert (0); 6623c761f0f0344757ac243c65511392fb41d1c841aphilippe} 6633c761f0f0344757ac243c65511392fb41d1c841aphilippe 6643c761f0f0344757ac243c65511392fb41d1c841aphilippe/* Set the registers of pid to regs. 6653c761f0f0344757ac243c65511392fb41d1c841aphilippe regs_bsz value gives the length of *regs. 6663c761f0f0344757ac243c65511392fb41d1c841aphilippe Returns True if all ok, otherwise False. */ 6673c761f0f0344757ac243c65511392fb41d1c841aphilippestatic 6683c761f0f0344757ac243c65511392fb41d1c841aphilippeBool setregs (pid_t pid, void *regs, long regs_bsz) 6693c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 6703c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "setregs regs_bsz %ld\n", regs_bsz); 671c07369bc8be6f6a26adfdbe391be7fe64a211829philippe 672c07369bc8be6f6a26adfdbe391be7fe64a211829philippe// Note : the below is checking for GETREGSET, not SETREGSET 673c07369bc8be6f6a26adfdbe391be7fe64a211829philippe// as if one is defined and working, the other one should also work. 674c07369bc8be6f6a26adfdbe391be7fe64a211829philippe# ifdef HAVE_PTRACE_GETREGSET 675c07369bc8be6f6a26adfdbe391be7fe64a211829philippe if (has_working_ptrace_getregset) { 676c07369bc8be6f6a26adfdbe391be7fe64a211829philippe // Platforms having SETREGSET 677c07369bc8be6f6a26adfdbe391be7fe64a211829philippe long res; 678c07369bc8be6f6a26adfdbe391be7fe64a211829philippe elf_gregset_t elf_regs; 679c07369bc8be6f6a26adfdbe391be7fe64a211829philippe struct iovec iovec; 680c07369bc8be6f6a26adfdbe391be7fe64a211829philippe 681c07369bc8be6f6a26adfdbe391be7fe64a211829philippe // setregset can never be called before getregset has done a runtime check. 682c07369bc8be6f6a26adfdbe391be7fe64a211829philippe assert (has_working_ptrace_getregset == 1); 683ee0ee03c426c9712903cfa17cdca12bc6134807eflorian DEBUG(1, "setregs PTRACE_SETREGSET sizeof(elf_regs) %zu\n", 684ee0ee03c426c9712903cfa17cdca12bc6134807eflorian sizeof(elf_regs)); 685c07369bc8be6f6a26adfdbe391be7fe64a211829philippe iovec.iov_base = regs; 686c07369bc8be6f6a26adfdbe391be7fe64a211829philippe iovec.iov_len = sizeof(elf_regs); 687c07369bc8be6f6a26adfdbe391be7fe64a211829philippe res = ptrace (PTRACE_SETREGSET, pid, NT_PRSTATUS, &iovec); 688c07369bc8be6f6a26adfdbe391be7fe64a211829philippe if (res != 0) { 689c07369bc8be6f6a26adfdbe391be7fe64a211829philippe ERROR(errno, "PTRACE_SETREGSET %ld\n", res); 690c07369bc8be6f6a26adfdbe391be7fe64a211829philippe return False; 691c07369bc8be6f6a26adfdbe391be7fe64a211829philippe } 692c07369bc8be6f6a26adfdbe391be7fe64a211829philippe return True; 693c07369bc8be6f6a26adfdbe391be7fe64a211829philippe } 694c07369bc8be6f6a26adfdbe391be7fe64a211829philippe# endif 695c07369bc8be6f6a26adfdbe391be7fe64a211829philippe 6963c761f0f0344757ac243c65511392fb41d1c841aphilippe// Note : the below is checking for GETREGS, not SETREGS 6973c761f0f0344757ac243c65511392fb41d1c841aphilippe// as if one is defined and working, the other one should also work. 6983c761f0f0344757ac243c65511392fb41d1c841aphilippe# ifdef HAVE_PTRACE_GETREGS 6993c761f0f0344757ac243c65511392fb41d1c841aphilippe if (has_working_ptrace_getregs) { 7003c761f0f0344757ac243c65511392fb41d1c841aphilippe // Platforms having SETREGS 7013c761f0f0344757ac243c65511392fb41d1c841aphilippe long res; 7023c761f0f0344757ac243c65511392fb41d1c841aphilippe // setregs can never be called before getregs has done a runtime check. 7033c761f0f0344757ac243c65511392fb41d1c841aphilippe assert (has_working_ptrace_getregs == 1); 7043c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "setregs PTRACE_SETREGS\n"); 7053c761f0f0344757ac243c65511392fb41d1c841aphilippe res = ptrace (PTRACE_SETREGS, pid, NULL, regs); 7063c761f0f0344757ac243c65511392fb41d1c841aphilippe if (res != 0) { 7073c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(errno, "PTRACE_SETREGS %ld\n", res); 7083c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 7093c761f0f0344757ac243c65511392fb41d1c841aphilippe } 7103c761f0f0344757ac243c65511392fb41d1c841aphilippe return True; 7113c761f0f0344757ac243c65511392fb41d1c841aphilippe } 7123c761f0f0344757ac243c65511392fb41d1c841aphilippe# endif 7133c761f0f0344757ac243c65511392fb41d1c841aphilippe 7143c761f0f0344757ac243c65511392fb41d1c841aphilippe { 7153c761f0f0344757ac243c65511392fb41d1c841aphilippe char *pregs = (char *) regs; 7163c761f0f0344757ac243c65511392fb41d1c841aphilippe long offset; 7173c761f0f0344757ac243c65511392fb41d1c841aphilippe long res; 7183c761f0f0344757ac243c65511392fb41d1c841aphilippe# ifdef PT_ENDREGS 7193c761f0f0344757ac243c65511392fb41d1c841aphilippe long peek_bsz = PT_ENDREGS; 7203c761f0f0344757ac243c65511392fb41d1c841aphilippe assert (peek_bsz <= regs_bsz); 7213c761f0f0344757ac243c65511392fb41d1c841aphilippe# else 7223c761f0f0344757ac243c65511392fb41d1c841aphilippe long peek_bsz = regs_bsz-1; 7233c761f0f0344757ac243c65511392fb41d1c841aphilippe# endif 7243c761f0f0344757ac243c65511392fb41d1c841aphilippe errno = 0; 7253c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "setregs PTRACE_POKEUSER(s) %ld\n", peek_bsz); 7263c761f0f0344757ac243c65511392fb41d1c841aphilippe for (offset = 0; offset < peek_bsz; offset = offset + sizeof(long)) { 7273c761f0f0344757ac243c65511392fb41d1c841aphilippe res = ptrace(PTRACE_POKEUSER, pid, offset, *(long*)(pregs+offset)); 7283c761f0f0344757ac243c65511392fb41d1c841aphilippe if (errno != 0) { 7293c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(errno, "PTRACE_POKEUSER offset %ld res %ld\n", offset, res); 7303c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 7313c761f0f0344757ac243c65511392fb41d1c841aphilippe } 7323c761f0f0344757ac243c65511392fb41d1c841aphilippe } 7333c761f0f0344757ac243c65511392fb41d1c841aphilippe return True; 7343c761f0f0344757ac243c65511392fb41d1c841aphilippe } 7353c761f0f0344757ac243c65511392fb41d1c841aphilippe 7363c761f0f0344757ac243c65511392fb41d1c841aphilippe // If neither PTRACE_SETREGS not PTRACE_POKEUSER have returned, 7373c761f0f0344757ac243c65511392fb41d1c841aphilippe // then we are in serious trouble. 7383c761f0f0344757ac243c65511392fb41d1c841aphilippe assert (0); 7393c761f0f0344757ac243c65511392fb41d1c841aphilippe} 7403c761f0f0344757ac243c65511392fb41d1c841aphilippe 7413c761f0f0344757ac243c65511392fb41d1c841aphilippe/* Restore the registers to the saved value, then detaches from all threads */ 7423c761f0f0344757ac243c65511392fb41d1c841aphilippestatic 7433c761f0f0344757ac243c65511392fb41d1c841aphilippevoid restore_and_detach (pid_t pid) 7443c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 7456654de8547d2e420c20e21980669b807aa80710ephilippe int res; 7466654de8547d2e420c20e21980669b807aa80710ephilippe 7476654de8547d2e420c20e21980669b807aa80710ephilippe DEBUG(1, "restore_and_detach pid %d pid_of_save_regs %d\n", 7486654de8547d2e420c20e21980669b807aa80710ephilippe pid, pid_of_save_regs); 7496654de8547d2e420c20e21980669b807aa80710ephilippe 7503c761f0f0344757ac243c65511392fb41d1c841aphilippe if (pid_of_save_regs) { 7513c761f0f0344757ac243c65511392fb41d1c841aphilippe /* In case the 'main pid' has been continued, we need to stop it 7523c761f0f0344757ac243c65511392fb41d1c841aphilippe before resetting the registers. */ 7533c761f0f0344757ac243c65511392fb41d1c841aphilippe if (pid_of_save_regs_continued) { 7543c761f0f0344757ac243c65511392fb41d1c841aphilippe pid_of_save_regs_continued = False; 7553c761f0f0344757ac243c65511392fb41d1c841aphilippe if (!stop(pid_of_save_regs, "sigstop before reset regs")) 7563c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(0, "Could not sigstop before reset"); 7573c761f0f0344757ac243c65511392fb41d1c841aphilippe } 7583c761f0f0344757ac243c65511392fb41d1c841aphilippe 7593c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "setregs restore registers pid %d\n", pid_of_save_regs); 7603c761f0f0344757ac243c65511392fb41d1c841aphilippe if (!setregs(pid_of_save_regs, &user_save.regs, sizeof(user_save.regs))) { 7613c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(errno, "setregs restore registers pid %d after cont\n", 7623c761f0f0344757ac243c65511392fb41d1c841aphilippe pid_of_save_regs); 7633c761f0f0344757ac243c65511392fb41d1c841aphilippe } 7646654de8547d2e420c20e21980669b807aa80710ephilippe 7656654de8547d2e420c20e21980669b807aa80710ephilippe /* Now, we transmit all the signals we have queued. */ 7666654de8547d2e420c20e21980669b807aa80710ephilippe if (signal_queue_sz > 0) { 7676654de8547d2e420c20e21980669b807aa80710ephilippe int i; 7686654de8547d2e420c20e21980669b807aa80710ephilippe for (i = 0; i < signal_queue_sz; i++) { 7696654de8547d2e420c20e21980669b807aa80710ephilippe DEBUG(1, "PTRACE_CONT to transmit queued signal %d\n", 7706654de8547d2e420c20e21980669b807aa80710ephilippe signal_queue[i].si_signo); 7716654de8547d2e420c20e21980669b807aa80710ephilippe res = ptrace (PTRACE_CONT, pid_of_save_regs, NULL, 7726654de8547d2e420c20e21980669b807aa80710ephilippe signal_queue[i].si_signo); 7736654de8547d2e420c20e21980669b807aa80710ephilippe if (res != 0) 7746654de8547d2e420c20e21980669b807aa80710ephilippe ERROR(errno, "PTRACE_CONT with signal %d\n", 7756654de8547d2e420c20e21980669b807aa80710ephilippe signal_queue[i].si_signo); 7766654de8547d2e420c20e21980669b807aa80710ephilippe if (!stop(pid_of_save_regs, "sigstop after transmit sig")) 7776654de8547d2e420c20e21980669b807aa80710ephilippe DEBUG(0, "Could not sigstop after transmit sig"); 7786654de8547d2e420c20e21980669b807aa80710ephilippe } 7796654de8547d2e420c20e21980669b807aa80710ephilippe free (signal_queue); 7806654de8547d2e420c20e21980669b807aa80710ephilippe signal_queue = NULL; 7816654de8547d2e420c20e21980669b807aa80710ephilippe signal_queue_sz = 0; 7826654de8547d2e420c20e21980669b807aa80710ephilippe } 7833c761f0f0344757ac243c65511392fb41d1c841aphilippe pid_of_save_regs = 0; 7843c761f0f0344757ac243c65511392fb41d1c841aphilippe } else { 7853c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "PTRACE_SETREGS restore registers: no pid\n"); 7863c761f0f0344757ac243c65511392fb41d1c841aphilippe } 7876654de8547d2e420c20e21980669b807aa80710ephilippe if (signal_queue) 7886654de8547d2e420c20e21980669b807aa80710ephilippe ERROR (0, "One or more signals queued were not delivered. " 7897136e5f14ebcb8117f629becf48bc8a49ab0b5afcarll "First signal: %d\n", signal_queue[0].si_signo); 7903c761f0f0344757ac243c65511392fb41d1c841aphilippe detach_from_all_threads(pid); 7913c761f0f0344757ac243c65511392fb41d1c841aphilippe} 7923c761f0f0344757ac243c65511392fb41d1c841aphilippe 7933c761f0f0344757ac243c65511392fb41d1c841aphilippeBool invoker_invoke_gdbserver (pid_t pid) 7943c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 7953c761f0f0344757ac243c65511392fb41d1c841aphilippe long res; 7963c761f0f0344757ac243c65511392fb41d1c841aphilippe Bool stopped; 797112711afefcfcd43680c7c4aa8d38ef180e8811esewardj# if defined(VGA_arm64) || defined(VGA_tilegx) 7982a429f5d70a41ab1673c9f2ec220e8a10d8c90d5mjw/* arm64 is extra special, old glibc defined kernel user_pt_regs, but 7992a429f5d70a41ab1673c9f2ec220e8a10d8c90d5mjw newer glibc instead define user_regs_struct. */ 8002a429f5d70a41ab1673c9f2ec220e8a10d8c90d5mjw# ifdef HAVE_SYS_USER_REGS 8012a429f5d70a41ab1673c9f2ec220e8a10d8c90d5mjw struct user_regs_struct user_mod; 8022a429f5d70a41ab1673c9f2ec220e8a10d8c90d5mjw# else 803c07369bc8be6f6a26adfdbe391be7fe64a211829philippe struct user_pt_regs user_mod; 8042a429f5d70a41ab1673c9f2ec220e8a10d8c90d5mjw# endif 805c07369bc8be6f6a26adfdbe391be7fe64a211829philippe# else 8063c761f0f0344757ac243c65511392fb41d1c841aphilippe struct user user_mod; 807c07369bc8be6f6a26adfdbe391be7fe64a211829philippe# endif 8085f9116d2675ee30ebb894ce13bd4e7597567b363philippe Addr sp __attribute__((unused)); // Not used on all platforms. 8095f9116d2675ee30ebb894ce13bd4e7597567b363philippe 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]; 874112711afefcfcd43680c7c4aa8d38ef180e8811esewardj#elif defined(VGA_tilegx) 875112711afefcfcd43680c7c4aa8d38ef180e8811esewardj sp = user_mod.sp; 8763c761f0f0344757ac243c65511392fb41d1c841aphilippe#else 8774769c3c0594bb0cbfd31a953ed39dafbe108605cphilippe I_die_here : (sp) architecture missing in vgdb-invoker-ptrace.c 8783c761f0f0344757ac243c65511392fb41d1c841aphilippe#endif 8793c761f0f0344757ac243c65511392fb41d1c841aphilippe 8803c761f0f0344757ac243c65511392fb41d1c841aphilippe 8813c761f0f0344757ac243c65511392fb41d1c841aphilippe // the magic below is derived from spying what gdb sends to 8823c761f0f0344757ac243c65511392fb41d1c841aphilippe // the (classical) gdbserver when invoking a C function. 8833c761f0f0344757ac243c65511392fb41d1c841aphilippe if (shared32 != NULL) { 8843c761f0f0344757ac243c65511392fb41d1c841aphilippe // vgdb speaking with a 32bit executable. 8853c761f0f0344757ac243c65511392fb41d1c841aphilippe#if defined(VGA_x86) || defined(VGA_amd64) 8863c761f0f0344757ac243c65511392fb41d1c841aphilippe const int regsize = 4; 8873c761f0f0344757ac243c65511392fb41d1c841aphilippe int rw; 8883c761f0f0344757ac243c65511392fb41d1c841aphilippe /* push check arg on the stack */ 8893c761f0f0344757ac243c65511392fb41d1c841aphilippe sp = sp - regsize; 8903c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "push check arg ptrace_write_memory\n"); 8913c761f0f0344757ac243c65511392fb41d1c841aphilippe assert(regsize == sizeof(check)); 8923c761f0f0344757ac243c65511392fb41d1c841aphilippe rw = ptrace_write_memory(pid, sp, 8933c761f0f0344757ac243c65511392fb41d1c841aphilippe &check, 8943c761f0f0344757ac243c65511392fb41d1c841aphilippe regsize); 8953c761f0f0344757ac243c65511392fb41d1c841aphilippe if (rw != 0) { 8963c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(rw, "push check arg ptrace_write_memory"); 8973c761f0f0344757ac243c65511392fb41d1c841aphilippe detach_from_all_threads(pid); 8983c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 8993c761f0f0344757ac243c65511392fb41d1c841aphilippe } 9003c761f0f0344757ac243c65511392fb41d1c841aphilippe 9013c761f0f0344757ac243c65511392fb41d1c841aphilippe sp = sp - regsize; 9023c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "push bad_return return address ptrace_write_memory\n"); 9033c761f0f0344757ac243c65511392fb41d1c841aphilippe // Note that for a 64 bits vgdb, only 4 bytes of NULL bad_return 9043c761f0f0344757ac243c65511392fb41d1c841aphilippe // are written. 9053c761f0f0344757ac243c65511392fb41d1c841aphilippe rw = ptrace_write_memory(pid, sp, 9063c761f0f0344757ac243c65511392fb41d1c841aphilippe &bad_return, 9073c761f0f0344757ac243c65511392fb41d1c841aphilippe regsize); 9083c761f0f0344757ac243c65511392fb41d1c841aphilippe if (rw != 0) { 9093c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(rw, "push bad_return return address ptrace_write_memory"); 9103c761f0f0344757ac243c65511392fb41d1c841aphilippe detach_from_all_threads(pid); 9113c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 9123c761f0f0344757ac243c65511392fb41d1c841aphilippe } 9133c761f0f0344757ac243c65511392fb41d1c841aphilippe#if defined(VGA_x86) 9143c761f0f0344757ac243c65511392fb41d1c841aphilippe /* set ebp, esp, eip and orig_eax to invoke gdbserver */ 9153c761f0f0344757ac243c65511392fb41d1c841aphilippe // compiled in 32bits, speaking with a 32bits exe 9163c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.ebp = sp; // bp set to sp 9173c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.esp = sp; 9183c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.eip = shared32->invoke_gdbserver; 9193c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.orig_eax = -1L; 9203c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_amd64) 9213c761f0f0344757ac243c65511392fb41d1c841aphilippe /* set ebp, esp, eip and orig_eax to invoke gdbserver */ 9223c761f0f0344757ac243c65511392fb41d1c841aphilippe // compiled in 64bits, speaking with a 32bits exe 9233c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.rbp = sp; // bp set to sp 9243c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.rsp = sp; 9253c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.rip = shared32->invoke_gdbserver; 9263c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.orig_rax = -1L; 9273c761f0f0344757ac243c65511392fb41d1c841aphilippe#else 9283c761f0f0344757ac243c65511392fb41d1c841aphilippe I_die_here : not x86 or amd64 in x86/amd64 section/ 9293c761f0f0344757ac243c65511392fb41d1c841aphilippe#endif 9303c761f0f0344757ac243c65511392fb41d1c841aphilippe 931cae0cc22b83ffb260ee8379e92099c5a701944cbcarll#elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le) 9323c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.nip = shared32->invoke_gdbserver; 9333c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.trap = -1L; 9343c761f0f0344757ac243c65511392fb41d1c841aphilippe /* put check arg in register 3 */ 9353c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.gpr[3] = check; 9363c761f0f0344757ac243c65511392fb41d1c841aphilippe /* put NULL return address in Link Register */ 9373c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.link = bad_return; 9383c761f0f0344757ac243c65511392fb41d1c841aphilippe 9393c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_arm) 9403c761f0f0344757ac243c65511392fb41d1c841aphilippe /* put check arg in register 0 */ 9413c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.uregs[0] = check; 9423c761f0f0344757ac243c65511392fb41d1c841aphilippe /* put NULL return address in Link Register */ 9433c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.uregs[14] = bad_return; 9443c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.uregs[15] = shared32->invoke_gdbserver; 9453c761f0f0344757ac243c65511392fb41d1c841aphilippe 946c07369bc8be6f6a26adfdbe391be7fe64a211829philippe#elif defined(VGA_arm64) 947c07369bc8be6f6a26adfdbe391be7fe64a211829philippe XERROR(0, "TBD arm64: vgdb a 32 bits executable with a 64 bits exe"); 948c07369bc8be6f6a26adfdbe391be7fe64a211829philippe 9493c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_s390x) 9503c761f0f0344757ac243c65511392fb41d1c841aphilippe XERROR(0, "(fn32) s390x has no 32bits implementation"); 9513c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_mips32) 9523c761f0f0344757ac243c65511392fb41d1c841aphilippe /* put check arg in register 4 */ 9533c761f0f0344757ac243c65511392fb41d1c841aphilippe p[4] = check; 9543c761f0f0344757ac243c65511392fb41d1c841aphilippe /* put NULL return address in ra */ 9553c761f0f0344757ac243c65511392fb41d1c841aphilippe p[31] = bad_return; 9563c761f0f0344757ac243c65511392fb41d1c841aphilippe p[34] = shared32->invoke_gdbserver; 9573c761f0f0344757ac243c65511392fb41d1c841aphilippe p[25] = shared32->invoke_gdbserver; 9583c761f0f0344757ac243c65511392fb41d1c841aphilippe /* make stack space for args */ 9593c761f0f0344757ac243c65511392fb41d1c841aphilippe p[29] = sp - 32; 9603c761f0f0344757ac243c65511392fb41d1c841aphilippe 961112711afefcfcd43680c7c4aa8d38ef180e8811esewardj#elif defined(VGA_mips64) || defined(VGA_tilegx) 9623c761f0f0344757ac243c65511392fb41d1c841aphilippe assert(0); // cannot vgdb a 32 bits executable with a 64 bits exe 9633c761f0f0344757ac243c65511392fb41d1c841aphilippe#else 9644769c3c0594bb0cbfd31a953ed39dafbe108605cphilippe I_die_here : architecture missing in vgdb-invoker-ptrace.c 9653c761f0f0344757ac243c65511392fb41d1c841aphilippe#endif 9663c761f0f0344757ac243c65511392fb41d1c841aphilippe } 9673c761f0f0344757ac243c65511392fb41d1c841aphilippe 9683c761f0f0344757ac243c65511392fb41d1c841aphilippe else if (shared64 != NULL) { 9693c761f0f0344757ac243c65511392fb41d1c841aphilippe#if defined(VGA_x86) 9703c761f0f0344757ac243c65511392fb41d1c841aphilippe assert(0); // cannot vgdb a 64 bits executable with a 32 bits exe 9713c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_amd64) 9723c761f0f0344757ac243c65511392fb41d1c841aphilippe // vgdb speaking with a 64 bit executable. 9733c761f0f0344757ac243c65511392fb41d1c841aphilippe const int regsize = 8; 9743c761f0f0344757ac243c65511392fb41d1c841aphilippe int rw; 9753c761f0f0344757ac243c65511392fb41d1c841aphilippe 9763c761f0f0344757ac243c65511392fb41d1c841aphilippe /* give check arg in rdi */ 9773c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.rdi = check; 9783c761f0f0344757ac243c65511392fb41d1c841aphilippe 9793c761f0f0344757ac243c65511392fb41d1c841aphilippe /* push return address on stack : return to breakaddr */ 9803c761f0f0344757ac243c65511392fb41d1c841aphilippe sp = sp - regsize; 9813c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "push bad_return return address ptrace_write_memory\n"); 9823c761f0f0344757ac243c65511392fb41d1c841aphilippe rw = ptrace_write_memory(pid, sp, 9833c761f0f0344757ac243c65511392fb41d1c841aphilippe &bad_return, 9843c761f0f0344757ac243c65511392fb41d1c841aphilippe sizeof(bad_return)); 9853c761f0f0344757ac243c65511392fb41d1c841aphilippe if (rw != 0) { 9863c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(rw, "push bad_return return address ptrace_write_memory"); 9873c761f0f0344757ac243c65511392fb41d1c841aphilippe detach_from_all_threads(pid); 9883c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 9893c761f0f0344757ac243c65511392fb41d1c841aphilippe } 9903c761f0f0344757ac243c65511392fb41d1c841aphilippe 9913c761f0f0344757ac243c65511392fb41d1c841aphilippe /* set rbp, rsp, rip and orig_rax to invoke gdbserver */ 9923c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.rbp = sp; // bp set to sp 9933c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.rsp = sp; 9943c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.rip = shared64->invoke_gdbserver; 9953c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.orig_rax = -1L; 9963c761f0f0344757ac243c65511392fb41d1c841aphilippe 9973c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_arm) 9983c761f0f0344757ac243c65511392fb41d1c841aphilippe assert(0); // cannot vgdb a 64 bits executable with a 32 bits exe 999c07369bc8be6f6a26adfdbe391be7fe64a211829philippe#elif defined(VGA_arm64) 1000c07369bc8be6f6a26adfdbe391be7fe64a211829philippe user_mod.regs[0] = check; 1001c07369bc8be6f6a26adfdbe391be7fe64a211829philippe user_mod.sp = sp; 1002c07369bc8be6f6a26adfdbe391be7fe64a211829philippe user_mod.pc = shared64->invoke_gdbserver; 1003c07369bc8be6f6a26adfdbe391be7fe64a211829philippe /* put NULL return address in Link Register */ 1004c07369bc8be6f6a26adfdbe391be7fe64a211829philippe user_mod.regs[30] = bad_return; 1005c07369bc8be6f6a26adfdbe391be7fe64a211829philippe 10063c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_ppc32) 10073c761f0f0344757ac243c65511392fb41d1c841aphilippe assert(0); // cannot vgdb a 64 bits executable with a 32 bits exe 1008cae0cc22b83ffb260ee8379e92099c5a701944cbcarll#elif defined(VGA_ppc64be) 10094769c3c0594bb0cbfd31a953ed39dafbe108605cphilippe Addr func_addr; 10104769c3c0594bb0cbfd31a953ed39dafbe108605cphilippe Addr toc_addr; 10113c761f0f0344757ac243c65511392fb41d1c841aphilippe int rw; 10123c761f0f0344757ac243c65511392fb41d1c841aphilippe rw = ptrace_read_memory(pid, shared64->invoke_gdbserver, 10133c761f0f0344757ac243c65511392fb41d1c841aphilippe &func_addr, 10144769c3c0594bb0cbfd31a953ed39dafbe108605cphilippe sizeof(Addr)); 10153c761f0f0344757ac243c65511392fb41d1c841aphilippe if (rw != 0) { 10163c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(rw, "ppc64 read func_addr\n"); 10173c761f0f0344757ac243c65511392fb41d1c841aphilippe detach_from_all_threads(pid); 10183c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 10193c761f0f0344757ac243c65511392fb41d1c841aphilippe } 10203c761f0f0344757ac243c65511392fb41d1c841aphilippe rw = ptrace_read_memory(pid, shared64->invoke_gdbserver+8, 10213c761f0f0344757ac243c65511392fb41d1c841aphilippe &toc_addr, 10224769c3c0594bb0cbfd31a953ed39dafbe108605cphilippe sizeof(Addr)); 10233c761f0f0344757ac243c65511392fb41d1c841aphilippe if (rw != 0) { 10243c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(rw, "ppc64 read toc_addr\n"); 10253c761f0f0344757ac243c65511392fb41d1c841aphilippe detach_from_all_threads(pid); 10263c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 10273c761f0f0344757ac243c65511392fb41d1c841aphilippe } 10283c761f0f0344757ac243c65511392fb41d1c841aphilippe // We are not pushing anything on the stack, so it is not 10293c761f0f0344757ac243c65511392fb41d1c841aphilippe // very clear why the sp has to be decreased, but it seems 10303c761f0f0344757ac243c65511392fb41d1c841aphilippe // needed. The ppc64 ABI might give some lights on this ? 10313c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.gpr[1] = sp - 220; 10323c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.gpr[2] = toc_addr; 10333c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.nip = func_addr; 10343c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.trap = -1L; 10353c761f0f0344757ac243c65511392fb41d1c841aphilippe /* put check arg in register 3 */ 10363c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.gpr[3] = check; 10373c761f0f0344757ac243c65511392fb41d1c841aphilippe /* put bad_return return address in Link Register */ 10383c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.link = bad_return; 1039582d58245637ab05272d89fb94b12fd0f18fa0f8carll#elif defined(VGA_ppc64le) 1040582d58245637ab05272d89fb94b12fd0f18fa0f8carll /* LE does not use the function pointer structure used in BE */ 1041582d58245637ab05272d89fb94b12fd0f18fa0f8carll user_mod.regs.nip = shared64->invoke_gdbserver; 1042582d58245637ab05272d89fb94b12fd0f18fa0f8carll user_mod.regs.gpr[1] = sp - 512; 1043582d58245637ab05272d89fb94b12fd0f18fa0f8carll user_mod.regs.gpr[12] = user_mod.regs.nip; 1044582d58245637ab05272d89fb94b12fd0f18fa0f8carll user_mod.regs.trap = -1L; 1045582d58245637ab05272d89fb94b12fd0f18fa0f8carll /* put check arg in register 3 */ 1046582d58245637ab05272d89fb94b12fd0f18fa0f8carll user_mod.regs.gpr[3] = check; 1047582d58245637ab05272d89fb94b12fd0f18fa0f8carll /* put bad_return return address in Link Register */ 1048582d58245637ab05272d89fb94b12fd0f18fa0f8carll user_mod.regs.link = bad_return; 10493c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_s390x) 10503c761f0f0344757ac243c65511392fb41d1c841aphilippe /* put check arg in register r2 */ 10513c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.gprs[2] = check; 10523c761f0f0344757ac243c65511392fb41d1c841aphilippe /* bad_return Return address is in r14 */ 10533c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.gprs[14] = bad_return; 10543c761f0f0344757ac243c65511392fb41d1c841aphilippe /* minimum stack frame */ 10553c761f0f0344757ac243c65511392fb41d1c841aphilippe sp = sp - 160; 10563c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.gprs[15] = sp; 10573c761f0f0344757ac243c65511392fb41d1c841aphilippe /* set program counter */ 10583c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs.psw.addr = shared64->invoke_gdbserver; 10593c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_mips32) 10603c761f0f0344757ac243c65511392fb41d1c841aphilippe assert(0); // cannot vgdb a 64 bits executable with a 32 bits exe 10613c761f0f0344757ac243c65511392fb41d1c841aphilippe#elif defined(VGA_mips64) 10623c761f0f0344757ac243c65511392fb41d1c841aphilippe /* put check arg in register 4 */ 10633c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs[4] = check; 10643c761f0f0344757ac243c65511392fb41d1c841aphilippe /* put NULL return address in ra */ 10653c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs[31] = bad_return; 10663c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs[34] = shared64->invoke_gdbserver; 10673c761f0f0344757ac243c65511392fb41d1c841aphilippe user_mod.regs[25] = shared64->invoke_gdbserver; 1068112711afefcfcd43680c7c4aa8d38ef180e8811esewardj#elif defined(VGA_tilegx) 1069112711afefcfcd43680c7c4aa8d38ef180e8811esewardj /* put check arg in register r0 */ 1070112711afefcfcd43680c7c4aa8d38ef180e8811esewardj user_mod.regs[0] = check; 1071112711afefcfcd43680c7c4aa8d38ef180e8811esewardj /* put NULL return address in lr */ 1072112711afefcfcd43680c7c4aa8d38ef180e8811esewardj user_mod.lr = bad_return; 1073112711afefcfcd43680c7c4aa8d38ef180e8811esewardj user_mod.pc = shared64->invoke_gdbserver; 10743c761f0f0344757ac243c65511392fb41d1c841aphilippe#else 10754769c3c0594bb0cbfd31a953ed39dafbe108605cphilippe I_die_here: architecture missing in vgdb-invoker-ptrace.c 10763c761f0f0344757ac243c65511392fb41d1c841aphilippe#endif 10773c761f0f0344757ac243c65511392fb41d1c841aphilippe } 10783c761f0f0344757ac243c65511392fb41d1c841aphilippe else { 10793c761f0f0344757ac243c65511392fb41d1c841aphilippe assert(0); 10803c761f0f0344757ac243c65511392fb41d1c841aphilippe } 10813c761f0f0344757ac243c65511392fb41d1c841aphilippe 10823c761f0f0344757ac243c65511392fb41d1c841aphilippe if (!setregs(pid, &user_mod.regs, sizeof(user_mod.regs))) { 10833c761f0f0344757ac243c65511392fb41d1c841aphilippe detach_from_all_threads(pid); 10843c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 10853c761f0f0344757ac243c65511392fb41d1c841aphilippe } 10863c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Now that we have modified the registers, we set 10873c761f0f0344757ac243c65511392fb41d1c841aphilippe pid_of_save_regs to indicate that restore_and_detach 10883c761f0f0344757ac243c65511392fb41d1c841aphilippe must restore the registers in case of cleanup. */ 10893c761f0f0344757ac243c65511392fb41d1c841aphilippe pid_of_save_regs = pid; 10903c761f0f0344757ac243c65511392fb41d1c841aphilippe pid_of_save_regs_continued = False; 10913c761f0f0344757ac243c65511392fb41d1c841aphilippe 10923c761f0f0344757ac243c65511392fb41d1c841aphilippe 10933c761f0f0344757ac243c65511392fb41d1c841aphilippe /* We PTRACE_CONT-inue pid. 10943c761f0f0344757ac243c65511392fb41d1c841aphilippe Either gdbserver will be invoked directly (if all 10953c761f0f0344757ac243c65511392fb41d1c841aphilippe threads are interruptible) or gdbserver will be 10963c761f0f0344757ac243c65511392fb41d1c841aphilippe called soon by the scheduler. In the first case, 10973c761f0f0344757ac243c65511392fb41d1c841aphilippe pid will stop on the break inserted above when 10983c761f0f0344757ac243c65511392fb41d1c841aphilippe gdbserver returns. In the 2nd case, the break will 10993c761f0f0344757ac243c65511392fb41d1c841aphilippe be encountered directly. */ 11003c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "PTRACE_CONT to invoke\n"); 11013c761f0f0344757ac243c65511392fb41d1c841aphilippe res = ptrace (PTRACE_CONT, pid, NULL, NULL); 11023c761f0f0344757ac243c65511392fb41d1c841aphilippe if (res != 0) { 11033c761f0f0344757ac243c65511392fb41d1c841aphilippe ERROR(errno, "PTRACE_CONT\n"); 11043c761f0f0344757ac243c65511392fb41d1c841aphilippe restore_and_detach(pid); 11053c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 11063c761f0f0344757ac243c65511392fb41d1c841aphilippe } 11073c761f0f0344757ac243c65511392fb41d1c841aphilippe pid_of_save_regs_continued = True; 11083c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Wait for SIGSTOP generated by m_gdbserver.c give_control_back_to_vgdb */ 11093c761f0f0344757ac243c65511392fb41d1c841aphilippe stopped = waitstopped (pid, SIGSTOP, 11103c761f0f0344757ac243c65511392fb41d1c841aphilippe "waitpid status after PTRACE_CONT to invoke"); 11113c761f0f0344757ac243c65511392fb41d1c841aphilippe if (stopped) { 11123c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Here pid has properly stopped on the break. */ 11133c761f0f0344757ac243c65511392fb41d1c841aphilippe pid_of_save_regs_continued = False; 11143c761f0f0344757ac243c65511392fb41d1c841aphilippe restore_and_detach(pid); 11153c761f0f0344757ac243c65511392fb41d1c841aphilippe return True; 11163c761f0f0344757ac243c65511392fb41d1c841aphilippe } else { 11173c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Whatever kind of problem happened. We shutdown. */ 11183c761f0f0344757ac243c65511392fb41d1c841aphilippe shutting_down = True; 11193c761f0f0344757ac243c65511392fb41d1c841aphilippe return False; 11203c761f0f0344757ac243c65511392fb41d1c841aphilippe } 11213c761f0f0344757ac243c65511392fb41d1c841aphilippe} 11223c761f0f0344757ac243c65511392fb41d1c841aphilippe 11233c761f0f0344757ac243c65511392fb41d1c841aphilippevoid invoker_cleanup_restore_and_detach(void *v_pid) 11243c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 11253c761f0f0344757ac243c65511392fb41d1c841aphilippe DEBUG(1, "invoker_cleanup_restore_and_detach dying: %d\n", dying); 11263c761f0f0344757ac243c65511392fb41d1c841aphilippe if (!dying) 11273c761f0f0344757ac243c65511392fb41d1c841aphilippe restore_and_detach(*(int*)v_pid); 11283c761f0f0344757ac243c65511392fb41d1c841aphilippe} 11293c761f0f0344757ac243c65511392fb41d1c841aphilippe 11303c761f0f0344757ac243c65511392fb41d1c841aphilippevoid invoker_restrictions_msg(void) 11313c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 11323c761f0f0344757ac243c65511392fb41d1c841aphilippe} 11333c761f0f0344757ac243c65511392fb41d1c841aphilippe 11343c761f0f0344757ac243c65511392fb41d1c841aphilippevoid invoker_valgrind_dying(void) 11353c761f0f0344757ac243c65511392fb41d1c841aphilippe{ 11363c761f0f0344757ac243c65511392fb41d1c841aphilippe /* Avoid messing up with registers of valgrind when it is dying. */ 11373c761f0f0344757ac243c65511392fb41d1c841aphilippe pid_of_save_regs_continued = False; 11383c761f0f0344757ac243c65511392fb41d1c841aphilippe dying = True; 11393c761f0f0344757ac243c65511392fb41d1c841aphilippe} 1140