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