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