vgdb.c revision 0ba37c90c4674515da387b30a6e5f23fa75a173c
13b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/*--------------------------------------------------------------------*/
23b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/*--- Relay between gdb and gdbserver embedded in valgrind  vgdb.c ---*/
33b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/*--------------------------------------------------------------------*/
43b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
53b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/*
63b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   This file is part of Valgrind, a dynamic binary instrumentation
73b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   framework.
83b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
91568e17cf07007c677274ce877973c7ed9357df2sewardj   Copyright (C) 2011-2011 Philippe Waroquiers
103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   This program is free software; you can redistribute it and/or
123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   modify it under the terms of the GNU General Public License as
133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   published by the Free Software Foundation; either version 2 of the
143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   License, or (at your option) any later version.
153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   This program is distributed in the hope that it will be useful, but
173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   WITHOUT ANY WARRANTY; without even the implied warranty of
183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   General Public License for more details.
203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   You should have received a copy of the GNU General Public License
223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   along with this program; if not, write to the Free Software
233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   02111-1307, USA.
253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   The GNU General Public License is contained in the file COPYING.
273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj*/
280ba37c90c4674515da387b30a6e5f23fa75a173csewardj
290ba37c90c4674515da387b30a6e5f23fa75a173csewardj/* Too difficult to make this work on Android right now.  Let's
300ba37c90c4674515da387b30a6e5f23fa75a173csewardj   skip for the time being at least. */
310ba37c90c4674515da387b30a6e5f23fa75a173csewardj#if defined(VGPV_arm_linux_android)
320ba37c90c4674515da387b30a6e5f23fa75a173csewardj
330ba37c90c4674515da387b30a6e5f23fa75a173csewardj#include <stdio.h>
340ba37c90c4674515da387b30a6e5f23fa75a173csewardjint main (int argc, char** argv)
350ba37c90c4674515da387b30a6e5f23fa75a173csewardj{
360ba37c90c4674515da387b30a6e5f23fa75a173csewardj   fprintf(stderr,
370ba37c90c4674515da387b30a6e5f23fa75a173csewardj           "%s: is not currently available on Android, sorry.\n",
380ba37c90c4674515da387b30a6e5f23fa75a173csewardj           argv[0]);
390ba37c90c4674515da387b30a6e5f23fa75a173csewardj   return 0;
400ba37c90c4674515da387b30a6e5f23fa75a173csewardj}
410ba37c90c4674515da387b30a6e5f23fa75a173csewardj
420ba37c90c4674515da387b30a6e5f23fa75a173csewardj#else /* all other (Linux?) platforms */
433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj#include <limits.h>
453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <unistd.h>
463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <string.h>
473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <poll.h>
483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <pthread.h>
493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <stdlib.h>
503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <stdio.h>
513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <fcntl.h>
523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <dirent.h>
533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <sys/stat.h>
543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <sys/time.h>
553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <errno.h>
563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <signal.h>
573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <sys/mman.h>
583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <sys/ptrace.h>
593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <sys/wait.h>
603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include "assert.h"
613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <sys/user.h>
623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
630ba37c90c4674515da387b30a6e5f23fa75a173csewardj#if defined(VGO_linux)
640ba37c90c4674515da387b30a6e5f23fa75a173csewardj#  include <sys/prctl.h>
650ba37c90c4674515da387b30a6e5f23fa75a173csewardj#  include <linux/ptrace.h>
660ba37c90c4674515da387b30a6e5f23fa75a173csewardj#endif
670ba37c90c4674515da387b30a6e5f23fa75a173csewardj
680ba37c90c4674515da387b30a6e5f23fa75a173csewardj#include "pub_core_basics.h"
690ba37c90c4674515da387b30a6e5f23fa75a173csewardj#include "pub_core_vki.h"
700ba37c90c4674515da387b30a6e5f23fa75a173csewardj#include "pub_core_libcsetjmp.h"
710ba37c90c4674515da387b30a6e5f23fa75a173csewardj#include "pub_core_threadstate.h"
720ba37c90c4674515da387b30a6e5f23fa75a173csewardj#include "pub_core_gdbserver.h"
733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* vgdb has two usages:
753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   1. relay application between gdb and the gdbserver embedded in valgrind.
763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   2. standalone to send monitor commands to a running valgrind-ified process
773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   It is made of a main program which reads arguments.  If no
793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   arguments are given or only --pid and --vgdb-prefix, then usage 1 is
803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   assumed.
813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   As relay application, vgdb reads bytes from gdb on stdin and
833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   writes these bytes to valgrind.  Bytes read from valgrind are
843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   written to gdb on stdout.  Read/Write from/to valgrind is done
853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   using FIFOs.  There is one thread reading from stdin, writing to
863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   valgrind on a FIFO.  There is one thread reading from valgrind on a
873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   FIFO, writing to gdb on stdout
883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   As a standalone utility, vgdb builds command packets to write to valgrind,
903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sends it and reads the reply. The same two threads are used to write/read.
913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Once all the commands are sent and their replies received, vgdb will exit.
923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj*/
943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* define PTRACEINVOKER to compile the ptrace related code
963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   which ensures a valgrind process blocked in a system call
973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   can be "waken up". PTRACEINVOKER implies some architecture
983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   specific code and/or some OS specific code. */
993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if defined(VGA_arm) || defined(VGA_x86) || defined(VGA_amd64) \
1003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj    || defined(VGA_ppc32) || defined(VGA_ppc64) || defined(VGA_s390x)
1013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define PTRACEINVOKER
1023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#else
1033b290486cd4cd601b20e04340e593c9ed9717e5fsewardjI_die_here : (PTRACEINVOKER) architecture missing in vgdb.c
1043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif
1053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Some darwin specific stuff is needed as ptrace is not
1073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   fully supported on MacOS. Till we find someone courageous
1083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   having access to Darwin, there is no PTRACEINVOKER. */
1093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if defined(VGO_darwin)
1103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#undef PTRACEINVOKER
1113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif
1123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
11330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj// Outputs information for the user about ptrace_scope protection
11430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj// or ptrace not working.
11530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardjstatic void ptrace_restrictions_msg(void);
11630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj
1173b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int debuglevel;
1183b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic struct timeval dbgtv;
1193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* if level <= debuglevel, print timestamp, then print provided by debug info */
1203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define DEBUG(level, ...) (level <= debuglevel ?                        \
1213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                           gettimeofday(&dbgtv, NULL),                  \
1223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                           fprintf(stderr, "%ld.%6.6ld ",               \
1233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                                   (long int)dbgtv.tv_sec,              \
1243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                                   (long int)dbgtv.tv_usec),            \
1253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                           fprintf(stderr, __VA_ARGS__),fflush(stderr)  \
1263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                           : 0)
1273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* same as DEBUG but does not print time stamp info */
1293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define PDEBUG(level, ...) (level <= debuglevel ?                       \
1303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                            fprintf(stderr, __VA_ARGS__),fflush(stderr) \
1313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                            : 0)
1323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* if errno != 0,
1343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   report the errno and fprintf the ... varargs on stderr. */
1353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define ERROR(errno, ...) ((errno == 0 ? 0 : perror("syscall failed")), \
1363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                           fprintf(stderr, __VA_ARGS__),                \
1373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                           fflush(stderr))
1383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* same as ERROR, but also exits with status 1 */
1393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define XERROR(errno, ...) ((errno == 0 ? 0 : perror("syscall failed")), \
1403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                            fprintf(stderr, __VA_ARGS__),                \
1413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                            fflush(stderr),                              \
1423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                            exit(1))
1433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1443b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic char *vgdb_prefix = "/tmp/vgdb-pipe";
1453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Will be set to True when any condition indicating we have to shutdown
1473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   is encountered. */
1483b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic Bool shutting_down = False;
1493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1503b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic VgdbShared32 *shared32;
1513b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic VgdbShared64 *shared64;
1523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define VS_written_by_vgdb (shared32 != NULL ?        \
1533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                            shared32->written_by_vgdb \
1543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                            : shared64->written_by_vgdb)
1553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define VS_seen_by_valgrind (shared32 != NULL ?         \
1563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                             shared32->seen_by_valgrind \
1573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                             : shared64->seen_by_valgrind)
1583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define VS_vgdb_pid (shared32 != NULL ? shared32->vgdb_pid : shared64->vgdb_pid)
1603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Calls malloc (size). Exits if memory can't be allocated. */
1623b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
1633b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid *vmalloc(size_t size)
1643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
1653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   void * mem = malloc(size);
1663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (mem == NULL)
1673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "can't allocate memory\n");
1683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return mem;
1693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
1703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Calls realloc (size). Exits if memory can't be allocated. */
1723b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
1733b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid *vrealloc(void *ptr,size_t size)
1743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
1753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   void * mem = realloc(ptr, size);
1763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (mem == NULL)
1773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "can't reallocate memory\n");
1783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return mem;
1793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
1803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* add nrw to the written_by_vgdb field of shared32 or shared64 */
1823b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
1833b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid add_written(int nrw)
1843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
1853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (shared32 != NULL)
1863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      shared32->written_by_vgdb += nrw;
1873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else if (shared64 != NULL)
1883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      shared64->written_by_vgdb += nrw;
1893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else
1903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      assert(0);
1913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
1923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1933b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int shared_mem_fd = -1;
1943b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
1953b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid map_vgdbshared (char* shared_mem)
1963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
1973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   struct stat fdstat;
1983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   void **s;
1993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   shared_mem_fd = open(shared_mem, O_RDWR);
2003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* shared_mem_fd will not be closed till vgdb exits. */
2013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (shared_mem_fd == -1)
2033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "error opening %s shared memory file\n", shared_mem);
2043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (fstat(shared_mem_fd, &fdstat) != 0)
2063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "fstat");
2073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (fdstat.st_size == sizeof(VgdbShared64))
2093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      s = (void*) &shared64;
2103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else if (fdstat.st_size == sizeof(VgdbShared32))
2113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      s = (void*) &shared32;
2123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else
2133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if VEX_HOST_WORDSIZE == 8
2143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (0,
2153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              "error size shared memory file %s.\n"
2163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              "expecting size %d (64bits) or %d (32bits) got %ld.\n",
2173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              shared_mem,
2183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              (int) sizeof(VgdbShared64), (int) sizeof(VgdbShared32),
2193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              (long int)fdstat.st_size);
2203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif VEX_HOST_WORDSIZE == 4
2213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (0,
2223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              "error size shared memory file %s.\n"
2233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              "expecting size %d (32bits) got %ld.\n",
2243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              shared_mem,
2253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              (int) sizeof(VgdbShared32),
2263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              fdstat.st_size);
2273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#else
2283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj# error "unexpected wordsize"
2293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif
2303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if VEX_HOST_WORDSIZE == 4
2323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (shared64 != NULL)
2333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (0, "cannot use 32 bits vgdb with a 64bits valgrind process\n");
2343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* But we can use a 64 bits vgdb with a 32 bits valgrind */
2353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif
2363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   *s = (void*) mmap (NULL, fdstat.st_size,
2383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                      PROT_READ|PROT_WRITE, MAP_SHARED,
2393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                      shared_mem_fd, 0);
2403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (*s == (void *) -1)
2423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "error mmap shared memory file %s\n", shared_mem);
2433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
2453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if VEX_HOST_WORDSIZE == 8
2473b290486cd4cd601b20e04340e593c9ed9717e5fsewardjtypedef Addr64 CORE_ADDR;
2483b290486cd4cd601b20e04340e593c9ed9717e5fsewardjtypedef Addr64 PTRACE_XFER_TYPE;
2493b290486cd4cd601b20e04340e593c9ed9717e5fsewardjtypedef void* PTRACE_ARG3_TYPE;
2503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif VEX_HOST_WORDSIZE == 4
2513b290486cd4cd601b20e04340e593c9ed9717e5fsewardjtypedef Addr32 CORE_ADDR;
2523b290486cd4cd601b20e04340e593c9ed9717e5fsewardjtypedef Addr32 PTRACE_XFER_TYPE;
2533b290486cd4cd601b20e04340e593c9ed9717e5fsewardjtypedef void* PTRACE_ARG3_TYPE;
2543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#else
2553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj# error "unexpected wordsize"
2563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif
2573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2583b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic Bool pid_of_save_regs_continued = False;
2593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj// True if we have continued pid_of_save_regs after PTRACE_ATTACH
2603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2613b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic Bool dying = False;
2623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj// Set to True when loss of connection indicating that the Valgrind
2633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj// process is dying.
2643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* To be called when connection with valgrind is lost.  In case we
2663b290486cd4cd601b20e04340e593c9ed9717e5fsewardjhave lost the connection, it means that Valgrind has closed the
2673b290486cd4cd601b20e04340e593c9ed9717e5fsewardjconnection and is busy exiting. We can't and don't have to stop it in
2683b290486cd4cd601b20e04340e593c9ed9717e5fsewardjthis case. */
2693b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
2703b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid valgrind_dying(void)
2713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
2723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   pid_of_save_regs_continued = False;
2733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   dying = True;
2743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
2753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#ifdef PTRACEINVOKER
2783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* ptrace_(read|write)_memory are modified extracts of linux-low.c
2793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   from gdb 6.6. Copyrighted FSF */
2803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Copy LEN bytes from inferior's memory starting at MEMADDR
2813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   to debugger memory starting at MYADDR.  */
2823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2833b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
2843b290486cd4cd601b20e04340e593c9ed9717e5fsewardjint ptrace_read_memory (pid_t inferior_pid, CORE_ADDR memaddr,
2853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                        unsigned char *myaddr, int len)
2863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
2873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   register int i;
2883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Round starting address down to longword boundary.  */
2893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
2903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Round ending address up; get number of longwords that makes.  */
2913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   register int count
2923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
2933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      / sizeof (PTRACE_XFER_TYPE);
2943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Allocate buffer of that many longwords.  */
2953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   register PTRACE_XFER_TYPE *buffer
2963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
2973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Read all the longwords */
2993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) {
3003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      errno = 0;
3013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      buffer[i] = ptrace (PTRACE_PEEKTEXT, inferior_pid,
3023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                          (PTRACE_ARG3_TYPE) addr, 0);
3033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (errno)
3043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return errno;
3053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
3063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Copy appropriate bytes out of the buffer.  */
3083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   memcpy (myaddr,
3093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), len);
3103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return 0;
3123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
3133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Copy LEN bytes of data from debugger memory at MYADDR
3153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   to inferior's memory at MEMADDR.
3163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   On failure (cannot write the inferior)
3173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   returns the value of errno.  */
3183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3193b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
3203b290486cd4cd601b20e04340e593c9ed9717e5fsewardjint ptrace_write_memory (pid_t inferior_pid, CORE_ADDR memaddr,
3213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                         const unsigned char *myaddr, int len)
3223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
3233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   register int i;
3243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Round starting address down to longword boundary.  */
3253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
3263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Round ending address up; get number of longwords that makes.  */
3273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   register int count
3283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
3293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      / sizeof (PTRACE_XFER_TYPE);
3303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Allocate buffer of that many longwords.  */
3313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   register PTRACE_XFER_TYPE *buffer
3323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
3333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (debuglevel >= 1) {
3353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG (1, "Writing ");
3363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      for (i = 0; i < len; i++)
3373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         PDEBUG (1, "%02x", (unsigned)myaddr[i]);
3383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      PDEBUG(1, " to %p\n", (void *) memaddr);
3393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
3403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Fill start and end extra bytes of buffer with existing memory data.  */
3423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   buffer[0] = ptrace (PTRACE_PEEKTEXT, inferior_pid,
3443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                       (PTRACE_ARG3_TYPE) addr, 0);
3453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (count > 1) {
3473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      buffer[count - 1]
3483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         = ptrace (PTRACE_PEEKTEXT, inferior_pid,
3493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   (PTRACE_ARG3_TYPE) (addr + (count - 1)
3503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                                       * sizeof (PTRACE_XFER_TYPE)),
3513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   0);
3523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
3533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Copy data to be written over corresponding part of buffer */
3553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)),
3573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           myaddr, len);
3583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Write the entire buffer.  */
3603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) {
3623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      errno = 0;
3633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      ptrace (PTRACE_POKETEXT, inferior_pid,
3643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              (PTRACE_ARG3_TYPE) addr, buffer[i]);
3653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (errno)
3663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return errno;
3673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
3683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return 0;
3703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
3713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* subset of VG_(threads) needed for vgdb ptrace.
3733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   This is initialized when process is attached. */
3743b290486cd4cd601b20e04340e593c9ed9717e5fsewardjtypedef struct {
3753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   ThreadStatus status;
3763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Int lwpid;
3773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
3783b290486cd4cd601b20e04340e593c9ed9717e5fsewardjVgdbThreadState;
3793b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic VgdbThreadState vgdb_threads[VG_N_THREADS];
3803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3813b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic const
3823b290486cd4cd601b20e04340e593c9ed9717e5fsewardjHChar* name_of_ThreadStatus ( ThreadStatus status )
3833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
3843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   switch (status) {
3853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case VgTs_Empty:     return "VgTs_Empty";
3863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case VgTs_Init:      return "VgTs_Init";
3873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case VgTs_Runnable:  return "VgTs_Runnable";
3883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case VgTs_WaitSys:   return "VgTs_WaitSys";
3893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case VgTs_Yielding:  return "VgTs_Yielding";
3903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case VgTs_Zombie:    return "VgTs_Zombie";
3913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   default:             return "VgTs_???";
3923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  }
3933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
3943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3953b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
3963b290486cd4cd601b20e04340e593c9ed9717e5fsewardjchar *status_image (int status)
3973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
3983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   static char result[256];
3993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int sz = 0;
4003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define APPEND(...) sz += snprintf (result+sz, 256 - sz - 1, __VA_ARGS__)
4013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   result[0] = 0;
4033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (WIFEXITED(status))
4053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      APPEND ("WIFEXITED %d ", WEXITSTATUS(status));
4063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (WIFSIGNALED(status)) {
4083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      APPEND ("WIFSIGNALED %d ", WTERMSIG(status));
4093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (WCOREDUMP(status)) APPEND ("WCOREDUMP ");
4103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
4113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (WIFSTOPPED(status))
4133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      APPEND ("WIFSTOPPED %d ", WSTOPSIG(status));
4143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (WIFCONTINUED(status))
4163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      APPEND ("WIFCONTINUED ");
4173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return result;
4193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#undef APPEND
4203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
4213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Wait till the process pid is reported as stopped with signal_expected.
4233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   If other signal(s) than signal_expected are received, waitstopped
4243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   will pass them to pid, waiting for signal_expected to stop pid.
4253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns True when process is in stopped state with signal_expected.
4263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns False if a problem was encountered while waiting for pid
4273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   to be stopped.
4283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   If pid is reported as being dead/exited, waitstopped will return False.
4303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj*/
4313b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
4323b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool waitstopped (int pid, int signal_expected, char *msg)
4333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
4343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   pid_t p;
4353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int status = 0;
4363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int signal_received;
4373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int res;
4383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   while (1) {
4403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "waitstopped %s before waitpid signal_expected %d\n",
4413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            msg, signal_expected);
4423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      p = waitpid(pid, &status, __WALL);
4433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "after waitpid pid %d p %d status 0x%x %s\n", pid, p,
4443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            status, status_image (status));
4453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (p != pid) {
4463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR(errno, "%s waitpid pid %d in waitstopped %d status 0x%x %s\n",
4473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               msg, pid, p, status, status_image (status));
4483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
4493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
4503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (WIFEXITED(status)) {
4523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         shutting_down = True;
4533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
4543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
4553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      assert (WIFSTOPPED(status));
4573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      signal_received = WSTOPSIG(status);
4583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (signal_received == signal_expected)
4593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         break;
4603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* pid received a signal which is not the signal we are waiting for.
4623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         We continue pid, transmitting this signal. */
4633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "waitstopped PTRACE_CONT with signal %d\n", signal_received);
4643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      res = ptrace (PTRACE_CONT, pid, NULL, signal_received);
4653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (res != 0) {
4663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR(errno, "waitstopped PTRACE_CONT\n");
4673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
4683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
4693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
4703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return True;
4723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
4733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Stops the given pid, wait for the process to be stopped.
4753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns True if succesful, False otherwise.
4763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   msg is used in tracing and error reporting. */
4773b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
4783b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool stop (int pid, char *msg)
4793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
4803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   long res;
4813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(1, "%s SIGSTOP pid %d\n", msg, pid);
4833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   res = kill (pid, SIGSTOP);
4843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (res != 0) {
4853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      ERROR(errno, "%s SIGSTOP pid %d %ld\n", msg, pid, res);
4863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
4873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
4883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return waitstopped (pid, SIGSTOP, msg);
4903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
4923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Attaches to given pid, wait for the process to be stopped.
4943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns True if succesful, False otherwise.
4953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   msg is used in tracing and error reporting. */
4963b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
4973b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool attach (int pid, char *msg)
4983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
4993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   long res;
50030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   static Bool output_error = True;
50130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   static Bool initial_attach = True;
50230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   // For a ptrace_scope protected system, we do not want to output
50330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   // repetitively attach error. We will output once an error
50430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   // for the initial_attach. Once the 1st attach has succeeded, we
50530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   // again show all errors.
5063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
5073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(1, "%s PTRACE_ATTACH pid %d\n", msg, pid);
5083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   res = ptrace (PTRACE_ATTACH, pid, NULL, NULL);
5093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (res != 0) {
51030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      if (output_error || debuglevel > 0) {
51130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         ERROR(errno, "%s PTRACE_ATTACH pid %d %ld\n", msg, pid, res);
51230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         if (initial_attach)
51330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            output_error = False;
51430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      }
5153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
5163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
5173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
51830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   initial_attach = False;
51930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   output_error = True;
5203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return waitstopped(pid, SIGSTOP, msg);
5213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
5223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
5233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* once we are attached to the pid, get the list of threads and stop
5243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   them all.
5253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns True if all threads properly suspended, False otherwise. */
5263b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
5273b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool acquire_and_suspend_threads(int pid)
5283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
5293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int i;
5303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int rw;
5313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Bool pid_found = False;
5323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Addr vgt;
5333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int sz_tst;
5343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int off_status;
5353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int off_lwpid;
5363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int nr_live_threads = 0;
5373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
5383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (shared32 != NULL) {
5393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      vgt = shared32->threads;
5403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sz_tst = shared32->sizeof_ThreadState;
5413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      off_status = shared32->offset_status;
5423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      off_lwpid = shared32->offset_lwpid;
5433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
5443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else if (shared64 != NULL) {
5453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      vgt = shared64->threads;
5463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sz_tst = shared64->sizeof_ThreadState;
5473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      off_status = shared64->offset_status;
5483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      off_lwpid = shared64->offset_lwpid;
5493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else {
5503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      assert (0);
5513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
5523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
5533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* note: the entry 0 is unused */
5543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   for (i = 1; i < VG_N_THREADS; i++) {
5553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      vgt += sz_tst;
5563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      rw = ptrace_read_memory(pid, vgt+off_status,
5573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                              (unsigned char *)&(vgdb_threads[i].status),
5583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                              sizeof(ThreadStatus));
5593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (rw != 0) {
5603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR(rw, "status ptrace_read_memory\n");
5613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
5623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
5633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
5643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      rw = ptrace_read_memory(pid, vgt+off_lwpid,
5653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                              (unsigned char *)&(vgdb_threads[i].lwpid),
5663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                              sizeof(Int));
5673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (rw != 0) {
5683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR(rw, "lwpid ptrace_read_memory\n");
5693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
5703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
5713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
5723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (vgdb_threads[i].status != VgTs_Empty) {
5733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         DEBUG(1, "found tid %d status %s lwpid %d\n",
5743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               i, name_of_ThreadStatus(vgdb_threads[i].status),
5753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               vgdb_threads[i].lwpid);
5763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         nr_live_threads++;
5773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (vgdb_threads[i].lwpid <= 1) {
5783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            if (vgdb_threads[i].lwpid == 0
5793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                && vgdb_threads[i].status == VgTs_Init) {
5803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               DEBUG(1, "not set lwpid tid %d status %s lwpid %d\n",
5813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     i, name_of_ThreadStatus(vgdb_threads[i].status),
5823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     vgdb_threads[i].lwpid);
5833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            } else {
5843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               ERROR(1, "unexpected lwpid tid %d status %s lwpid %d\n",
5853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     i, name_of_ThreadStatus(vgdb_threads[i].status),
5863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     vgdb_threads[i].lwpid);
5873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            }
5883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            /* in case we have a VtTs_Init thread with lwpid not yet set,
5893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               we try again later. */
5903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            return False;
5913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
5923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (vgdb_threads[i].lwpid == pid) {
5933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            assert (!pid_found);
5943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            assert (i == 1);
5953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            pid_found = True;
5963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         } else {
5973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            if (!attach(vgdb_threads[i].lwpid, "attach_thread")) {
5983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                 ERROR(0, "ERROR attach pid %d tid %d\n",
5993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                       vgdb_threads[i].lwpid, i);
6003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               return False;
6013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            }
6023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
6033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
6043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
6053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* If we found no thread, it means the process is stopping, and
6063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      we better do not force anything to happen during that. */
6073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (nr_live_threads > 0)
6083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return True;
6093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else
6103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
6113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
6123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
6133b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
6143b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid detach_from_all_threads(int pid)
6153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
6163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int i;
6173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   long res;
6183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Bool pid_found = False;
6193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
6203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* detach from all the threads  */
6213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   for (i = 1; i < VG_N_THREADS; i++) {
6223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (vgdb_threads[i].status != VgTs_Empty) {
6233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (vgdb_threads[i].status == VgTs_Init
6243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj             && vgdb_threads[i].lwpid == 0) {
6253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(1, "skipping PTRACE_DETACH pid %d tid %d status %s\n",
6263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  vgdb_threads[i].lwpid, i,
6273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  name_of_ThreadStatus (vgdb_threads[i].status));
6283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         } else {
6293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            if (vgdb_threads[i].lwpid == pid) {
6303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               assert (!pid_found);
6313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               pid_found = True;
6323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            }
6333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(1, "PTRACE_DETACH pid %d tid %d status %s\n",
6343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  vgdb_threads[i].lwpid, i,
6353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  name_of_ThreadStatus (vgdb_threads[i].status));
6363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            res = ptrace (PTRACE_DETACH, vgdb_threads[i].lwpid, NULL, NULL);
6373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            if (res != 0) {
6383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               ERROR(errno, "PTRACE_DETACH pid %d tid %d status %s res %ld\n",
6393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     vgdb_threads[i].lwpid, i,
6403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     name_of_ThreadStatus (vgdb_threads[i].status),
6413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     res);
6423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            }
6433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
6443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
6453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
6463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
6473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (!pid_found && pid) {
6483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* No threads are live. Process is busy stopping.
6493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         We need to detach from pid explicitely. */
6503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "no thread live => PTRACE_DETACH pid %d\n", pid);
6513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      res = ptrace (PTRACE_DETACH, pid, NULL, NULL);
6523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (res != 0)
6533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR(errno, "PTRACE_DETACH pid %d res %ld\n", pid, res);
6543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
6553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
6563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
6573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj// if > 0, pid for which registers have to be restored.
6583b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int pid_of_save_regs = 0;
6593b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic struct user user_save;
6603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
661eefeeb7a60a347bc851605fadd52672cbd927201sewardj// The below indicates if ptrace_getregs (and ptrace_setregs) can be used.
662eefeeb7a60a347bc851605fadd52672cbd927201sewardj// Note that some linux versions are defining PTRACE_GETREGS but using
663eefeeb7a60a347bc851605fadd52672cbd927201sewardj// it gives back EIO.
664eefeeb7a60a347bc851605fadd52672cbd927201sewardj// has_working_ptrace_getregs can take the following values:
665eefeeb7a60a347bc851605fadd52672cbd927201sewardj//  -1 : PTRACE_GETREGS is defined
666eefeeb7a60a347bc851605fadd52672cbd927201sewardj//       runtime check not yet done.
667eefeeb7a60a347bc851605fadd52672cbd927201sewardj//   0 : PTRACE_GETREGS runtime check has failed.
668eefeeb7a60a347bc851605fadd52672cbd927201sewardj//   1 : PTRACE_GETREGS defined and runtime check ok.
669eefeeb7a60a347bc851605fadd52672cbd927201sewardj#ifdef PTRACE_GETREGS
670eefeeb7a60a347bc851605fadd52672cbd927201sewardjstatic int has_working_ptrace_getregs = -1;
671eefeeb7a60a347bc851605fadd52672cbd927201sewardj#endif
672eefeeb7a60a347bc851605fadd52672cbd927201sewardj
6733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Get the registers from pid into regs.
674eefeeb7a60a347bc851605fadd52672cbd927201sewardj   regs_bsz value gives the length of *regs.
6753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns True if all ok, otherwise False. */
6763b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
677eefeeb7a60a347bc851605fadd52672cbd927201sewardjBool getregs (int pid, void *regs, long regs_bsz)
6783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
679eefeeb7a60a347bc851605fadd52672cbd927201sewardj   DEBUG(1, "getregs regs_bsz %ld\n", regs_bsz);
680eefeeb7a60a347bc851605fadd52672cbd927201sewardj#  ifdef PTRACE_GETREGS
681eefeeb7a60a347bc851605fadd52672cbd927201sewardj   if (has_working_ptrace_getregs) {
682eefeeb7a60a347bc851605fadd52672cbd927201sewardj      // Platforms having GETREGS
683eefeeb7a60a347bc851605fadd52672cbd927201sewardj      long res;
684eefeeb7a60a347bc851605fadd52672cbd927201sewardj      DEBUG(1, "getregs PTRACE_GETREGS\n");
685eefeeb7a60a347bc851605fadd52672cbd927201sewardj      res = ptrace (PTRACE_GETREGS, pid, NULL, regs);
686eefeeb7a60a347bc851605fadd52672cbd927201sewardj      if (res == 0) {
687eefeeb7a60a347bc851605fadd52672cbd927201sewardj         if (has_working_ptrace_getregs == -1) {
688eefeeb7a60a347bc851605fadd52672cbd927201sewardj            // First call to PTRACE_GETREGS succesful =>
689eefeeb7a60a347bc851605fadd52672cbd927201sewardj            has_working_ptrace_getregs = 1;
690eefeeb7a60a347bc851605fadd52672cbd927201sewardj            DEBUG(1, "detected a working PTRACE_GETREGS\n");
691eefeeb7a60a347bc851605fadd52672cbd927201sewardj         }
692eefeeb7a60a347bc851605fadd52672cbd927201sewardj         assert (has_working_ptrace_getregs == 1);
693eefeeb7a60a347bc851605fadd52672cbd927201sewardj         return True;
694eefeeb7a60a347bc851605fadd52672cbd927201sewardj      }
695eefeeb7a60a347bc851605fadd52672cbd927201sewardj      else if (has_working_ptrace_getregs == 1) {
696eefeeb7a60a347bc851605fadd52672cbd927201sewardj         // We had a working call, but now it fails.
697eefeeb7a60a347bc851605fadd52672cbd927201sewardj         // This is unexpected.
698eefeeb7a60a347bc851605fadd52672cbd927201sewardj         ERROR(errno, "PTRACE_GETREGS %ld\n", res);
6993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
700eefeeb7a60a347bc851605fadd52672cbd927201sewardj      } else {
701eefeeb7a60a347bc851605fadd52672cbd927201sewardj         // Check this is the first call:
702eefeeb7a60a347bc851605fadd52672cbd927201sewardj         assert (has_working_ptrace_getregs == -1);
703eefeeb7a60a347bc851605fadd52672cbd927201sewardj         if (errno == EIO) {
704eefeeb7a60a347bc851605fadd52672cbd927201sewardj            DEBUG(1, "detected a broken PTRACE_GETREGS with EIO\n");
705eefeeb7a60a347bc851605fadd52672cbd927201sewardj            has_working_ptrace_getregs = 0;
706eefeeb7a60a347bc851605fadd52672cbd927201sewardj            // Fall over to the PTRACE_PEEKUSER case.
707eefeeb7a60a347bc851605fadd52672cbd927201sewardj         } else {
708eefeeb7a60a347bc851605fadd52672cbd927201sewardj            ERROR(errno, "broken PTRACE_GETREGS unexpected errno %ld\n", res);
709eefeeb7a60a347bc851605fadd52672cbd927201sewardj            return False;
710eefeeb7a60a347bc851605fadd52672cbd927201sewardj         }
7113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
7123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
7133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#  endif
714eefeeb7a60a347bc851605fadd52672cbd927201sewardj
715eefeeb7a60a347bc851605fadd52672cbd927201sewardj   // We assume  PTRACE_PEEKUSER is defined everywhere.
716eefeeb7a60a347bc851605fadd52672cbd927201sewardj   {
717eefeeb7a60a347bc851605fadd52672cbd927201sewardj#     ifdef PT_ENDREGS
718eefeeb7a60a347bc851605fadd52672cbd927201sewardj      long peek_bsz = PT_ENDREGS;
719eefeeb7a60a347bc851605fadd52672cbd927201sewardj      assert (peek_bsz <= regs_bsz);
720eefeeb7a60a347bc851605fadd52672cbd927201sewardj#     else
721eefeeb7a60a347bc851605fadd52672cbd927201sewardj      long peek_bsz = regs_bsz-1;
722eefeeb7a60a347bc851605fadd52672cbd927201sewardj#     endif
723eefeeb7a60a347bc851605fadd52672cbd927201sewardj      char *pregs = (char *) regs;
724eefeeb7a60a347bc851605fadd52672cbd927201sewardj      long offset;
725eefeeb7a60a347bc851605fadd52672cbd927201sewardj      errno = 0;
726eefeeb7a60a347bc851605fadd52672cbd927201sewardj      DEBUG(1, "getregs PTRACE_PEEKUSER(s) peek_bsz %ld\n", peek_bsz);
727eefeeb7a60a347bc851605fadd52672cbd927201sewardj      for (offset = 0; offset < peek_bsz; offset = offset + sizeof(long)) {
728eefeeb7a60a347bc851605fadd52672cbd927201sewardj         *(long *)(pregs+offset) = ptrace(PTRACE_PEEKUSER, pid, offset, NULL);
729eefeeb7a60a347bc851605fadd52672cbd927201sewardj         if (errno != 0) {
730eefeeb7a60a347bc851605fadd52672cbd927201sewardj            ERROR(errno, "PTRACE_PEEKUSER offset %ld\n", offset);
731eefeeb7a60a347bc851605fadd52672cbd927201sewardj            return False;
732eefeeb7a60a347bc851605fadd52672cbd927201sewardj         }
733eefeeb7a60a347bc851605fadd52672cbd927201sewardj      }
734eefeeb7a60a347bc851605fadd52672cbd927201sewardj      return True;
735eefeeb7a60a347bc851605fadd52672cbd927201sewardj   }
736eefeeb7a60a347bc851605fadd52672cbd927201sewardj
737eefeeb7a60a347bc851605fadd52672cbd927201sewardj   // If neither PTRACE_GETREGS not PTRACE_PEEKUSER have returned,
738eefeeb7a60a347bc851605fadd52672cbd927201sewardj   // then we are in serious trouble.
739eefeeb7a60a347bc851605fadd52672cbd927201sewardj   assert (0);
7403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
7413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
7423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Set the registers of pid to regs.
743eefeeb7a60a347bc851605fadd52672cbd927201sewardj   regs_bsz value gives the length of *regs.
7443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns True if all ok, otherwise False. */
7453b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
746eefeeb7a60a347bc851605fadd52672cbd927201sewardjBool setregs (int pid, void *regs, long regs_bsz)
7473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
748eefeeb7a60a347bc851605fadd52672cbd927201sewardj   DEBUG(1, "setregs regs_bsz %ld\n", regs_bsz);
749eefeeb7a60a347bc851605fadd52672cbd927201sewardj// Note : the below is checking for GETREGS, not SETREGS
750eefeeb7a60a347bc851605fadd52672cbd927201sewardj// as if one is defined and working, the other one should also work.
751eefeeb7a60a347bc851605fadd52672cbd927201sewardj#  ifdef PTRACE_GETREGS
752eefeeb7a60a347bc851605fadd52672cbd927201sewardj   if (has_working_ptrace_getregs) {
753eefeeb7a60a347bc851605fadd52672cbd927201sewardj      // Platforms having SETREGS
754eefeeb7a60a347bc851605fadd52672cbd927201sewardj      long res;
755eefeeb7a60a347bc851605fadd52672cbd927201sewardj      // setregs can never be called before getregs has done a runtime check.
756eefeeb7a60a347bc851605fadd52672cbd927201sewardj      assert (has_working_ptrace_getregs == 1);
757eefeeb7a60a347bc851605fadd52672cbd927201sewardj      DEBUG(1, "setregs PTRACE_SETREGS\n");
758eefeeb7a60a347bc851605fadd52672cbd927201sewardj      res = ptrace (PTRACE_SETREGS, pid, NULL, regs);
759eefeeb7a60a347bc851605fadd52672cbd927201sewardj      if (res != 0) {
760eefeeb7a60a347bc851605fadd52672cbd927201sewardj         ERROR(errno, "PTRACE_SETREGS %ld\n", res);
7613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
7623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
763eefeeb7a60a347bc851605fadd52672cbd927201sewardj      return True;
7643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
7653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#  endif
766eefeeb7a60a347bc851605fadd52672cbd927201sewardj
767eefeeb7a60a347bc851605fadd52672cbd927201sewardj   {
768eefeeb7a60a347bc851605fadd52672cbd927201sewardj      char *pregs = (char *) regs;
769eefeeb7a60a347bc851605fadd52672cbd927201sewardj      long offset;
770eefeeb7a60a347bc851605fadd52672cbd927201sewardj      long res;
771eefeeb7a60a347bc851605fadd52672cbd927201sewardj#     ifdef PT_ENDREGS
772eefeeb7a60a347bc851605fadd52672cbd927201sewardj      long peek_bsz = PT_ENDREGS;
773eefeeb7a60a347bc851605fadd52672cbd927201sewardj      assert (peek_bsz <= regs_bsz);
774eefeeb7a60a347bc851605fadd52672cbd927201sewardj#     else
775eefeeb7a60a347bc851605fadd52672cbd927201sewardj      long peek_bsz = regs_bsz-1;
776eefeeb7a60a347bc851605fadd52672cbd927201sewardj#     endif
777eefeeb7a60a347bc851605fadd52672cbd927201sewardj      errno = 0;
778eefeeb7a60a347bc851605fadd52672cbd927201sewardj      DEBUG(1, "setregs PTRACE_POKEUSER(s) %ld\n", peek_bsz);
779eefeeb7a60a347bc851605fadd52672cbd927201sewardj      for (offset = 0; offset < peek_bsz; offset = offset + sizeof(long)) {
780eefeeb7a60a347bc851605fadd52672cbd927201sewardj         res = ptrace(PTRACE_POKEUSER, pid, offset, *(long*)(pregs+offset));
781eefeeb7a60a347bc851605fadd52672cbd927201sewardj         if (errno != 0) {
782eefeeb7a60a347bc851605fadd52672cbd927201sewardj            ERROR(errno, "PTRACE_POKEUSER offset %ld res %ld\n", offset, res);
783eefeeb7a60a347bc851605fadd52672cbd927201sewardj            return False;
784eefeeb7a60a347bc851605fadd52672cbd927201sewardj         }
785eefeeb7a60a347bc851605fadd52672cbd927201sewardj      }
786eefeeb7a60a347bc851605fadd52672cbd927201sewardj      return True;
787eefeeb7a60a347bc851605fadd52672cbd927201sewardj   }
788eefeeb7a60a347bc851605fadd52672cbd927201sewardj
789eefeeb7a60a347bc851605fadd52672cbd927201sewardj   // If neither PTRACE_SETREGS not PTRACE_POKEUSER have returned,
790eefeeb7a60a347bc851605fadd52672cbd927201sewardj   // then we are in serious trouble.
791eefeeb7a60a347bc851605fadd52672cbd927201sewardj   assert (0);
7923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
7933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
7943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Restore the registers to the saved value, then detaches from all threads */
7953b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
7963b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid restore_and_detach(int pid)
7973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
7983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (pid_of_save_regs) {
7993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* In case the 'main pid' has been continued, we need to stop it
8003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         before resetting the registers. */
8013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (pid_of_save_regs_continued) {
8023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         pid_of_save_regs_continued = False;
8033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (!stop(pid_of_save_regs, "sigstop before reset regs"))
8043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(0, "Could not sigstop before reset");
8053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
8063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "setregs restore registers pid %d\n", pid_of_save_regs);
808eefeeb7a60a347bc851605fadd52672cbd927201sewardj      if (!setregs(pid_of_save_regs, &user_save.regs, sizeof(user_save.regs))) {
8093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR(errno, "setregs restore registers pid %d after cont\n",
8103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               pid_of_save_regs);
8113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
8123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pid_of_save_regs = 0;
8133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else {
8143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "PTRACE_SETREGS restore registers: no pid\n");
8153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
8163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   detach_from_all_threads(pid);
8173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
8183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Ensures that the gdbserver code is invoked by pid.
8203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   If an error occurs, resets to the valgrind process
8213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   to the state it has before being ptrace-d.
8223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns True if invoke successful, False otherwise.
8233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj*/
8243b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
8253b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool invoke_gdbserver (int pid)
8263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
82730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   static Bool ptrace_restrictions_msg_given = False;
8283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   long res;
8293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Bool stopped;
8303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   struct user user_mod;
8313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Addr sp;
8323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* A specific int value is passed to invoke_gdbserver, to check
8333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      everything goes according to the plan. */
8343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   const int check = 0x8BADF00D; // ate bad food.
8353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   const Addr bad_return = 0;
8373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   // A bad return address will be pushed on the stack.
8383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   // The function invoke_gdbserver cannot return. If ever it returns, a NULL
8393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   // address pushed on the stack should ensure this is detected.
8403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Not yet attached. If problem, vgdb can abort,
8423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      no cleanup needed.
8433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      On Ubuntu>= 10.10, a /proc setting can disable ptrace.
8453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      So, Valgrind has to SET_PTRACER this vgdb. Once this
8463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      is done, this vgdb can ptrace the valgrind process. */
8473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(1, "attach to 'main' pid %d\n", pid);
8493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (!attach(pid, "attach main pid")) {
85030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      if (!ptrace_restrictions_msg_given) {
85130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         ptrace_restrictions_msg_given = True;
85230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         ERROR(0, "error attach main pid %d\n", pid);
85330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         ptrace_restrictions_msg();
85430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      }
8553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
8563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
8573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Now, we are attached. If problem, detach and return. */
8593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (!acquire_and_suspend_threads(pid)) {
8613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      detach_from_all_threads(pid);
8623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* if the pid does not exist anymore, we better stop */
8633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (kill(pid, 0) != 0)
8643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        XERROR (errno, "invoke_gdbserver: check for pid %d existence failed\n",
8653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                pid);
8663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
8673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
8683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
869eefeeb7a60a347bc851605fadd52672cbd927201sewardj   if (!getregs(pid, &user_mod.regs, sizeof(user_mod.regs))) {
8703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      detach_from_all_threads(pid);
8713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
8723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
8733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   user_save = user_mod;
8743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if defined(VGA_x86)
8763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sp = user_mod.regs.esp;
8773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_amd64)
8783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sp = user_mod.regs.rsp;
8793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (shared32 != NULL) {
8803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     /* 64bit vgdb speaking with a 32bit executable.
8813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        To have system call restart properly, we need to sign extend rax.
8823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        For more info:
8833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        web search '[patch] Fix syscall restarts for amd64->i386 biarch'
8843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        e.g. http://sourceware.org/ml/gdb-patches/2009-11/msg00592.html */
8853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     *(long *)&user_save.regs.rax = *(int*)&user_save.regs.rax;
8863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     DEBUG(1, "Sign extending %8.8lx to %8.8lx\n",
8873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           user_mod.regs.rax, user_save.regs.rax);
8883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
8893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_arm)
8903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sp = user_mod.regs.uregs[13];
8913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_ppc32)
8923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sp = user_mod.regs.gpr[1];
8933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_ppc64)
8943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sp = user_mod.regs.gpr[1];
8953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_s390x)
8963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sp = user_mod.regs.gprs[15];
8973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#else
8983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   I_die_here : (sp) architecture missing in vgdb.c
8993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif
9003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
9013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
9023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   // the magic below is derived from spying what gdb sends to
9033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   // the (classical) gdbserver when invoking a C function.
9043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (shared32 != NULL) {
9053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      // vgdb speaking with a 32bit executable.
9063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if   defined(VGA_x86) || defined(VGA_amd64)
9073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      const int regsize = 4;
9083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      int rw;
9093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* push check arg on the stack */
9103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sp = sp - regsize;
9113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "push check arg ptrace_write_memory\n");
9123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      assert(regsize == sizeof(check));
9133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      rw = ptrace_write_memory(pid, sp,
9143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                               (unsigned char *) &check,
9153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                               regsize);
9163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (rw != 0) {
9173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR(rw, "push check arg ptrace_write_memory");
9183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         detach_from_all_threads(pid);
9193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
9203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
9213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
9223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sp = sp - regsize;
9233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "push bad_return return address ptrace_write_memory\n");
9243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      // Note that for a 64 bits vgdb, only 4 bytes of NULL bad_return
9253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      // are written.
9263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      rw = ptrace_write_memory(pid, sp,
9273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                               (unsigned char *) &bad_return,
9283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                               regsize);
9293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (rw != 0) {
9303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR(rw, "push bad_return return address ptrace_write_memory");
9313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         detach_from_all_threads(pid);
9323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
9333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
9343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if   defined(VGA_x86)
9353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* set ebp, esp, eip and orig_eax to invoke gdbserver */
9363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      // compiled in 32bits, speaking with a 32bits exe
9373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.ebp = sp; // bp set to sp
9383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.esp = sp;
9393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.eip = shared32->invoke_gdbserver;
9403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.orig_eax = -1L;
9413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_amd64)
9423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* set ebp, esp, eip and orig_eax to invoke gdbserver */
9433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      // compiled in 64bits, speaking with a 32bits exe
9443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.rbp = sp; // bp set to sp
9453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.rsp = sp;
9463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.rip = shared32->invoke_gdbserver;
9473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.orig_rax = -1L;
9483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#else
9493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      I_die_here : not x86 or amd64 in x86/amd64 section/
9503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif
9513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
9523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_ppc32) || defined(VGA_ppc64)
9533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.nip = shared32->invoke_gdbserver;
9543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.trap = -1L;
9553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* put check arg in register 3 */
9563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.gpr[3] = check;
9573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* put NULL return address in Link Register */
9583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.link = bad_return;
9593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
9603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_arm)
9613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* put check arg in register 0 */
9623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.uregs[0] = check;
9633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* put NULL return address in Link Register */
9643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.uregs[14] = bad_return;
9653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.uregs[15] = shared32->invoke_gdbserver;
9663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
9673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_s390x)
9683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR(0, "(fn32) s390x has no 32bits implementation");
9693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#else
9703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      I_die_here : architecture missing in vgdb.c
9713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif
9723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
9733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
9743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else if (shared64 != NULL) {
9753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if defined(VGA_x86)
9763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      assert(0); // cannot vgdb a 64 bits executable with a 32 bits exe
9773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_amd64)
9783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      // vgdb speaking with a 64 bit executable.
9793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      const int regsize = 8;
9803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      int rw;
9813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
9823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* give check arg in rdi */
9833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.rdi = check;
9843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
9853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* push return address on stack : return to breakaddr */
9863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sp = sp - regsize;
9873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "push bad_return return address ptrace_write_memory\n");
9883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      rw = ptrace_write_memory(pid, sp,
9893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                               (unsigned char *) &bad_return,
9903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                               sizeof(bad_return));
9913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (rw != 0) {
9923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR(rw, "push bad_return return address ptrace_write_memory");
9933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         detach_from_all_threads(pid);
9943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
9953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
9963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
9973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* set rbp, rsp, rip and orig_rax to invoke gdbserver */
9983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.rbp = sp; // bp set to sp
9993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.rsp = sp;
10003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.rip = shared64->invoke_gdbserver;
10013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.orig_rax = -1L;
10023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
10033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_arm)
10043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      assert(0); // cannot vgdb a 64 bits executable with a 32 bits exe
10053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_ppc32)
10063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      assert(0); // cannot vgdb a 64 bits executable with a 32 bits exe
10073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_ppc64)
10083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      Addr64 func_addr;
10093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      Addr64 toc_addr;
10103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      int rw;
10113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      rw = ptrace_read_memory(pid, shared64->invoke_gdbserver,
10123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                              (unsigned char *)&func_addr,
10133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                              sizeof(Addr64));
10143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (rw != 0) {
10153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR(rw, "ppc64 read func_addr\n");
10163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         detach_from_all_threads(pid);
10173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
10183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
10193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      rw = ptrace_read_memory(pid, shared64->invoke_gdbserver+8,
10203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                              (unsigned char *)&toc_addr,
10213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                              sizeof(Addr64));
10223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (rw != 0) {
10233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR(rw, "ppc64 read toc_addr\n");
10243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         detach_from_all_threads(pid);
10253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
10263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
10273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      // We are not pushing anything on the stack, so it is not
10283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      // very clear why the sp has to be decreased, but it seems
10293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      // needed. The ppc64 ABI might give some lights on this ?
10303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.gpr[1] = sp - 220;
10313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.gpr[2] = toc_addr;
10323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.nip = func_addr;
10333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.trap = -1L;
10343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* put check arg in register 3 */
10353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.gpr[3] = check;
10363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* put bad_return return address in Link Register */
10373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.link = bad_return;
10383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_s390x)
10393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* put check arg in register r2 */
10403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.gprs[2] = check;
10413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* bad_return Return address is in r14 */
10423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.gprs[14] = bad_return;
10433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* minimum stack frame */
10443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sp = sp - 160;
10453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.gprs[15] = sp;
10463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* set program counter */
10473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.psw.addr = shared64->invoke_gdbserver;
10483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#else
10493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      I_die_here: architecture missing in vgdb.c
10503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif
10513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
10523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else {
10533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      assert(0);
10543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
10553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1056eefeeb7a60a347bc851605fadd52672cbd927201sewardj   if (!setregs(pid, &user_mod.regs, sizeof(user_mod.regs))) {
10573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      detach_from_all_threads(pid);
10583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
10593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
10603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Now that we have modified the registers, we set
10613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pid_of_save_regs to indicate that restore_and_detach
10623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      must restore the registers in case of cleanup. */
10633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   pid_of_save_regs = pid;
10643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   pid_of_save_regs_continued = False;
10653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
10663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
10673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* We PTRACE_CONT-inue pid.
10683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      Either gdbserver will be invoked directly (if all
10693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      threads are interruptible) or gdbserver will be
10703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      called soon by the scheduler. In the first case,
10713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pid will stop on the break inserted above when
10723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      gdbserver returns. In the 2nd case, the break will
10733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      be encountered directly. */
10743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(1, "PTRACE_CONT to invoke\n");
10753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   res = ptrace (PTRACE_CONT, pid, NULL, NULL);
10763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (res != 0) {
10773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      ERROR(errno, "PTRACE_CONT\n");
10783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      restore_and_detach(pid);
10793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
10803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
10813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   pid_of_save_regs_continued = True;
1082b2572b52b37d56d302408395f7fed9f509423af1sewardj   /* Wait for SIGSTOP generated by m_gdbserver.c give_control_back_to_vgdb */
1083b2572b52b37d56d302408395f7fed9f509423af1sewardj   stopped = waitstopped (pid, SIGSTOP,
10843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                          "waitpid status after PTRACE_CONT to invoke");
10853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (stopped) {
10863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* Here pid has properly stopped on the break. */
10873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pid_of_save_regs_continued = False;
10883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      restore_and_detach(pid);
10893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return True;
10903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else {
10913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* Whatever kind of problem happened. We shutdown */
10923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      shutting_down = True;
10933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
10943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
10953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
10963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif
10973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
10983b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
10993b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid cleanup_restore_and_detach(void *v_pid)
11003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
11013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(1, "cleanup_restore_and_detach dying: %d\n", dying);
11023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#ifdef PTRACEINVOKER
11033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (!dying)
11043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      restore_and_detach(*(int*)v_pid);
11053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif
11063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
11073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
11083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* This function loops till shutting_down becomes true.  In this loop,
11093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   it verifies if valgrind process is reading the characters written
11103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   by vgdb.  The verification is done every max_invoke_ms ms.  If
11113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   valgrind is not reading characters, it will use invoke_gdbserver
11123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   (if PTRACE_INVOKER is defined) to ensure that the gdbserver code is
11133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   called soon by valgrind. */
11143b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int max_invoke_ms = 100;
111530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj#define NEVER 99999999
111630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardjstatic int cmd_time_out = NEVER;
11173b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
11183b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid *invoke_gdbserver_in_valgrind(void *v_pid)
11193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
112030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   struct timeval cmd_max_end_time;
112130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   Bool cmd_started = False;
112230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   struct timeval invoke_time;
112330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj
11243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int pid = *(int *)v_pid;
11253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int written_by_vgdb_before_sleep;
11263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int seen_by_valgrind_before_sleep;
11273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
11283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int invoked_written = -1;
112930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   unsigned int usecs;
11303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
11313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   pthread_cleanup_push(cleanup_restore_and_detach, v_pid);
11323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
11333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   while (!shutting_down) {
11343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      written_by_vgdb_before_sleep = VS_written_by_vgdb;
11353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      seen_by_valgrind_before_sleep = VS_seen_by_valgrind;
11363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(3,
11373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            "written_by_vgdb_before_sleep %d "
11383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            "seen_by_valgrind_before_sleep %d\n",
11393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            written_by_vgdb_before_sleep,
11403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            seen_by_valgrind_before_sleep);
114130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      if (cmd_time_out != NEVER
114230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj          && !cmd_started
114330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj          && written_by_vgdb_before_sleep > seen_by_valgrind_before_sleep) {
114430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         /* A command was started. Record the time at which it was started. */
114530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         DEBUG(1, "IO for command started\n");
114630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         gettimeofday(&cmd_max_end_time, NULL);
114730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         cmd_max_end_time.tv_sec += cmd_time_out;
114830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         cmd_started = True;
114930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      }
115030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      if (max_invoke_ms > 0) {
115130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         usecs = 1000 * max_invoke_ms;
115230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         gettimeofday(&invoke_time, NULL);
115330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         invoke_time.tv_sec += max_invoke_ms / 1000;
115430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         invoke_time.tv_usec += 1000 * (max_invoke_ms % 1000);
115530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         invoke_time.tv_sec += invoke_time.tv_usec / (1000 * 1000);
115630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         invoke_time.tv_usec = invoke_time.tv_usec % (1000 * 1000);
115730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      } else {
115830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         usecs = 0;
115930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      }
116030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      if (cmd_started) {
116130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         // 0 usecs here means the thread just has to check gdbserver eats
116230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         // the characters in <= cmd_time_out seconds.
116330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         // We will just wait by 1 second max at a time.
116430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         if (usecs == 0 || usecs > 1000 * 1000)
116530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            usecs = 1000 * 1000;
116630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      }
116730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      if (usleep(usecs) != 0) {
11683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (errno == EINTR)
11693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            continue;
11703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         XERROR (errno, "error usleep\n");
11713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
117230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      /* If nothing happened during our sleep, let's try to wake up valgrind
117330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         or check for cmd time out. */
11743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (written_by_vgdb_before_sleep == VS_written_by_vgdb
11753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj          && seen_by_valgrind_before_sleep == VS_seen_by_valgrind
11763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj          && VS_written_by_vgdb > VS_seen_by_valgrind) {
117730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         struct timeval now;
117830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         gettimeofday(&now, NULL);
11793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         DEBUG(2,
11803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               "after sleep "
11813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               "written_by_vgdb %d "
11823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               "seen_by_valgrind %d "
11833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               "invoked_written %d\n",
11843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               VS_written_by_vgdb,
11853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               VS_seen_by_valgrind,
11863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               invoked_written);
11873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         /* if the pid does not exist anymore, we better stop */
11883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (kill(pid, 0) != 0)
11893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           XERROR (errno,
11903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   "invoke_gdbserver_in_valgrind: "
11913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   "check for pid %d existence failed\n", pid);
119230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         if (cmd_started) {
119330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            if (timercmp (&now, &cmd_max_end_time, >))
119430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj               XERROR (0,
119530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj                       "pid %d did not handle a command in %d seconds\n",
119630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj                       pid, cmd_time_out);
119730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         }
119830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         if (max_invoke_ms > 0 && timercmp (&now, &invoke_time, >=)) {
119930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            #if defined(PTRACEINVOKER)
120030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            /* only need to wake up if the nr written has changed since
120130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj               last invoke. */
120230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            if (invoked_written != written_by_vgdb_before_sleep) {
120330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj               if (invoke_gdbserver(pid)) {
120430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj                  /* If invoke succesful, no need to invoke again
120530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj                     for the same value of written_by_vgdb_before_sleep. */
120630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj                  invoked_written = written_by_vgdb_before_sleep;
120730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj               }
12083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            }
120930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            #else
121030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            DEBUG(2, "invoke_gdbserver via ptrace not (yet) implemented\n");
121130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            #endif
121230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         }
121330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      } else {
121430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         // Something happened => restart timer check.
121530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         if (cmd_time_out != NEVER) {
121630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            DEBUG(2, "some IO was done => restart command\n");
121730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            cmd_started = False;
12183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
12193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
12203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
12213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   pthread_cleanup_pop(0);
12223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return NULL;
12233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
12243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
12253b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
12263b290486cd4cd601b20e04340e593c9ed9717e5fsewardjint open_fifo (char* name, int flags, char* desc)
12273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
12283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int fd;
12293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(1, "opening %s %s\n", name, desc);
12303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   fd = open(name, flags);
12313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (fd == -1)
12323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "error opening %s %s\n", name, desc);
12333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
12343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(1, "opened %s %s fd %d\n", name, desc, fd);
12353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return fd;
12363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
12373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
12383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* acquire a lock on the first byte of the given fd. If not successful,
12393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   exits with error.
12403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   This allows to avoid having two vgdb speaking with the same Valgrind
12413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   gdbserver as this causes serious headaches to the protocol. */
12423b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
12433b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid acquire_lock (int fd, int valgrind_pid)
12443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
12453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (lockf(fd, F_TLOCK, 1) < 0) {
12463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (errno == EAGAIN || errno == EACCES) {
12473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         XERROR(errno,
12483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                "Cannot acquire lock.\n"
12493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                "Probably vgdb pid %d already speaks with Valgrind pid %d\n",
12503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                VS_vgdb_pid,
12513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                valgrind_pid);
12523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else {
12533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         XERROR(errno, "cannot acquire lock.\n");
12543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
12553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
12563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
12573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Here, we have the lock. It will be released when fd will be closed. */
12583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* We indicate our pid to Valgrind gdbserver */
12593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (shared32 != NULL)
12603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      shared32->vgdb_pid = getpid();
12613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else if (shared64 != NULL)
12623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      shared64->vgdb_pid = getpid();
12633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else
12643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      assert(0);
12653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
12663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
12673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define PBUFSIZ 16384 /* keep in sync with server.h */
12683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
12693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* read some characters from fd.
12703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns the nr of characters read, -1 if error.
12713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   desc is a string used in tracing */
12723b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
12733b290486cd4cd601b20e04340e593c9ed9717e5fsewardjint read_buf (int fd, char* buf, char* desc)
12743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
12753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int nrread;
12763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(2, "reading %s\n", desc);
12773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   nrread = read(fd, buf, PBUFSIZ);
12783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (nrread == -1) {
12793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      ERROR (errno, "error reading %s\n", desc);
12803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return -1;
12813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
12823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   buf[nrread] = '\0';
12833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(2, "read %s %s\n", desc, buf);
12843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return nrread;
12853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
12863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
12873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* write size bytes from buf to fd.
12883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   desc is a description of the action for which the write is done.
12893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   If notify, then add size to the shared cntr indicating to the
12903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   valgrind process that there is new data.
12913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns True if write is ok, False if there was a problem. */
12923b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
12933b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool write_buf(int fd, char* buf, int size, char* desc, Bool notify)
12943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
12953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int nrwritten;
12963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int nrw;
12973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(2, "writing %s len %d %s notify: %d\n", desc, size, buf, notify);
12983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   nrwritten = 0;
12993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   while (nrwritten < size) {
13003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      nrw = write (fd, buf+nrwritten, size - nrwritten);
13013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (nrw == -1) {
13023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR(errno, "error write %s\n", desc);
13033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
13043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
13053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      nrwritten = nrwritten + nrw;
13063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (notify)
13073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         add_written(nrw);
13083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
13093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return True;
13103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
13113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
13123b290486cd4cd601b20e04340e593c9ed9717e5fsewardjtypedef enum {
13133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   FROM_GDB,
13143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   TO_GDB,
13153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   FROM_PID,
13163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   TO_PID } ConnectionKind;
13173b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic const int NumConnectionKind = TO_PID+1;
13183b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
13193b290486cd4cd601b20e04340e593c9ed9717e5fsewardjchar *ppConnectionKind (ConnectionKind con)
13203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
13213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   switch (con) {
13223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case FROM_GDB: return "FROM_GDB";
13233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case TO_GDB:   return "TO_GDB";
13243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case FROM_PID: return "FROM_PID";
13253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case TO_PID:   return "TO_PID";
13263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   default:       return "invalid connection kind";
13273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
13283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
13293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
13303b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic char *shared_mem;
13313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
13323b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic const int from_gdb = 0;
13333b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic char *from_gdb_to_pid; /* fifo name to write gdb command to pid */
13343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Returns True in case read/write operations were done properly.
13353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns False in case of error.
13363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   to_pid is the file descriptor to write to the process pid. */
13373b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
13383b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool read_from_gdb_write_to_pid(int to_pid)
13393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
13403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   char buf[PBUFSIZ];
13413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int nrread;
13423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
13433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   nrread = read_buf(from_gdb, buf, "from gdb on stdin");
13443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (nrread <= 0) {
13453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (nrread == 0)
13463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         DEBUG(1, "read 0 bytes from gdb => assume exit\n");
13473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      else
13483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         DEBUG(1, "error reading bytes from gdb\n");
13493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      close (from_gdb);
13503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      shutting_down = True;
13513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
13523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
13533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return write_buf(to_pid, buf, nrread, "to_pid", /* notify */ True);
13543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
13553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
13563b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic const int to_gdb = 1;
13573b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic char *to_gdb_from_pid; /* fifo name to read pid replies */
13583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Returns True in case read/write operations were done properly.
13593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns False in case of error.
13603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   from_pid is the file descriptor to read data from the process pid. */
13613b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
13623b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool read_from_pid_write_to_gdb(int from_pid)
13633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
13643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   char buf[PBUFSIZ];
13653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int nrread;
13663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
13673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   nrread = read_buf(from_pid, buf, "from pid");
13683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (nrread <= 0) {
13693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (nrread == 0)
13703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         DEBUG(1, "read 0 bytes from pid => assume exit\n");
13713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      else
13723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         DEBUG(1, "error reading bytes from pid\n");
13733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      close (from_pid);
13743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      shutting_down = True;
13753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
13763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
13773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return write_buf(to_gdb, buf, nrread, "to_gdb", /* notify */ False);
13783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
13793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
13803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* prepares the FIFOs filenames, map the shared memory. */
13813b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
13823b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid prepare_fifos_and_shared_mem(int pid)
13833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
13843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   from_gdb_to_pid = vmalloc (strlen(vgdb_prefix) + 30);
13853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   to_gdb_from_pid = vmalloc (strlen(vgdb_prefix) + 30);
13863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   shared_mem      = vmalloc (strlen(vgdb_prefix) + 30);
13873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* below 3 lines must match the equivalent in remote-utils.c */
13883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sprintf(from_gdb_to_pid, "%s-from-vgdb-to-%d",    vgdb_prefix, pid);
13893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sprintf(to_gdb_from_pid, "%s-to-vgdb-from-%d",    vgdb_prefix, pid);
13903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sprintf(shared_mem,      "%s-shared-mem-vgdb-%d", vgdb_prefix, pid);
13913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG (1, "vgdb: using %s %s %s\n",
13923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj          from_gdb_to_pid, to_gdb_from_pid, shared_mem);
13933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
13943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   map_vgdbshared(shared_mem);
13953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
13963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
13973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Convert hex digit A to a number.  */
13983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
13993b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int
14003b290486cd4cd601b20e04340e593c9ed9717e5fsewardjfromhex (int a)
14013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
14023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (a >= '0' && a <= '9')
14033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return a - '0';
14043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else if (a >= 'a' && a <= 'f')
14053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return a - 'a' + 10;
14063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else
14073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR(0, "Reply contains invalid hex digit %c\n", a);
14083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  return 0;
14093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
14103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
14113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Returns next char from fd.  -1 if error, -2 if EOF.
14123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   NB: must always call it with the same fd */
14133b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int
14143b290486cd4cd601b20e04340e593c9ed9717e5fsewardjreadchar (int fd)
14153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
14163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  static unsigned char buf[PBUFSIZ];
14173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  static int bufcnt = 0;
14183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  static unsigned char *bufp;
14193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
14203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  if (bufcnt-- > 0)
14213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     return *bufp++;
14223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
14233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  bufcnt = read (fd, buf, sizeof (buf));
14243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
14253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  if (bufcnt <= 0) {
14263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     if (bufcnt == 0) {
14273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        fprintf (stderr, "readchar: Got EOF\n");
14283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        return -2;
14293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     } else {
14303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        ERROR (errno, "readchar\n");
14313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        return -1;
14323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     }
14333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  }
14343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
14353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  bufp = buf;
14363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  bufcnt--;
14373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  return *bufp++;
14383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
14393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
14403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Read a packet from fromfd, with error checking,
14413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   and store it in BUF.
14423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns length of packet, or -1 if error or -2 if EOF.
14433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Writes ack on ackfd */
14443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
14453b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int
14463b290486cd4cd601b20e04340e593c9ed9717e5fsewardjgetpkt (char *buf, int fromfd, int ackfd)
14473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
14483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  char *bp;
14493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  unsigned char csum, c1, c2;
14503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  int c;
14513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
14523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  while (1) {
14533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     csum = 0;
14543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
14553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     while (1) {
14563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        c = readchar (fromfd);
14573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        if (c == '$')
14583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           break;
14593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        DEBUG(2, "[getpkt: discarding char '%c']\n", c);
14603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        if (c < 0)
14613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           return c;
14623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     }
14633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
14643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     bp = buf;
14653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     while (1) {
14663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        c = readchar (fromfd);
14673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        if (c < 0)
14683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           return c;
14693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        if (c == '#')
14703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           break;
14713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        if (c == '*') {
14723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           int repeat;
14733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           int r;
14743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           int prev;
14753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           prev = *(bp-1);
14763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           csum += c;
14773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           repeat = readchar (fromfd);
14783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           csum += repeat;
14793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           for (r = 0; r < repeat - 29; r ++)
14803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              *bp++ = prev;
14813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        } else {
14823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           *bp++ = c;
14833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           csum += c;
14843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        }
14853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     }
14863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     *bp = 0;
14873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
14883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     c1 = fromhex (readchar (fromfd));
14893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     c2 = fromhex (readchar (fromfd));
14903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
14913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     if (csum == (c1 << 4) + c2)
14923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj	break;
14933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
14943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
14953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              (c1 << 4) + c2, csum, buf);
14963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     if (write (ackfd, "-", 1) != 1)
14973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        ERROR(0, "error when writing - (nack)\n");
14983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     else
14993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        add_written(1);
15003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  }
15013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  DEBUG(2, "getpkt (\"%s\");  [sending ack] \n", buf);
15033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  if (write (ackfd, "+", 1) != 1)
15043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     ERROR(0, "error when writing + (ack)\n");
15053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  else
15063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     add_written(1);
15073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  return bp - buf;
15083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
15093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15103b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sigint = 0;
15113b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sigterm = 0;
15123b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sigpipe = 0;
15133b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sighup = 0;
15143b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sigusr1 = 0;
15153b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sigalrm = 0;
15163b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sigusr1_fd = -1;
15173b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic pthread_t invoke_gdbserver_in_valgrind_thread;
15183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15193b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
15203b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid received_signal (int signum)
15213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
15223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (signum == SIGINT)
15233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sigint++;
15243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else if (signum == SIGUSR1) {
15253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sigusr1++;
15263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (sigusr1_fd >= 0) {
15273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         char control_c = '\003';
15283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         write_buf(sigusr1_fd, &control_c, 1,
15293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   "write \\003 on SIGUSR1", /* notify */ True);
15303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
15313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
15323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else if (signum == SIGTERM) {
15333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      shutting_down = True;
15343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sigterm++;
15353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else if (signum == SIGHUP) {
15363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      shutting_down = True;
15373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sighup++;
15383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else if (signum == SIGPIPE) {
15393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sigpipe++;
15403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else if (signum == SIGALRM) {
15413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sigalrm++;
15423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "pthread_cancel invoke_gdbserver_in_valgrind_thread\n");
15433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* Note: we cannot directly invoke restore_and_detach : this must
15443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         be done by the thread that has attached.
15453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         We have in this thread pushed a cleanup handler that will
15463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         cleanup what is needed. */
15473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pthread_cancel(invoke_gdbserver_in_valgrind_thread);
15483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else {
15493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      ERROR(0, "unexpected signal %d\n", signum);
15503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
15513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
15523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* install the signal handlers allowing e.g. vgdb to cleanup in
15543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case of termination. */
15553b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
15563b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid install_handlers(void)
15573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
15583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   struct sigaction action, oldaction;
15593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   action.sa_handler = received_signal;
15613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sigemptyset (&action.sa_mask);
15623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   action.sa_flags = 0;
15633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* SIGINT: when user types C-c in gdb, this sends
15653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      a SIGINT to vgdb + causes a character to be sent to remote gdbserver.
15663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      The later is enough to wakeup the valgrind process. */
15673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (sigaction (SIGINT, &action, &oldaction) != 0)
15683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "vgdb error sigaction SIGINT\n");
15693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* We might do something more intelligent than just
15703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      reporting this SIGINT E.g. behave similarly to the gdb: two
15713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      control-C without feedback from the debugged process would
15723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      mean to stop debugging it. */
15733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* SIGUSR1: this is used to facilitate automatic testing.  When
15753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      vgdb receives this signal, it will simulate the user typing C-c. */
15763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (sigaction (SIGUSR1, &action, &oldaction) != 0)
15773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "vgdb error sigaction SIGUSR1\n");
15783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* SIGTERM: can receive this signal (e.g. from gdb) to terminate vgdb
15813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      when detaching or similar. A clean shutdown will be done as both
15823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      the read and write side will detect an end of file. */
15833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (sigaction (SIGTERM, &action, &oldaction) != 0)
15843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "vgdb error sigaction SIGTERM\n");
15853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* SIGPIPE: can receive this signal when gdb detaches or kill the
15873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      process debugged: gdb will close its pipes to vgdb. vgdb
15883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      must resist to this signal to allow a clean shutdown. */
15893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (sigaction (SIGPIPE, &action, &oldaction) != 0)
15903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "vgdb error sigaction SIGPIPE\n");
15913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* SIGALRM: in case invoke thread is blocked, alarm is used
15933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      to cleanup.  */
15943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (sigaction (SIGALRM, &action, &oldaction) != 0)
15953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "vgdb error sigaction SIGALRM\n");
15963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
15973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* close the FIFOs provided connections, terminate the invoker thread.  */
15993b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
16003b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid close_connection(int to_pid, int from_pid)
16013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
16023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(1, "nr received signals: sigint %d sigterm %d sighup %d sigpipe %d\n",
16033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         sigint, sigterm, sighup, sigpipe);
16043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Note that we do not forward sigterm to the valgrind process:
16053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      a sigterm signal is (probably) received from gdb if the user wants to
16063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      kill the debugged process. The kill instruction has been given to
16073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      the valgrind process, which should execute a clean exit. */
16083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
16093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* We first close the connection to pid. The pid will then
16103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      terminates its gdbserver work. We keep the from pid
16113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      fifo opened till the invoker thread is finished.
16123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      This allows the gdbserver to finish sending its last reply. */
16133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (close(to_pid) != 0)
16143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      ERROR(errno, "close to_pid\n");
16153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
16163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* if there is a task that was busy trying to wake up valgrind
16173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      process, we wait for it to be terminated otherwise threads
16183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      in the valgrind process can stay stopped if vgdb main
16193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      exits before the invoke thread had time to detach from
16203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      all valgrind threads. */
162130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   if (max_invoke_ms > 0 || cmd_time_out != NEVER) {
16223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      int join;
16233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
16243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* It is surprisingly complex to properly shutdown or exit the
16253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         valgrind process in which gdbserver has been invoked through
16263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ptrace.  In the normal case (gdb detaches from the process,
16273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         or process is continued), the valgrind process will reach the
16283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         breakpoint place.  Using ptrace, vgdb will ensure the
16293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         previous activity of the process is resumed (e.g. restart a
16303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         blocking system call).  The special case is when gdb asks the
16313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         valgrind process to exit (using either the "kill" command or
16323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         "monitor exit").  In such a case, the valgrind process will
16333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         call exit.  But a ptraced process will be blocked in exit,
16343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         waiting for the ptracing process to detach or die. vgdb
16353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         cannot detach unconditionally as otherwise, in the normal
1636b2572b52b37d56d302408395f7fed9f509423af1sewardj         case, the valgrind process would stop abnormally with SIGSTOP
16373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         (as vgdb would not be there to catch it). vgdb can also not
16383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         die unconditionally otherwise again, similar problem.  So, we
16393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         assume that most of the time, we arrive here in the normal
16403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         case, and so, the breakpoint has been encountered by the
16413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         valgrind process, so the invoker thread will exit and the
16423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         join will succeed.  For the "kill" case, we cause an alarm
16433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         signal to be sent after a few seconds. This means that in the
16443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         normal case, the gdbserver code in valgrind process must have
16453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         returned the control in less than the alarm nr of seconds,
1646b2572b52b37d56d302408395f7fed9f509423af1sewardj         otherwise, valgrind will stop abnormally with SIGSTOP. */
16473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      (void) alarm (3);
16483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
16493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "joining with invoke_gdbserver_in_valgrind_thread\n");
16503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      join = pthread_join(invoke_gdbserver_in_valgrind_thread, NULL);
16513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (join != 0)
16523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         XERROR
16533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            (join,
16543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj             "vgdb error pthread_join invoke_gdbserver_in_valgrind_thread\n");
16553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
16563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (close(from_pid) != 0)
16573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      ERROR(errno, "close from_pid\n");
16583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
16593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
16603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Relay data between gdb and Valgrind gdbserver, till EOF or an
16613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   error is encountered. */
16623b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
16633b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid gdb_relay (int pid)
16643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
16653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int from_pid = -1; /* fd to read from pid */
16663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int to_pid = -1; /* fd to write to pid */
16673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
16683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int shutdown_loop = 0;
16693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   fprintf (stderr, "relaying data between gdb and process %d\n", pid);
16703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   fflush (stderr);
16713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
16723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (max_invoke_ms > 0)
16733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pthread_create(&invoke_gdbserver_in_valgrind_thread, NULL,
16743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     invoke_gdbserver_in_valgrind, (void *) &pid);
16753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   to_pid = open_fifo(from_gdb_to_pid, O_WRONLY, "write to pid");
16763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   acquire_lock (shared_mem_fd, pid);
16773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
16783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   from_pid = open_fifo (to_gdb_from_pid, O_RDONLY|O_NONBLOCK,
16793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                         "read mode from pid");
16803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
16813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sigusr1_fd = to_pid; /* allow simulating user typing control-c */
16823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
16833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   while (1) {
16843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      ConnectionKind ck;
16853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      int ret;
16863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      struct pollfd pollfds[NumConnectionKind];
16873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
16883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* watch data written by gdb, watch POLLERR on both gdb fd */
16893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[FROM_GDB].fd = from_gdb;
16903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[FROM_GDB].events = POLLIN;
16913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[FROM_GDB].revents = 0;
16923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[TO_GDB].fd = to_gdb;
16933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[TO_GDB].events = 0;
16943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[TO_GDB].revents = 0;
16953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
16963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* watch data written by pid, watch POLLERR on both pid fd */
16973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[FROM_PID].fd = from_pid;
16983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[FROM_PID].events = POLLIN;
16993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[FROM_PID].revents = 0;
17003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[TO_PID].fd = to_pid;
17013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[TO_PID].events = 0;
17023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[TO_PID].revents = 0;
17033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
17043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      ret = poll(pollfds,
17053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                 NumConnectionKind,
17063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                 (shutting_down ?
17073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  1 /* one second */
17083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  : -1 /* infinite */));
17093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(2, "poll ret %d errno %d\n", ret, errno);
17103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
17113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* check for unexpected error */
17123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (ret <= 0 && errno != EINTR) {
17133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR (errno, "unexpected poll ret %d\n", ret);
17143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         shutting_down = True;
17153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         break;
17163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
17173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
17183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* check for data to read */
17193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      for (ck = 0; ck < NumConnectionKind; ck ++) {
17203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (pollfds[ck].revents & POLLIN) {
17213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            switch (ck) {
17223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            case FROM_GDB:
17233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               if (!read_from_gdb_write_to_pid(to_pid))
17243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  shutting_down = True;
17253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               break;
17263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               case FROM_PID:
17273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  if (!read_from_pid_write_to_gdb(from_pid))
17283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     shutting_down = True;
17293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  break;
17303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            default: XERROR(0, "unexpected POLLIN on %s\n",
17313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                               ppConnectionKind(ck));
17323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            }
17333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
17343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
17353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
17363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* check for an fd being in error condition */
17373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      for (ck = 0; ck < NumConnectionKind; ck ++) {
17383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (pollfds[ck].revents & POLLERR) {
17393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(1, "connection %s fd %d POLLERR error condition\n",
17403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     ppConnectionKind(ck), pollfds[ck].fd);
17413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            valgrind_dying();
17423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            shutting_down = True;
17433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
17443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (pollfds[ck].revents & POLLHUP) {
17453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(1, "connection %s fd %d POLLHUP error condition\n",
17463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  ppConnectionKind(ck), pollfds[ck].fd);
17473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            valgrind_dying();
17483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            shutting_down = True;
17493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
17503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (pollfds[ck].revents & POLLNVAL) {
17513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(1, "connection %s fd %d POLLNVAL error condition\n",
17523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  ppConnectionKind(ck), pollfds[ck].fd);
17533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            valgrind_dying();
17543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            shutting_down = True;
17553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
17563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
17573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
17583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (shutting_down) {
17593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         /* we let some time to the final packets to be transferred */
17603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         shutdown_loop++;
17613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (shutdown_loop > 3)
17623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            break;
17633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
17643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
17653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   close_connection(to_pid, from_pid);
17663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
17673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
17683b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int packet_len_for_command(char *cmd)
17693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
17703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* cmd will be send as a packet $qRcmd,xxxx....................xx#cc      */
17713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return                          7+     2*strlen(cmd)             +3  + 1;
17723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
17733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
17743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* hyper-minimal protocol implementation that
17753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sends the provided commands (using qRcmd packets)
17763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   and read and display their replies. */
17773b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
17783b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid standalone_send_commands(int pid,
17793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                              int last_command,
17803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                              char *commands[] )
17813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
17823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int from_pid = -1; /* fd to read from pid */
17833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int to_pid = -1; /* fd to write to pid */
17843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
17853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int i;
17863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int hi;
17873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   unsigned char hex[3];
17883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   unsigned char cksum;
17893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   unsigned char *hexcommand;
17903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   unsigned char buf[PBUFSIZ];
17913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int buflen;
17923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int nc;
17933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
17943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
179530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   if (max_invoke_ms > 0 || cmd_time_out != NEVER)
17963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pthread_create(&invoke_gdbserver_in_valgrind_thread, NULL,
17973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     invoke_gdbserver_in_valgrind, (void *) &pid);
17983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
17993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   to_pid = open_fifo(from_gdb_to_pid, O_WRONLY, "write to pid");
18003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   acquire_lock (shared_mem_fd, pid);
18013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
18023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* first send a C-c \003 to pid, so that it wakes up the process
18033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      After that, we can open the fifo from the pid in read mode
18043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      We then start to wait for packets (normally first a resume reply)
18053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      At that point, we send our command and expect replies */
18063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   buf[0] = '\003';
18073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   write_buf(to_pid, buf, 1, "write \\003 to wake up", /* notify */ True);
18083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   from_pid = open_fifo(to_gdb_from_pid, O_RDONLY,
18093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                        "read cmd result from pid");
18103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
18113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   for (nc = 0; nc <= last_command; nc++) {
18123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      fprintf (stderr, "sending command %s to pid %d\n", commands[nc], pid);
18133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      fflush (stderr);
18143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
18153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* prepare hexcommand $qRcmd,xxxx....................xx#cc      */
18163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      hexcommand = vmalloc (packet_len_for_command(commands[nc]));
18173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      hexcommand[0] = 0;
18183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      strcat (hexcommand, "$qRcmd,");
18193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      for (i = 0; i < strlen(commands[nc]); i++) {
18203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         sprintf(hex, "%02x", commands[nc][i]);
18213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         strcat (hexcommand, hex);
18223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
18233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* checksum (but without the $) */
18243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      cksum = 0;
18253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      for (hi = 1; hi < strlen(hexcommand); hi++)
18263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         cksum+=hexcommand[hi];
18273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      strcat(hexcommand, "#");
18283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sprintf(hex, "%02x", cksum);
18293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      strcat(hexcommand, hex);
18303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      write_buf(to_pid, hexcommand, strlen(hexcommand),
18313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                "writing hex command to pid", /* notify */ True);
18323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
18333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* we exit of the below loop explicitely when the command has
18343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         been handled or because a signal handler will set
18353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         shutting_down. */
18363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      while (!shutting_down) {
18373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         buflen = getpkt(buf, from_pid, to_pid);
18383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (buflen < 0) {
18393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            ERROR (0, "error reading packet\n");
18403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            if (buflen == -2)
18413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               valgrind_dying();
18423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            break;
18433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
18443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (strlen(buf) == 0) {
18453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(0, "empty packet rcvd (packet qRcmd not recognised?)\n");
18463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            break;
18473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
18483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (strcmp(buf, "OK") == 0) {
18493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(1, "OK packet rcvd\n");
18503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            break;
18513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
18523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (buf[0] == 'E') {
18533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(0,
18543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  "E NN error packet rcvd: %s (unknown monitor command?)\n",
18553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  buf);
18563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            break;
18573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
18583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (buf[0] == 'W') {
18593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(0, "W stopped packet rcvd: %s\n", buf);
18603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            break;
18613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
18623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (buf[0] == 'T') {
18633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(1, "T resume reply packet received: %s\n", buf);
18643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            continue;
18653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
18663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
18673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         /* must be here an O packet with hex encoded string reply
18683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            => decode and print it */
18693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (buf[0] != 'O') {
18703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(0, "expecting O packet, received: %s\n", buf);
18713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            continue;
18723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
18733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         {
18743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            char buf_print[buflen/2 + 1];
18753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            for (i = 1; i < buflen; i = i + 2)
18763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               buf_print[i/2] = (fromhex(*(buf+i)) << 4)
18773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     + fromhex(*(buf+i+1));
18783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            buf_print[buflen/2] = 0;
18793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            printf("%s", buf_print);
18803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            fflush(stdout);
18813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
18823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
18833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      free (hexcommand);
18843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
18853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   shutting_down = True;
18863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
18873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   close_connection(to_pid, from_pid);
18883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
18893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
18903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* report to user the existence of a vgdb-able valgrind process
18913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   with given pid */
18923b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
189330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardjvoid report_pid (int pid, Bool on_stdout)
18943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
18953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   char cmdline_file[100];
18963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   char cmdline[1000];
18973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int fd;
18983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int i, sz;
18993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
19003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sprintf(cmdline_file, "/proc/%d/cmdline", pid);
19013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   fd = open (cmdline_file, O_RDONLY);
19023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (fd == -1) {
19033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "error opening cmdline file %s %s\n",
19043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            cmdline_file, strerror(errno));
19053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sprintf(cmdline, "(could not obtain process command line)");
19063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else {
19073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sz = read(fd, cmdline, 1000);
19083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      for (i = 0; i < sz; i++)
19093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (cmdline[i] == 0)
19103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            cmdline[i] = ' ';
19113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      cmdline[sz] = 0;
1912d8c12f178d9d03b934ce10d6fcb45c27503889dcsewardj      close (fd);
19133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
191430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   fprintf((on_stdout ? stdout : stderr), "use --pid=%d for %s\n", pid, cmdline);
191530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   fflush((on_stdout ? stdout : stderr));
19163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
19173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
191830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj/* Possibly produces additional usage information documenting the
19193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   ptrace restrictions. */
19203b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
192130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardjvoid ptrace_restrictions_msg(void)
19223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
19233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#  ifdef PR_SET_PTRACER
19243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   char *ptrace_scope_setting_file = "/proc/sys/kernel/yama/ptrace_scope";
19253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int fd = -1;
19263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   char ptrace_scope = 'X';
19273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   fd = open (ptrace_scope_setting_file, O_RDONLY, 0);
19283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (fd >= 0 && (read (fd, &ptrace_scope, 1) == 1) && (ptrace_scope != '0')) {
19293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      fprintf (stderr,
19303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               "Note: your kernel restricts ptrace invoker using %s\n"
19313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               "vgdb will only be able to attach to a Valgrind process\n"
19323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               "blocked in a system call *after* an initial successful attach\n",
19333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               ptrace_scope_setting_file);
19343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else if (ptrace_scope == 'X') {
1935d142f99836471d4245250247cc9ac7bc5a1391fasewardj      DEBUG (1,
1936d142f99836471d4245250247cc9ac7bc5a1391fasewardj             "PR_SET_PTRACER defined"
1937d142f99836471d4245250247cc9ac7bc5a1391fasewardj             " but could not determine ptrace scope from %s\n",
1938d142f99836471d4245250247cc9ac7bc5a1391fasewardj             ptrace_scope_setting_file);
19393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
19403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (fd >= 0)
19413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      close (fd);
19423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#  endif
19433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
19443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#  ifndef PTRACEINVOKER
19453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   fprintf(stderr,
19463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           "Note: ptrace invoker not implemented\n"
19473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           "For more info: read user manual section"
19483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           " 'Limitations of the Valgrind gdbserver'\n");
19493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#  endif
19503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
19513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
19523b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
19533b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid usage(void)
19543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
19553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   fprintf(stderr,
19563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"Usage: vgdb [OPTION]... [[-c] COMMAND]...\n"
19573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"vgdb (valgrind gdb) has two usages\n"
19583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"  1. standalone to send monitor commands to a Valgrind gdbserver.\n"
19593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"     The OPTION(s) must be followed by the command to send\n"
19603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"     To send more than one command, separate the commands with -c\n"
19613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"  2. relay application between gdb and a Valgrind gdbserver.\n"
19623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"     Only OPTION(s) can be given.\n"
19633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"\n"
19643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj" OPTIONS are [--pid=<number>] [--vgdb-prefix=<prefix>]\n"
196530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"             [--wait=<number>] [--max-invoke-ms=<number>]\n"
196630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"             [--cmd-time-out=<number>] [-l] [-D] [-d]\n"
196730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"             \n"
19683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"  --pid arg must be given if multiple Valgrind gdbservers are found.\n"
19693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"  --vgdb-prefix arg must be given to both Valgrind and vgdb utility\n"
19703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"      if you want to change the default prefix for the FIFOs communication\n"
19713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"      between the Valgrind gdbserver and vgdb.\n"
197230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"  --wait (default 0) tells vgdb to check during the specified number\n"
19733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"      of seconds if a Valgrind gdbserver can be found.\n"
197430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"  --max-invoke-ms (default 100) gives the nr of milli-seconds after which vgdb\n"
197530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"      will force the invocation of the Valgrind gdbserver (if the Valgrind\n"
197630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"         process is blocked in a system call).\n"
197730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"  --cmd-time-out (default 99999999) tells vgdb to exit if the found Valgrind\n"
197830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"     gdbserver has not processed a command after number seconds\n"
1979d142f99836471d4245250247cc9ac7bc5a1391fasewardj"  -l  arg tells to show the list of running Valgrind gdbserver and then exit.\n"
198030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"  -D  arg tells to show shared mem status and then exit.\n"
198130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"  -d  arg tells to show debug info. Multiple -d args for more debug info\n"
1982d142f99836471d4245250247cc9ac7bc5a1391fasewardj"\n"
1983d142f99836471d4245250247cc9ac7bc5a1391fasewardj"  -h --help shows this message\n"
1984d142f99836471d4245250247cc9ac7bc5a1391fasewardj"  To get help from the Valgrind gdbserver, use vgdb help\n"
19853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"\n"
19863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           );
198730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   ptrace_restrictions_msg();
19883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
19893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
199030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj/* If show_list, outputs on stdout the list of Valgrind processes with gdbserver activated.
1991d142f99836471d4245250247cc9ac7bc5a1391fasewardj                 and then exits.
1992d142f99836471d4245250247cc9ac7bc5a1391fasewardj
1993d142f99836471d4245250247cc9ac7bc5a1391fasewardj   else if arg_pid == -1, waits maximum check_trials seconds to discover
19943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   a valgrind pid appearing.
1995d142f99836471d4245250247cc9ac7bc5a1391fasewardj
19963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Otherwise verify arg_pid is valid and corresponds to a Valgrind process
19973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   with gdbserver activated.
19983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
19993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns the pid to work with
20003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   or exits in case of error (e.g. no pid found corresponding to arg_pid */
20013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
20023b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
2003d142f99836471d4245250247cc9ac7bc5a1391fasewardjint search_arg_pid(int arg_pid, int check_trials, Bool show_list)
20043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
20053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int i;
20063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int pid = -1;
20073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
20083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (arg_pid == 0 || arg_pid < -1) {
20093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      fprintf (stderr, "vgdb error: invalid pid %d given\n", arg_pid);
20103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      exit (1);
20113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else {
20123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* search for a matching named fifo.
20133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         If we have been given a pid, we will check that the matching FIFO is
20143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         there (or wait the nr of check_trials for this to appear).
20153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         If no pid has been given, then if we find only one FIFO,
20163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         we will use this to build the pid to use.
20173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         If we find multiple processes with valid FIFO, we report them and will
20183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         exit with an error. */
20193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DIR *vgdb_dir;
20203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      char *vgdb_dir_name = vmalloc (strlen (vgdb_prefix) + 3);
20213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      struct dirent *f;
20223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      int is;
20233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      int nr_valid_pid = 0;
20243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      const char *suffix = "-from-vgdb-to-"; /* followed by pid */
20253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      char *vgdb_format = vmalloc (strlen(vgdb_prefix) + strlen(suffix) + 1);
20263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
20273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      strcpy (vgdb_format, vgdb_prefix);
20283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      strcat (vgdb_format, suffix);
20293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
20303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      strcpy (vgdb_dir_name, vgdb_prefix);
20313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
20323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      for (is = strlen(vgdb_prefix) - 1; is >= 0; is--)
20333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (vgdb_dir_name[is] == '/') {
20343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            vgdb_dir_name[is+1] = '\0';
20353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            break;
20363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
20373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (strlen(vgdb_dir_name) == 0)
20383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         strcpy (vgdb_dir_name, "./");
20393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
20403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "searching pid in directory %s format %s\n",
20413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            vgdb_dir_name, vgdb_format);
20423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
20433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* try to find FIFOs with valid pid.
20443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         On exit of the loop, pid is set to:
2045d142f99836471d4245250247cc9ac7bc5a1391fasewardj         the last pid found if show_list (or -1 if no process was listed)
20463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         -1 if no FIFOs matching a running process is found
20473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         -2 if multiple FIFOs of running processes are found
20483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         otherwise it is set to the (only) pid found that can be debugged
20493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      */
20503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      for (i = 0; i < check_trials; i++) {
20513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         DEBUG(1, "check_trial %d \n", i);
20523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (i > 0)
20533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           /* wait one second before checking again */
20543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           sleep(1);
20553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
20563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         vgdb_dir = opendir (vgdb_dir_name);
20573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (vgdb_dir == NULL)
20583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            XERROR (errno,
20593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                    "vgdb error: opening directory %s searching vgdb fifo\n",
20603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                    vgdb_dir_name);
20613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
20623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         errno = 0; /* avoid complain if vgdb_dir is empty */
20633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         while ((f = readdir (vgdb_dir))) {
20643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            struct stat st;
20653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            char pathname[strlen(vgdb_dir_name) + strlen(f->d_name)];
20663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            char *wrongpid;
20673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            int newpid;
20683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
20693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            strcpy (pathname, vgdb_dir_name);
20703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            strcat (pathname, f->d_name);
20713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(3, "trying %s\n", pathname);
20723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            if (stat (pathname, &st) != 0) {
20733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               if (debuglevel >= 3)
20743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  ERROR (errno, "vgdb error: stat %s searching vgdb fifo\n",
20753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                         pathname);
20763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            } else if (S_ISFIFO (st.st_mode)) {
20773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               DEBUG(3, "trying %s\n", pathname);
20783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               if (strncmp (pathname, vgdb_format,
20793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                            strlen (vgdb_format)) == 0) {
20803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  newpid = strtol(pathname + strlen (vgdb_format),
20813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                                  &wrongpid, 10);
20823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  if (*wrongpid == '\0' && newpid > 0
20833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                      && kill (newpid, 0) == 0) {
20843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     nr_valid_pid++;
2085d142f99836471d4245250247cc9ac7bc5a1391fasewardj                     if (show_list) {
208630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj                        report_pid (newpid, /*on_stdout*/ True);
2087d142f99836471d4245250247cc9ac7bc5a1391fasewardj                        pid = newpid;
2088d142f99836471d4245250247cc9ac7bc5a1391fasewardj                     } else if (arg_pid != -1) {
20893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                        if (arg_pid == newpid) {
20903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                           pid = newpid;
20913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                        }
20923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     } else if (nr_valid_pid > 1) {
20933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                        if (nr_valid_pid == 2) {
20943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                           fprintf
20953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                              (stderr,
20963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                               "no --pid= arg given"
20973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                               " and multiple valgrind pids found:\n");
209830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj                           report_pid (pid, /*on_stdout*/ False);
20993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                        }
21003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                        pid = -2;
210130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj                        report_pid (newpid, /*on_stdout*/ False);
21023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     } else {
21033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                        pid = newpid;
21043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     }
21053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  }
21063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               }
21073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            }
21083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            errno = 0; /* avoid complain if at the end of vgdb_dir */
21093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
21103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (f == NULL && errno != 0)
21113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            XERROR (errno, "vgdb error: reading directory %s for vgdb fifo\n",
21123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                    vgdb_dir_name);
21133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
21143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         closedir (vgdb_dir);
21153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (pid != -1)
21163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            break;
21173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
21183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
21193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      free (vgdb_dir_name);
21203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      free (vgdb_format);
21213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
2122d142f99836471d4245250247cc9ac7bc5a1391fasewardj
2123d142f99836471d4245250247cc9ac7bc5a1391fasewardj   if (show_list) {
2124d142f99836471d4245250247cc9ac7bc5a1391fasewardj      exit (1);
2125d142f99836471d4245250247cc9ac7bc5a1391fasewardj   } else if (pid == -1) {
21263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (arg_pid == -1)
21273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         fprintf (stderr, "vgdb error: no FIFO found and no pid given\n");
21283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      else
21293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         fprintf (stderr, "vgdb error: no FIFO found matching pid %d\n",
21303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  arg_pid);
21313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      exit (1);
21323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
21333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else if (pid == -2) {
21343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* no arg_pid given, multiple FIFOs found */
21353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      exit (1);
21363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
21373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else {
21383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return pid;
21393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
21403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
21413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
21423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* return true if the numeric value of an option of the
21433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   form --xxxxxxxxx=<number> could properly be extracted
21443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   from arg. If True is returned, *value contains the
21453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   extracted value.*/
21463b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
21473b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool numeric_val(char* arg, int *value)
21483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
21493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   const char *eq_pos = strchr(arg, '=');
21503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   char *wrong;
215130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   long long int long_value;
21523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
21533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (eq_pos == NULL)
21543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
21553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
215630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   long_value = strtoll(eq_pos+1, &wrong, 10);
215730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   if (long_value < 0 || long_value > INT_MAX)
215830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      return False;
21593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (*wrong)
21603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
21613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
216230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   *value = (int) long_value;
21633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return True;
21643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
21653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
21663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* true if arg matches the provided option */
21673b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
21683b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool is_opt(char* arg, char *option)
21693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
21703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int option_len = strlen(option);
21713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (option[option_len-1] == '=')
21723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return (0 == strncmp(option, arg, option_len));
21733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else
21743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return (0 == strcmp(option, arg));
21753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
21763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
21773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Parse command lines options. If error(s), exits.
21783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Otherwise returns the options in *p_... args.
21793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   commands must be big enough for the commands extracted from argv.
21803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   On return, *p_last_command gives the position in commands where
21813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   the last command has been allocated (using vmalloc). */
21823b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
21833b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid parse_options(int argc, char** argv,
21843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   Bool *p_show_shared_mem,
2185d142f99836471d4245250247cc9ac7bc5a1391fasewardj                   Bool *p_show_list,
21863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   int *p_arg_pid,
21873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   int *p_check_trials,
21883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   int *p_last_command,
21893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   char *commands[])
21903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
21913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Bool show_shared_mem = False;
2192d142f99836471d4245250247cc9ac7bc5a1391fasewardj   Bool show_list = False;
21933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int arg_pid = -1;
21943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int check_trials = 1;
21953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int last_command = -1;
21963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
21973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int i;
21983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int arg_errors = 0;
21993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
22003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   for (i = 1; i < argc; i++) {
22013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (is_opt(argv[i], "--help") || is_opt(argv[i], "-h")) {
22023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         usage();
22033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         exit(0);
22043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else if (is_opt(argv[i], "-d")) {
22053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         debuglevel++;
22063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else if (is_opt(argv[i], "-D")) {
22073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         show_shared_mem = True;
2208d142f99836471d4245250247cc9ac7bc5a1391fasewardj      } else if (is_opt(argv[i], "-l")) {
2209d142f99836471d4245250247cc9ac7bc5a1391fasewardj         show_list = True;
22103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else if (is_opt(argv[i], "--pid=")) {
22113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         int newpid;
22123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (!numeric_val(argv[i], &newpid)) {
221330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            fprintf (stderr, "invalid --pid argument %s\n", argv[i]);
22143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            arg_errors++;
22153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         } else if (arg_pid != -1) {
221630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            fprintf (stderr, "multiple --pid arguments given\n");
22173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            arg_errors++;
22183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         } else {
22193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            arg_pid = newpid;
22203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
22213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else if (is_opt(argv[i], "--wait=")) {
22223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (!numeric_val(argv[i], &check_trials)) {
222330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            fprintf (stderr, "invalid --wait argument %s\n", argv[i]);
22243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            arg_errors++;
22253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
22263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else if (is_opt(argv[i], "--max-invoke-ms=")) {
22273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (!numeric_val(argv[i], &max_invoke_ms)) {
222830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            fprintf (stderr, "invalid --max-invoke-ms argument %s\n", argv[i]);
222930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            arg_errors++;
223030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         }
223130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      } else if (is_opt(argv[i], "--cmd-time-out=")) {
223230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         if (!numeric_val(argv[i], &cmd_time_out)) {
223330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            fprintf (stderr, "invalid --cmd-time-out argument %s\n", argv[i]);
22343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            arg_errors++;
22353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
22363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else if (is_opt(argv[i], "--vgdb-prefix=")) {
22373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         vgdb_prefix = argv[i] + 14;
22383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else if (is_opt(argv[i], "-c")) {
22393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         last_command++;
22403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         commands[last_command] = vmalloc (1);
22413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         commands[last_command][0] = '\0';
22423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else if (0 == strncmp(argv[i], "-", 1)) {
22433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         fprintf (stderr, "unknown or invalid argument %s\n", argv[i]);
22443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         arg_errors++;
22453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else {
22463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         int len;
22473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (last_command == -1) {
22483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            /* only one command, no -c command indicator */
22493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            last_command++;
22503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            commands[last_command] = vmalloc (1);
22513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            commands[last_command][0] = '\0';
22523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
22533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         len = strlen(commands[last_command]);
22543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         commands[last_command] = vrealloc (commands[last_command],
22553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                                            len + 1 + strlen(argv[i]) + 1);
22563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (len > 0)
22573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            strcat (commands[last_command], " ");
22583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         strcat (commands[last_command], argv[i]);
22593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (packet_len_for_command(commands[last_command]) > PBUFSIZ) {
22603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            fprintf (stderr, "command %s too long\n", commands[last_command]);
22613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            arg_errors++;
22623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
22633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
22643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
22653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
2266d142f99836471d4245250247cc9ac7bc5a1391fasewardj
2267d142f99836471d4245250247cc9ac7bc5a1391fasewardj   if (isatty(0)
2268d142f99836471d4245250247cc9ac7bc5a1391fasewardj       && !show_shared_mem
2269d142f99836471d4245250247cc9ac7bc5a1391fasewardj       && !show_list
2270d142f99836471d4245250247cc9ac7bc5a1391fasewardj       && last_command == -1) {
2271d142f99836471d4245250247cc9ac7bc5a1391fasewardj      arg_errors++;
2272d142f99836471d4245250247cc9ac7bc5a1391fasewardj      fprintf (stderr,
2273d142f99836471d4245250247cc9ac7bc5a1391fasewardj               "Using vgdb standalone implies to give -D or -l or a COMMAND\n");
2274d142f99836471d4245250247cc9ac7bc5a1391fasewardj   }
2275d142f99836471d4245250247cc9ac7bc5a1391fasewardj
2276d142f99836471d4245250247cc9ac7bc5a1391fasewardj   if (show_shared_mem && show_list) {
2277d142f99836471d4245250247cc9ac7bc5a1391fasewardj      arg_errors++;
2278d142f99836471d4245250247cc9ac7bc5a1391fasewardj      fprintf (stderr,
2279d142f99836471d4245250247cc9ac7bc5a1391fasewardj               "Can't use both -D and -l options\n");
2280d142f99836471d4245250247cc9ac7bc5a1391fasewardj   }
2281d142f99836471d4245250247cc9ac7bc5a1391fasewardj
228230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   if (max_invoke_ms > 0
228330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj       && cmd_time_out != NEVER
228430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj       && (cmd_time_out * 1000) <= max_invoke_ms) {
228530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      arg_errors++;
228630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      fprintf (stderr,
228730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj               "--max-invoke-ms must be < --cmd-time-out * 1000\n");
228830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   }
228930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj
2290d142f99836471d4245250247cc9ac7bc5a1391fasewardj   if (show_list && arg_pid != -1) {
2291d142f99836471d4245250247cc9ac7bc5a1391fasewardj      arg_errors++;
2292d142f99836471d4245250247cc9ac7bc5a1391fasewardj      fprintf (stderr,
2293d142f99836471d4245250247cc9ac7bc5a1391fasewardj               "Can't use both --pid and -l options\n");
2294d142f99836471d4245250247cc9ac7bc5a1391fasewardj   }
2295d142f99836471d4245250247cc9ac7bc5a1391fasewardj
22963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (arg_errors > 0) {
22973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      fprintf (stderr, "args error. Try `vgdb --help` for more information\n");
22983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      exit(1);
22993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
23003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
23013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   *p_show_shared_mem = show_shared_mem;
2302d142f99836471d4245250247cc9ac7bc5a1391fasewardj   *p_show_list = show_list;
23033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   *p_arg_pid = arg_pid;
23043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   *p_check_trials = check_trials;
23053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   *p_last_command = last_command;
23063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
23073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
23083b290486cd4cd601b20e04340e593c9ed9717e5fsewardjint main(int argc, char** argv)
23093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
23103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int i;
23113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int pid;
23123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
23133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Bool show_shared_mem;
2314d142f99836471d4245250247cc9ac7bc5a1391fasewardj   Bool show_list;
23153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int arg_pid;
23163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int check_trials;
23173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int last_command;
23183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   char *commands[argc]; // we will never have more commands than args.
23193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
23203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   parse_options(argc, argv,
23213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                 &show_shared_mem,
2322d142f99836471d4245250247cc9ac7bc5a1391fasewardj                 &show_list,
23233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                 &arg_pid,
23243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                 &check_trials,
23253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                 &last_command,
23263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                 commands);
23273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
23283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* when we are working as a relay for gdb, handle some signals by
23293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      only reporting them (according to debug level). Also handle these
23303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      when ptrace will be used: vgdb must clean up the ptrace effect before
23313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      dying. */
23323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (max_invoke_ms > 0 || last_command == -1)
23333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      install_handlers();
23343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2335d142f99836471d4245250247cc9ac7bc5a1391fasewardj   pid = search_arg_pid (arg_pid, check_trials, show_list);
23363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
23373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   prepare_fifos_and_shared_mem(pid);
23383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
23393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (show_shared_mem) {
23403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      fprintf(stderr,
23413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              "vgdb %d "
23423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              "written_by_vgdb %d "
23433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              "seen_by_valgrind %d\n"
23443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              "vgdb pid %d\n",
23453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              VS_vgdb_pid,
23463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              VS_written_by_vgdb,
23473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              VS_seen_by_valgrind,
23483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              VS_vgdb_pid);
23493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      exit (0);
23503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
23513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
23523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (last_command >= 0) {
23533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      standalone_send_commands(pid, last_command, commands);
23543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else {
23553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      gdb_relay(pid);
23563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
23573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
23583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
23593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   free (from_gdb_to_pid);
23603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   free (to_gdb_from_pid);
23613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   free (shared_mem);
23623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
23633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   for (i = 0; i <= last_command; i++)
23643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      free (commands[i]);
23653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return 0;
23663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
23670ba37c90c4674515da387b30a6e5f23fa75a173csewardj
23680ba37c90c4674515da387b30a6e5f23fa75a173csewardj#endif /* !defined(VGPV_arm_linux_android) */
2369