vgdb.c revision ae52a9398788dfa1b4d51b03013e8665268ad6df
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
29cbe385015145f16e3e88f919d8979df628a535easewardj#include "pub_core_basics.h"
30cbe385015145f16e3e88f919d8979df628a535easewardj#include "pub_core_vki.h"
31cbe385015145f16e3e88f919d8979df628a535easewardj#include "pub_core_libcsetjmp.h"
32cbe385015145f16e3e88f919d8979df628a535easewardj#include "pub_core_threadstate.h"
33cbe385015145f16e3e88f919d8979df628a535easewardj#include "pub_core_gdbserver.h"
34b985e2de52983cafd2d17cc6c9e60064847777fdflorian#include "config.h"
35cbe385015145f16e3e88f919d8979df628a535easewardj
3630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj#include <limits.h>
3756501b67e44eb4d012449e16aafe49d885b557f1sewardj#include <unistd.h>
383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <string.h>
393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <poll.h>
403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <pthread.h>
413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <stdlib.h>
423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <stdio.h>
433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <fcntl.h>
443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <dirent.h>
453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <sys/stat.h>
463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <sys/time.h>
473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <errno.h>
48e7f8f3f669763ac7b4f83428771f563ba55d74e2sewardj#include <signal.h>
49992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#include <sys/types.h>
50992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#include <sys/socket.h>
51992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#include <netinet/in.h>
52992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#include <arpa/inet.h>
533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <sys/mman.h>
543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <sys/ptrace.h>
553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <sys/wait.h>
56cbe385015145f16e3e88f919d8979df628a535easewardj#include <assert.h>
573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* vgdb has two usages:
583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   1. relay application between gdb and the gdbserver embedded in valgrind.
593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   2. standalone to send monitor commands to a running valgrind-ified process
603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   It is made of a main program which reads arguments.  If no
623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   arguments are given or only --pid and --vgdb-prefix, then usage 1 is
633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   assumed.
643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   As relay application, vgdb reads bytes from gdb on stdin and
663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   writes these bytes to valgrind.  Bytes read from valgrind are
673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   written to gdb on stdout.  Read/Write from/to valgrind is done
683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   using FIFOs.  There is one thread reading from stdin, writing to
693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   valgrind on a FIFO.  There is one thread reading from valgrind on a
703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   FIFO, writing to gdb on stdout
713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   As a standalone utility, vgdb builds command packets to write to valgrind,
733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sends it and reads the reply. The same two threads are used to write/read.
743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Once all the commands are sent and their replies received, vgdb will exit.
753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj*/
773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* define PTRACEINVOKER to compile the ptrace related code
793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   which ensures a valgrind process blocked in a system call
803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   can be "waken up". PTRACEINVOKER implies some architecture
813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   specific code and/or some OS specific code. */
823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if defined(VGA_arm) || defined(VGA_x86) || defined(VGA_amd64) \
833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj    || defined(VGA_ppc32) || defined(VGA_ppc64) || defined(VGA_s390x)
843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define PTRACEINVOKER
853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#else
863b290486cd4cd601b20e04340e593c9ed9717e5fsewardjI_die_here : (PTRACEINVOKER) architecture missing in vgdb.c
873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif
883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Some darwin specific stuff is needed as ptrace is not
903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   fully supported on MacOS. Till we find someone courageous
913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   having access to Darwin, there is no PTRACEINVOKER. */
923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if defined(VGO_darwin)
933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#undef PTRACEINVOKER
943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif
953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
96992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#if defined(VGPV_arm_linux_android)
97992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#undef PTRACEINVOKER
98992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#endif
99992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj
100992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#if defined(PTRACEINVOKER)
101992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#include <sys/user.h>
102992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#if defined(VGO_linux)
103992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#  include <sys/prctl.h>
104992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#  include <linux/ptrace.h>
105992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#endif
106992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#endif
107992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj
108992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj
10930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj// Outputs information for the user about ptrace_scope protection
11030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj// or ptrace not working.
11130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardjstatic void ptrace_restrictions_msg(void);
11230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj
1133b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int debuglevel;
1143b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic struct timeval dbgtv;
1153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* if level <= debuglevel, print timestamp, then print provided by debug info */
1163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define DEBUG(level, ...) (level <= debuglevel ?                        \
1173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                           gettimeofday(&dbgtv, NULL),                  \
1183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                           fprintf(stderr, "%ld.%6.6ld ",               \
1193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                                   (long int)dbgtv.tv_sec,              \
1203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                                   (long int)dbgtv.tv_usec),            \
1213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                           fprintf(stderr, __VA_ARGS__),fflush(stderr)  \
1223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                           : 0)
1233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* same as DEBUG but does not print time stamp info */
1253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define PDEBUG(level, ...) (level <= debuglevel ?                       \
1263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                            fprintf(stderr, __VA_ARGS__),fflush(stderr) \
1273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                            : 0)
1283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* if errno != 0,
1303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   report the errno and fprintf the ... varargs on stderr. */
1313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define ERROR(errno, ...) ((errno == 0 ? 0 : perror("syscall failed")), \
1323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                           fprintf(stderr, __VA_ARGS__),                \
1333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                           fflush(stderr))
1343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* same as ERROR, but also exits with status 1 */
1353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define XERROR(errno, ...) ((errno == 0 ? 0 : perror("syscall failed")), \
1363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                            fprintf(stderr, __VA_ARGS__),                \
1373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                            fflush(stderr),                              \
1383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                            exit(1))
1393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
140b985e2de52983cafd2d17cc6c9e60064847777fdflorianstatic char *vgdb_prefix = NULL;
1413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Will be set to True when any condition indicating we have to shutdown
1433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   is encountered. */
1443b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic Bool shutting_down = False;
1453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1463b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic VgdbShared32 *shared32;
1473b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic VgdbShared64 *shared64;
1483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define VS_written_by_vgdb (shared32 != NULL ?        \
1493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                            shared32->written_by_vgdb \
1503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                            : shared64->written_by_vgdb)
1513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define VS_seen_by_valgrind (shared32 != NULL ?         \
1523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                             shared32->seen_by_valgrind \
1533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                             : shared64->seen_by_valgrind)
1543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define VS_vgdb_pid (shared32 != NULL ? shared32->vgdb_pid : shared64->vgdb_pid)
1563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Calls malloc (size). Exits if memory can't be allocated. */
1583b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
1593b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid *vmalloc(size_t size)
1603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
1613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   void * mem = malloc(size);
1623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (mem == NULL)
1633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "can't allocate memory\n");
1643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return mem;
1653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
1663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Calls realloc (size). Exits if memory can't be allocated. */
1683b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
1693b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid *vrealloc(void *ptr,size_t size)
1703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
1713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   void * mem = realloc(ptr, size);
1723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (mem == NULL)
1733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "can't reallocate memory\n");
1743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return mem;
1753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
1763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
177b985e2de52983cafd2d17cc6c9e60064847777fdflorian/* Return the name of a directory for temporary files. */
178b985e2de52983cafd2d17cc6c9e60064847777fdflorianstatic
179b985e2de52983cafd2d17cc6c9e60064847777fdflorianconst char *vgdb_tmpdir(void)
180b985e2de52983cafd2d17cc6c9e60064847777fdflorian{
181b985e2de52983cafd2d17cc6c9e60064847777fdflorian   const char *tmpdir;
182b985e2de52983cafd2d17cc6c9e60064847777fdflorian
183b985e2de52983cafd2d17cc6c9e60064847777fdflorian   tmpdir = getenv("TMPDIR");
184ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe   if (tmpdir == NULL || *tmpdir == '\0')
185ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe     tmpdir = VG_TMPDIR;
186ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe   if (tmpdir == NULL || *tmpdir == '\0')
187ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe     tmpdir = "/tmp";    /* fallback */
188b985e2de52983cafd2d17cc6c9e60064847777fdflorian
189b985e2de52983cafd2d17cc6c9e60064847777fdflorian   return tmpdir;
190b985e2de52983cafd2d17cc6c9e60064847777fdflorian}
191b985e2de52983cafd2d17cc6c9e60064847777fdflorian
192ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe/* Return the default path prefix for the named pipes (FIFOs) used by vgdb/gdb
193b985e2de52983cafd2d17cc6c9e60064847777fdflorian   to communicate with valgrind */
194b985e2de52983cafd2d17cc6c9e60064847777fdflorianstatic
195b985e2de52983cafd2d17cc6c9e60064847777fdflorianchar *vgdb_prefix_default(void)
196b985e2de52983cafd2d17cc6c9e60064847777fdflorian{
197ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe   static HChar *prefix;
198ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe
199ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe   if (prefix == NULL) {
200ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe      const char *tmpdir = vgdb_tmpdir();
201ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe      prefix = vmalloc(strlen(tmpdir) + strlen("/vgdb-pipe") + 1);
202ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe      strcpy(prefix, tmpdir);
203ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe      strcat(prefix, "/vgdb-pipe");
204ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe   }
205b985e2de52983cafd2d17cc6c9e60064847777fdflorian   return prefix;
206b985e2de52983cafd2d17cc6c9e60064847777fdflorian}
207b985e2de52983cafd2d17cc6c9e60064847777fdflorian
2083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* add nrw to the written_by_vgdb field of shared32 or shared64 */
2093b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
2103b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid add_written(int nrw)
2113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
2123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (shared32 != NULL)
2133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      shared32->written_by_vgdb += nrw;
2143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else if (shared64 != NULL)
2153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      shared64->written_by_vgdb += nrw;
2163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else
2173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      assert(0);
2183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
2193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2203b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int shared_mem_fd = -1;
2213b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
2223b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid map_vgdbshared (char* shared_mem)
2233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
2243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   struct stat fdstat;
2253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   void **s;
2263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   shared_mem_fd = open(shared_mem, O_RDWR);
2273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* shared_mem_fd will not be closed till vgdb exits. */
2283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (shared_mem_fd == -1)
2303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "error opening %s shared memory file\n", shared_mem);
2313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (fstat(shared_mem_fd, &fdstat) != 0)
2333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "fstat");
2343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (fdstat.st_size == sizeof(VgdbShared64))
2363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      s = (void*) &shared64;
2373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else if (fdstat.st_size == sizeof(VgdbShared32))
2383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      s = (void*) &shared32;
2393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else
2403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if VEX_HOST_WORDSIZE == 8
2413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (0,
2423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              "error size shared memory file %s.\n"
2433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              "expecting size %d (64bits) or %d (32bits) got %ld.\n",
2443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              shared_mem,
2453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              (int) sizeof(VgdbShared64), (int) sizeof(VgdbShared32),
2463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              (long int)fdstat.st_size);
2473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif VEX_HOST_WORDSIZE == 4
2483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (0,
2493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              "error size shared memory file %s.\n"
2503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              "expecting size %d (32bits) got %ld.\n",
2513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              shared_mem,
2523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              (int) sizeof(VgdbShared32),
2533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              fdstat.st_size);
2543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#else
2553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj# error "unexpected wordsize"
2563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif
2573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if VEX_HOST_WORDSIZE == 4
2593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (shared64 != NULL)
2603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (0, "cannot use 32 bits vgdb with a 64bits valgrind process\n");
2613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* But we can use a 64 bits vgdb with a 32 bits valgrind */
2623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif
2633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   *s = (void*) mmap (NULL, fdstat.st_size,
2653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                      PROT_READ|PROT_WRITE, MAP_SHARED,
2663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                      shared_mem_fd, 0);
2673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (*s == (void *) -1)
2693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "error mmap shared memory file %s\n", shared_mem);
2703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
2723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if VEX_HOST_WORDSIZE == 8
2743b290486cd4cd601b20e04340e593c9ed9717e5fsewardjtypedef Addr64 CORE_ADDR;
2753b290486cd4cd601b20e04340e593c9ed9717e5fsewardjtypedef Addr64 PTRACE_XFER_TYPE;
2763b290486cd4cd601b20e04340e593c9ed9717e5fsewardjtypedef void* PTRACE_ARG3_TYPE;
2773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif VEX_HOST_WORDSIZE == 4
2783b290486cd4cd601b20e04340e593c9ed9717e5fsewardjtypedef Addr32 CORE_ADDR;
2793b290486cd4cd601b20e04340e593c9ed9717e5fsewardjtypedef Addr32 PTRACE_XFER_TYPE;
2803b290486cd4cd601b20e04340e593c9ed9717e5fsewardjtypedef void* PTRACE_ARG3_TYPE;
2813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#else
2823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj# error "unexpected wordsize"
2833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif
2843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2853b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic Bool pid_of_save_regs_continued = False;
2863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj// True if we have continued pid_of_save_regs after PTRACE_ATTACH
2873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2883b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic Bool dying = False;
2893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj// Set to True when loss of connection indicating that the Valgrind
2903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj// process is dying.
2913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* To be called when connection with valgrind is lost.  In case we
2933b290486cd4cd601b20e04340e593c9ed9717e5fsewardjhave lost the connection, it means that Valgrind has closed the
2943b290486cd4cd601b20e04340e593c9ed9717e5fsewardjconnection and is busy exiting. We can't and don't have to stop it in
2953b290486cd4cd601b20e04340e593c9ed9717e5fsewardjthis case. */
2963b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
2973b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid valgrind_dying(void)
2983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
2993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   pid_of_save_regs_continued = False;
3003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   dying = True;
3013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
3023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#ifdef PTRACEINVOKER
3053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* ptrace_(read|write)_memory are modified extracts of linux-low.c
3063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   from gdb 6.6. Copyrighted FSF */
3073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Copy LEN bytes from inferior's memory starting at MEMADDR
3083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   to debugger memory starting at MYADDR.  */
3093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3103b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
3113b290486cd4cd601b20e04340e593c9ed9717e5fsewardjint ptrace_read_memory (pid_t inferior_pid, CORE_ADDR memaddr,
3123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                        unsigned char *myaddr, int len)
3133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
3143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   register int i;
3153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Round starting address down to longword boundary.  */
3163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
3173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Round ending address up; get number of longwords that makes.  */
3183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   register int count
3193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
3203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      / sizeof (PTRACE_XFER_TYPE);
3213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Allocate buffer of that many longwords.  */
3223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   register PTRACE_XFER_TYPE *buffer
3233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
3243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Read all the longwords */
3263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) {
3273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      errno = 0;
3283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      buffer[i] = ptrace (PTRACE_PEEKTEXT, inferior_pid,
3293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                          (PTRACE_ARG3_TYPE) addr, 0);
3303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (errno)
3313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return errno;
3323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
3333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Copy appropriate bytes out of the buffer.  */
3353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   memcpy (myaddr,
3363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), len);
3373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return 0;
3393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
3403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Copy LEN bytes of data from debugger memory at MYADDR
3423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   to inferior's memory at MEMADDR.
3433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   On failure (cannot write the inferior)
3443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   returns the value of errno.  */
3453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3463b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
3473b290486cd4cd601b20e04340e593c9ed9717e5fsewardjint ptrace_write_memory (pid_t inferior_pid, CORE_ADDR memaddr,
3483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                         const unsigned char *myaddr, int len)
3493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
3503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   register int i;
3513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Round starting address down to longword boundary.  */
3523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
3533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Round ending address up; get number of longwords that makes.  */
3543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   register int count
3553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
3563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      / sizeof (PTRACE_XFER_TYPE);
3573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Allocate buffer of that many longwords.  */
3583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   register PTRACE_XFER_TYPE *buffer
3593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
3603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (debuglevel >= 1) {
3623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG (1, "Writing ");
3633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      for (i = 0; i < len; i++)
3643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         PDEBUG (1, "%02x", (unsigned)myaddr[i]);
3653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      PDEBUG(1, " to %p\n", (void *) memaddr);
3663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
3673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Fill start and end extra bytes of buffer with existing memory data.  */
3693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   buffer[0] = ptrace (PTRACE_PEEKTEXT, inferior_pid,
3713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                       (PTRACE_ARG3_TYPE) addr, 0);
3723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (count > 1) {
3743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      buffer[count - 1]
3753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         = ptrace (PTRACE_PEEKTEXT, inferior_pid,
3763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   (PTRACE_ARG3_TYPE) (addr + (count - 1)
3773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                                       * sizeof (PTRACE_XFER_TYPE)),
3783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   0);
3793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
3803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Copy data to be written over corresponding part of buffer */
3823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)),
3843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           myaddr, len);
3853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Write the entire buffer.  */
3873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) {
3893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      errno = 0;
3903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      ptrace (PTRACE_POKETEXT, inferior_pid,
3913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              (PTRACE_ARG3_TYPE) addr, buffer[i]);
3923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (errno)
3933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return errno;
3943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
3953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return 0;
3973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
3983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* subset of VG_(threads) needed for vgdb ptrace.
4003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   This is initialized when process is attached. */
4013b290486cd4cd601b20e04340e593c9ed9717e5fsewardjtypedef struct {
4023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   ThreadStatus status;
4033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Int lwpid;
4043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
4053b290486cd4cd601b20e04340e593c9ed9717e5fsewardjVgdbThreadState;
4063b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic VgdbThreadState vgdb_threads[VG_N_THREADS];
4073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4083b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic const
4093b290486cd4cd601b20e04340e593c9ed9717e5fsewardjHChar* name_of_ThreadStatus ( ThreadStatus status )
4103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
4113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   switch (status) {
4123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case VgTs_Empty:     return "VgTs_Empty";
4133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case VgTs_Init:      return "VgTs_Init";
4143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case VgTs_Runnable:  return "VgTs_Runnable";
4153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case VgTs_WaitSys:   return "VgTs_WaitSys";
4163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case VgTs_Yielding:  return "VgTs_Yielding";
4173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case VgTs_Zombie:    return "VgTs_Zombie";
4183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   default:             return "VgTs_???";
4193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  }
4203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
4213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4223b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
4233b290486cd4cd601b20e04340e593c9ed9717e5fsewardjchar *status_image (int status)
4243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
4253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   static char result[256];
4263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int sz = 0;
4273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define APPEND(...) sz += snprintf (result+sz, 256 - sz - 1, __VA_ARGS__)
4283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   result[0] = 0;
4303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (WIFEXITED(status))
4323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      APPEND ("WIFEXITED %d ", WEXITSTATUS(status));
4333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (WIFSIGNALED(status)) {
4353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      APPEND ("WIFSIGNALED %d ", WTERMSIG(status));
4363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (WCOREDUMP(status)) APPEND ("WCOREDUMP ");
4373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
4383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (WIFSTOPPED(status))
4403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      APPEND ("WIFSTOPPED %d ", WSTOPSIG(status));
4413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (WIFCONTINUED(status))
4433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      APPEND ("WIFCONTINUED ");
4443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return result;
4463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#undef APPEND
4473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
4483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Wait till the process pid is reported as stopped with signal_expected.
4503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   If other signal(s) than signal_expected are received, waitstopped
4513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   will pass them to pid, waiting for signal_expected to stop pid.
4523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns True when process is in stopped state with signal_expected.
4533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns False if a problem was encountered while waiting for pid
4543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   to be stopped.
4553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   If pid is reported as being dead/exited, waitstopped will return False.
4573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj*/
4583b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
4593b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool waitstopped (int pid, int signal_expected, char *msg)
4603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
4613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   pid_t p;
4623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int status = 0;
4633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int signal_received;
4643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int res;
4653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   while (1) {
4673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "waitstopped %s before waitpid signal_expected %d\n",
4683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            msg, signal_expected);
4693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      p = waitpid(pid, &status, __WALL);
4703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "after waitpid pid %d p %d status 0x%x %s\n", pid, p,
4713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            status, status_image (status));
4723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (p != pid) {
4733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR(errno, "%s waitpid pid %d in waitstopped %d status 0x%x %s\n",
4743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               msg, pid, p, status, status_image (status));
4753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
4763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
4773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (WIFEXITED(status)) {
4793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         shutting_down = True;
4803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
4813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
4823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      assert (WIFSTOPPED(status));
4843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      signal_received = WSTOPSIG(status);
4853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (signal_received == signal_expected)
4863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         break;
4873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* pid received a signal which is not the signal we are waiting for.
4893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         We continue pid, transmitting this signal. */
4903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "waitstopped PTRACE_CONT with signal %d\n", signal_received);
4913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      res = ptrace (PTRACE_CONT, pid, NULL, signal_received);
4923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (res != 0) {
4933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR(errno, "waitstopped PTRACE_CONT\n");
4943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
4953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
4963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
4973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return True;
4993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
5003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
5013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Stops the given pid, wait for the process to be stopped.
5023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns True if succesful, False otherwise.
5033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   msg is used in tracing and error reporting. */
5043b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
5053b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool stop (int pid, char *msg)
5063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
5073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   long res;
5083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
5093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(1, "%s SIGSTOP pid %d\n", msg, pid);
5103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   res = kill (pid, SIGSTOP);
5113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (res != 0) {
5123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      ERROR(errno, "%s SIGSTOP pid %d %ld\n", msg, pid, res);
5133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
5143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
5153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
5163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return waitstopped (pid, SIGSTOP, msg);
5173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
5183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
5193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
5203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Attaches to given pid, wait for the process to be stopped.
5213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns True if succesful, False otherwise.
5223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   msg is used in tracing and error reporting. */
5233b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
5243b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool attach (int pid, char *msg)
5253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
5263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   long res;
52730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   static Bool output_error = True;
52830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   static Bool initial_attach = True;
52930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   // For a ptrace_scope protected system, we do not want to output
53030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   // repetitively attach error. We will output once an error
53130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   // for the initial_attach. Once the 1st attach has succeeded, we
53230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   // again show all errors.
5333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
5343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(1, "%s PTRACE_ATTACH pid %d\n", msg, pid);
5353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   res = ptrace (PTRACE_ATTACH, pid, NULL, NULL);
5363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (res != 0) {
53730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      if (output_error || debuglevel > 0) {
53830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         ERROR(errno, "%s PTRACE_ATTACH pid %d %ld\n", msg, pid, res);
53930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         if (initial_attach)
54030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            output_error = False;
54130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      }
5423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
5433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
5443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
54530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   initial_attach = False;
54630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   output_error = True;
5473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return waitstopped(pid, SIGSTOP, msg);
5483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
5493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
5503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* once we are attached to the pid, get the list of threads and stop
5513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   them all.
5523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns True if all threads properly suspended, False otherwise. */
5533b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
5543b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool acquire_and_suspend_threads(int pid)
5553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
5563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int i;
5573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int rw;
5583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Bool pid_found = False;
5593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Addr vgt;
5603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int sz_tst;
5613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int off_status;
5623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int off_lwpid;
5633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int nr_live_threads = 0;
5643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
5653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (shared32 != NULL) {
5663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      vgt = shared32->threads;
5673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sz_tst = shared32->sizeof_ThreadState;
5683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      off_status = shared32->offset_status;
5693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      off_lwpid = shared32->offset_lwpid;
5703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
5713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else if (shared64 != NULL) {
5723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      vgt = shared64->threads;
5733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sz_tst = shared64->sizeof_ThreadState;
5743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      off_status = shared64->offset_status;
5753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      off_lwpid = shared64->offset_lwpid;
5763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else {
5773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      assert (0);
5783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
5793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
5803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* note: the entry 0 is unused */
5813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   for (i = 1; i < VG_N_THREADS; i++) {
5823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      vgt += sz_tst;
5833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      rw = ptrace_read_memory(pid, vgt+off_status,
5843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                              (unsigned char *)&(vgdb_threads[i].status),
5853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                              sizeof(ThreadStatus));
5863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (rw != 0) {
5873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR(rw, "status ptrace_read_memory\n");
5883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
5893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
5903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
5913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      rw = ptrace_read_memory(pid, vgt+off_lwpid,
5923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                              (unsigned char *)&(vgdb_threads[i].lwpid),
5933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                              sizeof(Int));
5943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (rw != 0) {
5953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR(rw, "lwpid ptrace_read_memory\n");
5963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
5973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
5983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
5993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (vgdb_threads[i].status != VgTs_Empty) {
6003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         DEBUG(1, "found tid %d status %s lwpid %d\n",
6013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               i, name_of_ThreadStatus(vgdb_threads[i].status),
6023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               vgdb_threads[i].lwpid);
6033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         nr_live_threads++;
6043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (vgdb_threads[i].lwpid <= 1) {
6053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            if (vgdb_threads[i].lwpid == 0
6063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                && vgdb_threads[i].status == VgTs_Init) {
6073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               DEBUG(1, "not set lwpid tid %d status %s lwpid %d\n",
6083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     i, name_of_ThreadStatus(vgdb_threads[i].status),
6093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     vgdb_threads[i].lwpid);
6103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            } else {
6113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               ERROR(1, "unexpected lwpid tid %d status %s lwpid %d\n",
6123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     i, name_of_ThreadStatus(vgdb_threads[i].status),
6133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     vgdb_threads[i].lwpid);
6143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            }
6153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            /* in case we have a VtTs_Init thread with lwpid not yet set,
6163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               we try again later. */
6173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            return False;
6183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
6193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (vgdb_threads[i].lwpid == pid) {
6203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            assert (!pid_found);
6213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            assert (i == 1);
6223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            pid_found = True;
6233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         } else {
6243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            if (!attach(vgdb_threads[i].lwpid, "attach_thread")) {
6253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                 ERROR(0, "ERROR attach pid %d tid %d\n",
6263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                       vgdb_threads[i].lwpid, i);
6273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               return False;
6283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            }
6293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
6303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
6313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
6323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* If we found no thread, it means the process is stopping, and
6333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      we better do not force anything to happen during that. */
6343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (nr_live_threads > 0)
6353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return True;
6363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else
6373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
6383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
6393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
6403b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
6413b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid detach_from_all_threads(int pid)
6423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
6433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int i;
6443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   long res;
6453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Bool pid_found = False;
6463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
6473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* detach from all the threads  */
6483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   for (i = 1; i < VG_N_THREADS; i++) {
6493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (vgdb_threads[i].status != VgTs_Empty) {
6503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (vgdb_threads[i].status == VgTs_Init
6513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj             && vgdb_threads[i].lwpid == 0) {
6523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(1, "skipping PTRACE_DETACH pid %d tid %d status %s\n",
6533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  vgdb_threads[i].lwpid, i,
6543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  name_of_ThreadStatus (vgdb_threads[i].status));
6553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         } else {
6563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            if (vgdb_threads[i].lwpid == pid) {
6573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               assert (!pid_found);
6583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               pid_found = True;
6593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            }
6603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(1, "PTRACE_DETACH pid %d tid %d status %s\n",
6613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  vgdb_threads[i].lwpid, i,
6623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  name_of_ThreadStatus (vgdb_threads[i].status));
6633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            res = ptrace (PTRACE_DETACH, vgdb_threads[i].lwpid, NULL, NULL);
6643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            if (res != 0) {
6653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               ERROR(errno, "PTRACE_DETACH pid %d tid %d status %s res %ld\n",
6663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     vgdb_threads[i].lwpid, i,
6673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     name_of_ThreadStatus (vgdb_threads[i].status),
6683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     res);
6693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            }
6703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
6713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
6723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
6733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
6743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (!pid_found && pid) {
6753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* No threads are live. Process is busy stopping.
6763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         We need to detach from pid explicitely. */
6773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "no thread live => PTRACE_DETACH pid %d\n", pid);
6783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      res = ptrace (PTRACE_DETACH, pid, NULL, NULL);
6793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (res != 0)
6803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR(errno, "PTRACE_DETACH pid %d res %ld\n", pid, res);
6813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
6823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
6833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
6843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj// if > 0, pid for which registers have to be restored.
6853b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int pid_of_save_regs = 0;
6863b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic struct user user_save;
6873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
688eefeeb7a60a347bc851605fadd52672cbd927201sewardj// The below indicates if ptrace_getregs (and ptrace_setregs) can be used.
689eefeeb7a60a347bc851605fadd52672cbd927201sewardj// Note that some linux versions are defining PTRACE_GETREGS but using
690eefeeb7a60a347bc851605fadd52672cbd927201sewardj// it gives back EIO.
691eefeeb7a60a347bc851605fadd52672cbd927201sewardj// has_working_ptrace_getregs can take the following values:
692eefeeb7a60a347bc851605fadd52672cbd927201sewardj//  -1 : PTRACE_GETREGS is defined
693eefeeb7a60a347bc851605fadd52672cbd927201sewardj//       runtime check not yet done.
694eefeeb7a60a347bc851605fadd52672cbd927201sewardj//   0 : PTRACE_GETREGS runtime check has failed.
695eefeeb7a60a347bc851605fadd52672cbd927201sewardj//   1 : PTRACE_GETREGS defined and runtime check ok.
696eefeeb7a60a347bc851605fadd52672cbd927201sewardj#ifdef PTRACE_GETREGS
697eefeeb7a60a347bc851605fadd52672cbd927201sewardjstatic int has_working_ptrace_getregs = -1;
698eefeeb7a60a347bc851605fadd52672cbd927201sewardj#endif
699eefeeb7a60a347bc851605fadd52672cbd927201sewardj
7003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Get the registers from pid into regs.
701eefeeb7a60a347bc851605fadd52672cbd927201sewardj   regs_bsz value gives the length of *regs.
7023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns True if all ok, otherwise False. */
7033b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
704eefeeb7a60a347bc851605fadd52672cbd927201sewardjBool getregs (int pid, void *regs, long regs_bsz)
7053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
706eefeeb7a60a347bc851605fadd52672cbd927201sewardj   DEBUG(1, "getregs regs_bsz %ld\n", regs_bsz);
707eefeeb7a60a347bc851605fadd52672cbd927201sewardj#  ifdef PTRACE_GETREGS
708eefeeb7a60a347bc851605fadd52672cbd927201sewardj   if (has_working_ptrace_getregs) {
709eefeeb7a60a347bc851605fadd52672cbd927201sewardj      // Platforms having GETREGS
710eefeeb7a60a347bc851605fadd52672cbd927201sewardj      long res;
711eefeeb7a60a347bc851605fadd52672cbd927201sewardj      DEBUG(1, "getregs PTRACE_GETREGS\n");
712eefeeb7a60a347bc851605fadd52672cbd927201sewardj      res = ptrace (PTRACE_GETREGS, pid, NULL, regs);
713eefeeb7a60a347bc851605fadd52672cbd927201sewardj      if (res == 0) {
714eefeeb7a60a347bc851605fadd52672cbd927201sewardj         if (has_working_ptrace_getregs == -1) {
715eefeeb7a60a347bc851605fadd52672cbd927201sewardj            // First call to PTRACE_GETREGS succesful =>
716eefeeb7a60a347bc851605fadd52672cbd927201sewardj            has_working_ptrace_getregs = 1;
717eefeeb7a60a347bc851605fadd52672cbd927201sewardj            DEBUG(1, "detected a working PTRACE_GETREGS\n");
718eefeeb7a60a347bc851605fadd52672cbd927201sewardj         }
719eefeeb7a60a347bc851605fadd52672cbd927201sewardj         assert (has_working_ptrace_getregs == 1);
720eefeeb7a60a347bc851605fadd52672cbd927201sewardj         return True;
721eefeeb7a60a347bc851605fadd52672cbd927201sewardj      }
722eefeeb7a60a347bc851605fadd52672cbd927201sewardj      else if (has_working_ptrace_getregs == 1) {
723eefeeb7a60a347bc851605fadd52672cbd927201sewardj         // We had a working call, but now it fails.
724eefeeb7a60a347bc851605fadd52672cbd927201sewardj         // This is unexpected.
725eefeeb7a60a347bc851605fadd52672cbd927201sewardj         ERROR(errno, "PTRACE_GETREGS %ld\n", res);
7263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
727eefeeb7a60a347bc851605fadd52672cbd927201sewardj      } else {
728eefeeb7a60a347bc851605fadd52672cbd927201sewardj         // Check this is the first call:
729eefeeb7a60a347bc851605fadd52672cbd927201sewardj         assert (has_working_ptrace_getregs == -1);
730eefeeb7a60a347bc851605fadd52672cbd927201sewardj         if (errno == EIO) {
731eefeeb7a60a347bc851605fadd52672cbd927201sewardj            DEBUG(1, "detected a broken PTRACE_GETREGS with EIO\n");
732eefeeb7a60a347bc851605fadd52672cbd927201sewardj            has_working_ptrace_getregs = 0;
733eefeeb7a60a347bc851605fadd52672cbd927201sewardj            // Fall over to the PTRACE_PEEKUSER case.
734eefeeb7a60a347bc851605fadd52672cbd927201sewardj         } else {
735eefeeb7a60a347bc851605fadd52672cbd927201sewardj            ERROR(errno, "broken PTRACE_GETREGS unexpected errno %ld\n", res);
736eefeeb7a60a347bc851605fadd52672cbd927201sewardj            return False;
737eefeeb7a60a347bc851605fadd52672cbd927201sewardj         }
7383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
7393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
7403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#  endif
741eefeeb7a60a347bc851605fadd52672cbd927201sewardj
742eefeeb7a60a347bc851605fadd52672cbd927201sewardj   // We assume  PTRACE_PEEKUSER is defined everywhere.
743eefeeb7a60a347bc851605fadd52672cbd927201sewardj   {
744eefeeb7a60a347bc851605fadd52672cbd927201sewardj#     ifdef PT_ENDREGS
745eefeeb7a60a347bc851605fadd52672cbd927201sewardj      long peek_bsz = PT_ENDREGS;
746eefeeb7a60a347bc851605fadd52672cbd927201sewardj      assert (peek_bsz <= regs_bsz);
747eefeeb7a60a347bc851605fadd52672cbd927201sewardj#     else
748eefeeb7a60a347bc851605fadd52672cbd927201sewardj      long peek_bsz = regs_bsz-1;
749eefeeb7a60a347bc851605fadd52672cbd927201sewardj#     endif
750eefeeb7a60a347bc851605fadd52672cbd927201sewardj      char *pregs = (char *) regs;
751eefeeb7a60a347bc851605fadd52672cbd927201sewardj      long offset;
752eefeeb7a60a347bc851605fadd52672cbd927201sewardj      errno = 0;
753eefeeb7a60a347bc851605fadd52672cbd927201sewardj      DEBUG(1, "getregs PTRACE_PEEKUSER(s) peek_bsz %ld\n", peek_bsz);
754eefeeb7a60a347bc851605fadd52672cbd927201sewardj      for (offset = 0; offset < peek_bsz; offset = offset + sizeof(long)) {
755eefeeb7a60a347bc851605fadd52672cbd927201sewardj         *(long *)(pregs+offset) = ptrace(PTRACE_PEEKUSER, pid, offset, NULL);
756eefeeb7a60a347bc851605fadd52672cbd927201sewardj         if (errno != 0) {
757eefeeb7a60a347bc851605fadd52672cbd927201sewardj            ERROR(errno, "PTRACE_PEEKUSER offset %ld\n", offset);
758eefeeb7a60a347bc851605fadd52672cbd927201sewardj            return False;
759eefeeb7a60a347bc851605fadd52672cbd927201sewardj         }
760eefeeb7a60a347bc851605fadd52672cbd927201sewardj      }
761eefeeb7a60a347bc851605fadd52672cbd927201sewardj      return True;
762eefeeb7a60a347bc851605fadd52672cbd927201sewardj   }
763eefeeb7a60a347bc851605fadd52672cbd927201sewardj
764eefeeb7a60a347bc851605fadd52672cbd927201sewardj   // If neither PTRACE_GETREGS not PTRACE_PEEKUSER have returned,
765eefeeb7a60a347bc851605fadd52672cbd927201sewardj   // then we are in serious trouble.
766eefeeb7a60a347bc851605fadd52672cbd927201sewardj   assert (0);
7673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
7683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
7693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Set the registers of pid to regs.
770eefeeb7a60a347bc851605fadd52672cbd927201sewardj   regs_bsz value gives the length of *regs.
7713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns True if all ok, otherwise False. */
7723b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
773eefeeb7a60a347bc851605fadd52672cbd927201sewardjBool setregs (int pid, void *regs, long regs_bsz)
7743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
775eefeeb7a60a347bc851605fadd52672cbd927201sewardj   DEBUG(1, "setregs regs_bsz %ld\n", regs_bsz);
776eefeeb7a60a347bc851605fadd52672cbd927201sewardj// Note : the below is checking for GETREGS, not SETREGS
777eefeeb7a60a347bc851605fadd52672cbd927201sewardj// as if one is defined and working, the other one should also work.
778eefeeb7a60a347bc851605fadd52672cbd927201sewardj#  ifdef PTRACE_GETREGS
779eefeeb7a60a347bc851605fadd52672cbd927201sewardj   if (has_working_ptrace_getregs) {
780eefeeb7a60a347bc851605fadd52672cbd927201sewardj      // Platforms having SETREGS
781eefeeb7a60a347bc851605fadd52672cbd927201sewardj      long res;
782eefeeb7a60a347bc851605fadd52672cbd927201sewardj      // setregs can never be called before getregs has done a runtime check.
783eefeeb7a60a347bc851605fadd52672cbd927201sewardj      assert (has_working_ptrace_getregs == 1);
784eefeeb7a60a347bc851605fadd52672cbd927201sewardj      DEBUG(1, "setregs PTRACE_SETREGS\n");
785eefeeb7a60a347bc851605fadd52672cbd927201sewardj      res = ptrace (PTRACE_SETREGS, pid, NULL, regs);
786eefeeb7a60a347bc851605fadd52672cbd927201sewardj      if (res != 0) {
787eefeeb7a60a347bc851605fadd52672cbd927201sewardj         ERROR(errno, "PTRACE_SETREGS %ld\n", res);
7883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
7893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
790eefeeb7a60a347bc851605fadd52672cbd927201sewardj      return True;
7913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
7923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#  endif
793eefeeb7a60a347bc851605fadd52672cbd927201sewardj
794eefeeb7a60a347bc851605fadd52672cbd927201sewardj   {
795eefeeb7a60a347bc851605fadd52672cbd927201sewardj      char *pregs = (char *) regs;
796eefeeb7a60a347bc851605fadd52672cbd927201sewardj      long offset;
797eefeeb7a60a347bc851605fadd52672cbd927201sewardj      long res;
798eefeeb7a60a347bc851605fadd52672cbd927201sewardj#     ifdef PT_ENDREGS
799eefeeb7a60a347bc851605fadd52672cbd927201sewardj      long peek_bsz = PT_ENDREGS;
800eefeeb7a60a347bc851605fadd52672cbd927201sewardj      assert (peek_bsz <= regs_bsz);
801eefeeb7a60a347bc851605fadd52672cbd927201sewardj#     else
802eefeeb7a60a347bc851605fadd52672cbd927201sewardj      long peek_bsz = regs_bsz-1;
803eefeeb7a60a347bc851605fadd52672cbd927201sewardj#     endif
804eefeeb7a60a347bc851605fadd52672cbd927201sewardj      errno = 0;
805eefeeb7a60a347bc851605fadd52672cbd927201sewardj      DEBUG(1, "setregs PTRACE_POKEUSER(s) %ld\n", peek_bsz);
806eefeeb7a60a347bc851605fadd52672cbd927201sewardj      for (offset = 0; offset < peek_bsz; offset = offset + sizeof(long)) {
807eefeeb7a60a347bc851605fadd52672cbd927201sewardj         res = ptrace(PTRACE_POKEUSER, pid, offset, *(long*)(pregs+offset));
808eefeeb7a60a347bc851605fadd52672cbd927201sewardj         if (errno != 0) {
809eefeeb7a60a347bc851605fadd52672cbd927201sewardj            ERROR(errno, "PTRACE_POKEUSER offset %ld res %ld\n", offset, res);
810eefeeb7a60a347bc851605fadd52672cbd927201sewardj            return False;
811eefeeb7a60a347bc851605fadd52672cbd927201sewardj         }
812eefeeb7a60a347bc851605fadd52672cbd927201sewardj      }
813eefeeb7a60a347bc851605fadd52672cbd927201sewardj      return True;
814eefeeb7a60a347bc851605fadd52672cbd927201sewardj   }
815eefeeb7a60a347bc851605fadd52672cbd927201sewardj
816eefeeb7a60a347bc851605fadd52672cbd927201sewardj   // If neither PTRACE_SETREGS not PTRACE_POKEUSER have returned,
817eefeeb7a60a347bc851605fadd52672cbd927201sewardj   // then we are in serious trouble.
818eefeeb7a60a347bc851605fadd52672cbd927201sewardj   assert (0);
8193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
8203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Restore the registers to the saved value, then detaches from all threads */
8223b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
8233b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid restore_and_detach(int pid)
8243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
8253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (pid_of_save_regs) {
8263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* In case the 'main pid' has been continued, we need to stop it
8273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         before resetting the registers. */
8283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (pid_of_save_regs_continued) {
8293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         pid_of_save_regs_continued = False;
8303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (!stop(pid_of_save_regs, "sigstop before reset regs"))
8313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(0, "Could not sigstop before reset");
8323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
8333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "setregs restore registers pid %d\n", pid_of_save_regs);
835eefeeb7a60a347bc851605fadd52672cbd927201sewardj      if (!setregs(pid_of_save_regs, &user_save.regs, sizeof(user_save.regs))) {
8363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR(errno, "setregs restore registers pid %d after cont\n",
8373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               pid_of_save_regs);
8383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
8393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pid_of_save_regs = 0;
8403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else {
8413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "PTRACE_SETREGS restore registers: no pid\n");
8423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
8433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   detach_from_all_threads(pid);
8443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
8453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Ensures that the gdbserver code is invoked by pid.
8473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   If an error occurs, resets to the valgrind process
8483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   to the state it has before being ptrace-d.
8493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns True if invoke successful, False otherwise.
8503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj*/
8513b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
8523b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool invoke_gdbserver (int pid)
8533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
85430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   static Bool ptrace_restrictions_msg_given = False;
8553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   long res;
8563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Bool stopped;
8573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   struct user user_mod;
8583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Addr sp;
8593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* A specific int value is passed to invoke_gdbserver, to check
8603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      everything goes according to the plan. */
8613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   const int check = 0x8BADF00D; // ate bad food.
8623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   const Addr bad_return = 0;
8643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   // A bad return address will be pushed on the stack.
8653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   // The function invoke_gdbserver cannot return. If ever it returns, a NULL
8663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   // address pushed on the stack should ensure this is detected.
8673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Not yet attached. If problem, vgdb can abort,
8693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      no cleanup needed.
8703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      On Ubuntu>= 10.10, a /proc setting can disable ptrace.
8723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      So, Valgrind has to SET_PTRACER this vgdb. Once this
8733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      is done, this vgdb can ptrace the valgrind process. */
8743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(1, "attach to 'main' pid %d\n", pid);
8763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (!attach(pid, "attach main pid")) {
87730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      if (!ptrace_restrictions_msg_given) {
87830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         ptrace_restrictions_msg_given = True;
87930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         ERROR(0, "error attach main pid %d\n", pid);
88030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         ptrace_restrictions_msg();
88130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      }
8823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
8833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
8843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Now, we are attached. If problem, detach and return. */
8863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (!acquire_and_suspend_threads(pid)) {
8883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      detach_from_all_threads(pid);
8893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* if the pid does not exist anymore, we better stop */
8903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (kill(pid, 0) != 0)
8913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        XERROR (errno, "invoke_gdbserver: check for pid %d existence failed\n",
8923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                pid);
8933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
8943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
8953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
896eefeeb7a60a347bc851605fadd52672cbd927201sewardj   if (!getregs(pid, &user_mod.regs, sizeof(user_mod.regs))) {
8973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      detach_from_all_threads(pid);
8983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
8993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
9003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   user_save = user_mod;
9013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
9023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if defined(VGA_x86)
9033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sp = user_mod.regs.esp;
9043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_amd64)
9053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sp = user_mod.regs.rsp;
9063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (shared32 != NULL) {
9073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     /* 64bit vgdb speaking with a 32bit executable.
9083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        To have system call restart properly, we need to sign extend rax.
9093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        For more info:
9103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        web search '[patch] Fix syscall restarts for amd64->i386 biarch'
9113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        e.g. http://sourceware.org/ml/gdb-patches/2009-11/msg00592.html */
9123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     *(long *)&user_save.regs.rax = *(int*)&user_save.regs.rax;
9133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     DEBUG(1, "Sign extending %8.8lx to %8.8lx\n",
9143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           user_mod.regs.rax, user_save.regs.rax);
9153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
9163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_arm)
9173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sp = user_mod.regs.uregs[13];
9183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_ppc32)
9193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sp = user_mod.regs.gpr[1];
9203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_ppc64)
9213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sp = user_mod.regs.gpr[1];
9223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_s390x)
9233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sp = user_mod.regs.gprs[15];
9243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#else
9253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   I_die_here : (sp) architecture missing in vgdb.c
9263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif
9273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
9283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
9293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   // the magic below is derived from spying what gdb sends to
9303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   // the (classical) gdbserver when invoking a C function.
9313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (shared32 != NULL) {
9323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      // vgdb speaking with a 32bit executable.
9333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if   defined(VGA_x86) || defined(VGA_amd64)
9343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      const int regsize = 4;
9353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      int rw;
9363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* push check arg on the stack */
9373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sp = sp - regsize;
9383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "push check arg ptrace_write_memory\n");
9393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      assert(regsize == sizeof(check));
9403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      rw = ptrace_write_memory(pid, sp,
9413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                               (unsigned char *) &check,
9423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                               regsize);
9433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (rw != 0) {
9443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR(rw, "push check arg ptrace_write_memory");
9453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         detach_from_all_threads(pid);
9463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
9473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
9483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
9493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sp = sp - regsize;
9503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "push bad_return return address ptrace_write_memory\n");
9513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      // Note that for a 64 bits vgdb, only 4 bytes of NULL bad_return
9523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      // are written.
9533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      rw = ptrace_write_memory(pid, sp,
9543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                               (unsigned char *) &bad_return,
9553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                               regsize);
9563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (rw != 0) {
9573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR(rw, "push bad_return return address ptrace_write_memory");
9583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         detach_from_all_threads(pid);
9593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
9603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
9613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if   defined(VGA_x86)
9623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* set ebp, esp, eip and orig_eax to invoke gdbserver */
9633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      // compiled in 32bits, speaking with a 32bits exe
9643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.ebp = sp; // bp set to sp
9653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.esp = sp;
9663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.eip = shared32->invoke_gdbserver;
9673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.orig_eax = -1L;
9683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_amd64)
9693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* set ebp, esp, eip and orig_eax to invoke gdbserver */
9703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      // compiled in 64bits, speaking with a 32bits exe
9713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.rbp = sp; // bp set to sp
9723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.rsp = sp;
9733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.rip = shared32->invoke_gdbserver;
9743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.orig_rax = -1L;
9753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#else
9763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      I_die_here : not x86 or amd64 in x86/amd64 section/
9773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif
9783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
9793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_ppc32) || defined(VGA_ppc64)
9803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.nip = shared32->invoke_gdbserver;
9813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.trap = -1L;
9823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* put check arg in register 3 */
9833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.gpr[3] = check;
9843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* put NULL return address in Link Register */
9853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.link = bad_return;
9863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
9873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_arm)
9883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* put check arg in register 0 */
9893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.uregs[0] = check;
9903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* put NULL return address in Link Register */
9913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.uregs[14] = bad_return;
9923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.uregs[15] = shared32->invoke_gdbserver;
9933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
9943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_s390x)
9953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR(0, "(fn32) s390x has no 32bits implementation");
9963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#else
9973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      I_die_here : architecture missing in vgdb.c
9983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif
9993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
10003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
10013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else if (shared64 != NULL) {
10023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if defined(VGA_x86)
10033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      assert(0); // cannot vgdb a 64 bits executable with a 32 bits exe
10043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_amd64)
10053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      // vgdb speaking with a 64 bit executable.
10063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      const int regsize = 8;
10073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      int rw;
10083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
10093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* give check arg in rdi */
10103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.rdi = check;
10113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
10123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* push return address on stack : return to breakaddr */
10133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sp = sp - regsize;
10143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "push bad_return return address ptrace_write_memory\n");
10153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      rw = ptrace_write_memory(pid, sp,
10163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                               (unsigned char *) &bad_return,
10173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                               sizeof(bad_return));
10183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (rw != 0) {
10193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR(rw, "push bad_return return address ptrace_write_memory");
10203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         detach_from_all_threads(pid);
10213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
10223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
10233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
10243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* set rbp, rsp, rip and orig_rax to invoke gdbserver */
10253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.rbp = sp; // bp set to sp
10263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.rsp = sp;
10273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.rip = shared64->invoke_gdbserver;
10283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.orig_rax = -1L;
10293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
10303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_arm)
10313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      assert(0); // cannot vgdb a 64 bits executable with a 32 bits exe
10323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_ppc32)
10333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      assert(0); // cannot vgdb a 64 bits executable with a 32 bits exe
10343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_ppc64)
10353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      Addr64 func_addr;
10363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      Addr64 toc_addr;
10373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      int rw;
10383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      rw = ptrace_read_memory(pid, shared64->invoke_gdbserver,
10393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                              (unsigned char *)&func_addr,
10403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                              sizeof(Addr64));
10413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (rw != 0) {
10423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR(rw, "ppc64 read func_addr\n");
10433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         detach_from_all_threads(pid);
10443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
10453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
10463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      rw = ptrace_read_memory(pid, shared64->invoke_gdbserver+8,
10473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                              (unsigned char *)&toc_addr,
10483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                              sizeof(Addr64));
10493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (rw != 0) {
10503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR(rw, "ppc64 read toc_addr\n");
10513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         detach_from_all_threads(pid);
10523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
10533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
10543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      // We are not pushing anything on the stack, so it is not
10553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      // very clear why the sp has to be decreased, but it seems
10563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      // needed. The ppc64 ABI might give some lights on this ?
10573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.gpr[1] = sp - 220;
10583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.gpr[2] = toc_addr;
10593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.nip = func_addr;
10603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.trap = -1L;
10613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* put check arg in register 3 */
10623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.gpr[3] = check;
10633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* put bad_return return address in Link Register */
10643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.link = bad_return;
10653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_s390x)
10663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* put check arg in register r2 */
10673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.gprs[2] = check;
10683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* bad_return Return address is in r14 */
10693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.gprs[14] = bad_return;
10703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* minimum stack frame */
10713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sp = sp - 160;
10723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.gprs[15] = sp;
10733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* set program counter */
10743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      user_mod.regs.psw.addr = shared64->invoke_gdbserver;
10753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#else
10763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      I_die_here: architecture missing in vgdb.c
10773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif
10783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
10793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else {
10803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      assert(0);
10813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
10823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1083eefeeb7a60a347bc851605fadd52672cbd927201sewardj   if (!setregs(pid, &user_mod.regs, sizeof(user_mod.regs))) {
10843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      detach_from_all_threads(pid);
10853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
10863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
10873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Now that we have modified the registers, we set
10883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pid_of_save_regs to indicate that restore_and_detach
10893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      must restore the registers in case of cleanup. */
10903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   pid_of_save_regs = pid;
10913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   pid_of_save_regs_continued = False;
10923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
10933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
10943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* We PTRACE_CONT-inue pid.
10953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      Either gdbserver will be invoked directly (if all
10963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      threads are interruptible) or gdbserver will be
10973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      called soon by the scheduler. In the first case,
10983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pid will stop on the break inserted above when
10993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      gdbserver returns. In the 2nd case, the break will
11003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      be encountered directly. */
11013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(1, "PTRACE_CONT to invoke\n");
11023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   res = ptrace (PTRACE_CONT, pid, NULL, NULL);
11033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (res != 0) {
11043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      ERROR(errno, "PTRACE_CONT\n");
11053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      restore_and_detach(pid);
11063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
11073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
11083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   pid_of_save_regs_continued = True;
1109b2572b52b37d56d302408395f7fed9f509423af1sewardj   /* Wait for SIGSTOP generated by m_gdbserver.c give_control_back_to_vgdb */
1110b2572b52b37d56d302408395f7fed9f509423af1sewardj   stopped = waitstopped (pid, SIGSTOP,
11113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                          "waitpid status after PTRACE_CONT to invoke");
11123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (stopped) {
11133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* Here pid has properly stopped on the break. */
11143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pid_of_save_regs_continued = False;
11153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      restore_and_detach(pid);
11163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return True;
11173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else {
11183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* Whatever kind of problem happened. We shutdown */
11193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      shutting_down = True;
11203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
11213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
11223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
11233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif
11243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
11253b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
11263b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid cleanup_restore_and_detach(void *v_pid)
11273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
11283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(1, "cleanup_restore_and_detach dying: %d\n", dying);
11293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#ifdef PTRACEINVOKER
11303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (!dying)
11313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      restore_and_detach(*(int*)v_pid);
11323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif
11333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
11343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
11353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* This function loops till shutting_down becomes true.  In this loop,
11363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   it verifies if valgrind process is reading the characters written
11373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   by vgdb.  The verification is done every max_invoke_ms ms.  If
11383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   valgrind is not reading characters, it will use invoke_gdbserver
11393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   (if PTRACE_INVOKER is defined) to ensure that the gdbserver code is
11403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   called soon by valgrind. */
11413b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int max_invoke_ms = 100;
114230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj#define NEVER 99999999
114330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardjstatic int cmd_time_out = NEVER;
11443b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
11453b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid *invoke_gdbserver_in_valgrind(void *v_pid)
11463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
114730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   struct timeval cmd_max_end_time;
114830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   Bool cmd_started = False;
114930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   struct timeval invoke_time;
115030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj
11513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int pid = *(int *)v_pid;
11523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int written_by_vgdb_before_sleep;
11533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int seen_by_valgrind_before_sleep;
11543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
11553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int invoked_written = -1;
115630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   unsigned int usecs;
11573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
11583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   pthread_cleanup_push(cleanup_restore_and_detach, v_pid);
11593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
11603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   while (!shutting_down) {
11613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      written_by_vgdb_before_sleep = VS_written_by_vgdb;
11623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      seen_by_valgrind_before_sleep = VS_seen_by_valgrind;
11633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(3,
11643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            "written_by_vgdb_before_sleep %d "
11653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            "seen_by_valgrind_before_sleep %d\n",
11663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            written_by_vgdb_before_sleep,
11673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            seen_by_valgrind_before_sleep);
116830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      if (cmd_time_out != NEVER
116930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj          && !cmd_started
117030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj          && written_by_vgdb_before_sleep > seen_by_valgrind_before_sleep) {
117130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         /* A command was started. Record the time at which it was started. */
117230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         DEBUG(1, "IO for command started\n");
117330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         gettimeofday(&cmd_max_end_time, NULL);
117430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         cmd_max_end_time.tv_sec += cmd_time_out;
117530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         cmd_started = True;
117630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      }
117730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      if (max_invoke_ms > 0) {
117830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         usecs = 1000 * max_invoke_ms;
117930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         gettimeofday(&invoke_time, NULL);
118030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         invoke_time.tv_sec += max_invoke_ms / 1000;
118130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         invoke_time.tv_usec += 1000 * (max_invoke_ms % 1000);
118230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         invoke_time.tv_sec += invoke_time.tv_usec / (1000 * 1000);
118330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         invoke_time.tv_usec = invoke_time.tv_usec % (1000 * 1000);
118430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      } else {
118530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         usecs = 0;
118630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      }
118730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      if (cmd_started) {
118830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         // 0 usecs here means the thread just has to check gdbserver eats
118930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         // the characters in <= cmd_time_out seconds.
119030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         // We will just wait by 1 second max at a time.
119130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         if (usecs == 0 || usecs > 1000 * 1000)
119230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            usecs = 1000 * 1000;
119330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      }
1194992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj      usleep(usecs);
1195992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj
119630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      /* If nothing happened during our sleep, let's try to wake up valgrind
119730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         or check for cmd time out. */
11983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (written_by_vgdb_before_sleep == VS_written_by_vgdb
11993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj          && seen_by_valgrind_before_sleep == VS_seen_by_valgrind
12003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj          && VS_written_by_vgdb > VS_seen_by_valgrind) {
120130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         struct timeval now;
120230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         gettimeofday(&now, NULL);
12033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         DEBUG(2,
12043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               "after sleep "
12053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               "written_by_vgdb %d "
12063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               "seen_by_valgrind %d "
12073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               "invoked_written %d\n",
12083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               VS_written_by_vgdb,
12093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               VS_seen_by_valgrind,
12103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               invoked_written);
12113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         /* if the pid does not exist anymore, we better stop */
12123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (kill(pid, 0) != 0)
12133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           XERROR (errno,
12143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   "invoke_gdbserver_in_valgrind: "
12153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   "check for pid %d existence failed\n", pid);
121630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         if (cmd_started) {
121730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            if (timercmp (&now, &cmd_max_end_time, >))
121830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj               XERROR (0,
121930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj                       "pid %d did not handle a command in %d seconds\n",
122030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj                       pid, cmd_time_out);
122130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         }
122230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         if (max_invoke_ms > 0 && timercmp (&now, &invoke_time, >=)) {
122330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            #if defined(PTRACEINVOKER)
122430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            /* only need to wake up if the nr written has changed since
122530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj               last invoke. */
122630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            if (invoked_written != written_by_vgdb_before_sleep) {
122730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj               if (invoke_gdbserver(pid)) {
122830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj                  /* If invoke succesful, no need to invoke again
122930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj                     for the same value of written_by_vgdb_before_sleep. */
123030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj                  invoked_written = written_by_vgdb_before_sleep;
123130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj               }
12323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            }
123330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            #else
123430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            DEBUG(2, "invoke_gdbserver via ptrace not (yet) implemented\n");
123530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            #endif
123630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         }
123730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      } else {
123830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         // Something happened => restart timer check.
123930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         if (cmd_time_out != NEVER) {
124030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            DEBUG(2, "some IO was done => restart command\n");
124130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            cmd_started = False;
12423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
12433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
12443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
12453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   pthread_cleanup_pop(0);
12463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return NULL;
12473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
12483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
12493b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
12503b290486cd4cd601b20e04340e593c9ed9717e5fsewardjint open_fifo (char* name, int flags, char* desc)
12513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
12523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int fd;
12533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(1, "opening %s %s\n", name, desc);
12543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   fd = open(name, flags);
12553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (fd == -1)
12563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "error opening %s %s\n", name, desc);
12573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
12583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(1, "opened %s %s fd %d\n", name, desc, fd);
12593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return fd;
12603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
12613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
12623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* acquire a lock on the first byte of the given fd. If not successful,
12633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   exits with error.
12643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   This allows to avoid having two vgdb speaking with the same Valgrind
12653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   gdbserver as this causes serious headaches to the protocol. */
12663b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
12673b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid acquire_lock (int fd, int valgrind_pid)
12683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
1269992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   struct flock fl;
1270992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   fl.l_type = F_WRLCK;
1271992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   fl.l_whence = SEEK_SET;
1272992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   fl.l_start = 0;
1273992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   fl.l_len = 1;
1274992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   if (fcntl(fd, F_SETLK, &fl) < 0) {
12753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (errno == EAGAIN || errno == EACCES) {
12763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         XERROR(errno,
12773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                "Cannot acquire lock.\n"
12783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                "Probably vgdb pid %d already speaks with Valgrind pid %d\n",
12793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                VS_vgdb_pid,
12803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                valgrind_pid);
12813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else {
12823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         XERROR(errno, "cannot acquire lock.\n");
12833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
12843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
12853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
12863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Here, we have the lock. It will be released when fd will be closed. */
12873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* We indicate our pid to Valgrind gdbserver */
12883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (shared32 != NULL)
12893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      shared32->vgdb_pid = getpid();
12903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else if (shared64 != NULL)
12913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      shared64->vgdb_pid = getpid();
12923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else
12933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      assert(0);
12943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
12953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
12963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define PBUFSIZ 16384 /* keep in sync with server.h */
12973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
12983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* read some characters from fd.
12993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns the nr of characters read, -1 if error.
13003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   desc is a string used in tracing */
13013b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
13023b290486cd4cd601b20e04340e593c9ed9717e5fsewardjint read_buf (int fd, char* buf, char* desc)
13033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
13043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int nrread;
13053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(2, "reading %s\n", desc);
13063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   nrread = read(fd, buf, PBUFSIZ);
13073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (nrread == -1) {
13083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      ERROR (errno, "error reading %s\n", desc);
13093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return -1;
13103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
13113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   buf[nrread] = '\0';
13123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(2, "read %s %s\n", desc, buf);
13133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return nrread;
13143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
13153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
13163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* write size bytes from buf to fd.
13173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   desc is a description of the action for which the write is done.
13183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   If notify, then add size to the shared cntr indicating to the
13193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   valgrind process that there is new data.
13203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns True if write is ok, False if there was a problem. */
13213b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
13223b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool write_buf(int fd, char* buf, int size, char* desc, Bool notify)
13233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
13243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int nrwritten;
13253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int nrw;
13263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(2, "writing %s len %d %s notify: %d\n", desc, size, buf, notify);
13273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   nrwritten = 0;
13283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   while (nrwritten < size) {
13293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      nrw = write (fd, buf+nrwritten, size - nrwritten);
13303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (nrw == -1) {
13313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR(errno, "error write %s\n", desc);
13323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
13333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
13343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      nrwritten = nrwritten + nrw;
13353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (notify)
13363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         add_written(nrw);
13373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
13383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return True;
13393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
13403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
13413b290486cd4cd601b20e04340e593c9ed9717e5fsewardjtypedef enum {
13423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   FROM_GDB,
13433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   TO_GDB,
13443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   FROM_PID,
13453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   TO_PID } ConnectionKind;
13463b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic const int NumConnectionKind = TO_PID+1;
13473b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
13483b290486cd4cd601b20e04340e593c9ed9717e5fsewardjchar *ppConnectionKind (ConnectionKind con)
13493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
13503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   switch (con) {
13513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case FROM_GDB: return "FROM_GDB";
13523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case TO_GDB:   return "TO_GDB";
13533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case FROM_PID: return "FROM_PID";
13543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case TO_PID:   return "TO_PID";
13553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   default:       return "invalid connection kind";
13563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
13573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
13583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
13593b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic char *shared_mem;
13603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1361992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardjstatic int from_gdb = 0; /* stdin by default, changed if --port is given. */
13623b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic char *from_gdb_to_pid; /* fifo name to write gdb command to pid */
13633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Returns True in case read/write operations were done properly.
13643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns False in case of error.
13653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   to_pid is the file descriptor to write to the process pid. */
13663b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
13673b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool read_from_gdb_write_to_pid(int to_pid)
13683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
13691d76a80d63502951cb9cbf6f696d663f093083faphilippe   char buf[PBUFSIZ+1]; // +1 for trailing \0
13703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int nrread;
13713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
13723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   nrread = read_buf(from_gdb, buf, "from gdb on stdin");
13733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (nrread <= 0) {
13743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (nrread == 0)
13753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         DEBUG(1, "read 0 bytes from gdb => assume exit\n");
13763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      else
13773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         DEBUG(1, "error reading bytes from gdb\n");
13783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      close (from_gdb);
13793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      shutting_down = True;
13803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
13813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
13823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return write_buf(to_pid, buf, nrread, "to_pid", /* notify */ True);
13833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
13843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1385992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardjstatic int to_gdb = 1; /* stdout by default, changed if --port is given. */
13863b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic char *to_gdb_from_pid; /* fifo name to read pid replies */
13873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Returns True in case read/write operations were done properly.
13883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns False in case of error.
13893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   from_pid is the file descriptor to read data from the process pid. */
13903b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
13913b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool read_from_pid_write_to_gdb(int from_pid)
13923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
13931d76a80d63502951cb9cbf6f696d663f093083faphilippe   char buf[PBUFSIZ+1]; // +1 for trailing \0
13943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int nrread;
13953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
13963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   nrread = read_buf(from_pid, buf, "from pid");
13973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (nrread <= 0) {
13983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (nrread == 0)
13993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         DEBUG(1, "read 0 bytes from pid => assume exit\n");
14003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      else
14013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         DEBUG(1, "error reading bytes from pid\n");
14023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      close (from_pid);
14033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      shutting_down = True;
14043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
14053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
14063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return write_buf(to_gdb, buf, nrread, "to_gdb", /* notify */ False);
14073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
14083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1409992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardjstatic
1410992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardjvoid wait_for_gdb_connect (int in_port)
1411992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj{
1412992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   struct sockaddr_in addr;
1413992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj
1414992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   int listen_gdb = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
1415992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   int gdb_connect;
1416992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj
1417992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   if (-1 == listen_gdb) {
1418992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj      XERROR(errno, "cannot create socket");
1419992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   }
1420992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj
1421992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    memset(&addr, 0, sizeof(addr));
1422992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj
1423992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    addr.sin_family = AF_INET;
1424992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    addr.sin_port = htons((unsigned short int)in_port);
1425992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    addr.sin_addr.s_addr = INADDR_ANY;
1426992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj
1427992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    if (-1 == bind(listen_gdb,(struct sockaddr *)&addr, sizeof(addr))) {
1428992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj      XERROR(errno, "bind failed");
1429992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    }
1430992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    fprintf(stderr, "listening on port %d ...", in_port);
1431992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    fflush(stderr);
1432992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    if (-1 == listen(listen_gdb, 1)) {
1433992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj      XERROR(errno, "error listen failed");
1434992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    }
1435992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj
1436992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    gdb_connect = accept(listen_gdb, NULL, NULL);
1437992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    if (gdb_connect < 0) {
1438992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj        XERROR(errno, "accept failed");
1439992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    }
1440992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    fprintf(stderr, "connected.\n");
1441992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    fflush(stderr);
1442992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    close(listen_gdb);
1443992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    from_gdb = gdb_connect;
1444992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    to_gdb = gdb_connect;
1445992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj}
1446992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj
14473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* prepares the FIFOs filenames, map the shared memory. */
14483b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
14493b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid prepare_fifos_and_shared_mem(int pid)
14503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
1451ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   const HChar *user, *host;
1452ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   unsigned len;
1453ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian
1454ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   user = getenv("LOGNAME");
1455ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   if (user == NULL) user = getenv("USER");
1456ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   if (user == NULL) user = "???";
1457ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian
1458ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   host = getenv("HOST");
1459ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   if (host == NULL) host = getenv("HOSTNAME");
1460ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   if (host == NULL) host = "???";
1461ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian
1462ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   len = strlen(vgdb_prefix) + strlen(user) + strlen(host) + 40;
1463ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   from_gdb_to_pid = vmalloc (len);
1464ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   to_gdb_from_pid = vmalloc (len);
1465ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   shared_mem      = vmalloc (len);
14663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* below 3 lines must match the equivalent in remote-utils.c */
1467ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   sprintf(from_gdb_to_pid, "%s-from-vgdb-to-%d-by-%s-on-%s",    vgdb_prefix,
1468ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian           pid, user, host);
1469ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   sprintf(to_gdb_from_pid, "%s-to-vgdb-from-%d-by-%s-on-%s",    vgdb_prefix,
1470ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian           pid, user, host);
1471ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   sprintf(shared_mem,      "%s-shared-mem-vgdb-%d-by-%s-on-%s", vgdb_prefix,
1472ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian           pid, user, host);
14733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG (1, "vgdb: using %s %s %s\n",
14743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj          from_gdb_to_pid, to_gdb_from_pid, shared_mem);
14753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
14763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   map_vgdbshared(shared_mem);
14773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
14783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
14793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Convert hex digit A to a number.  */
14803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
14813b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int
14823b290486cd4cd601b20e04340e593c9ed9717e5fsewardjfromhex (int a)
14833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
14843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (a >= '0' && a <= '9')
14853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return a - '0';
14863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else if (a >= 'a' && a <= 'f')
14873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return a - 'a' + 10;
14883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else
14893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR(0, "Reply contains invalid hex digit %c\n", a);
14903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  return 0;
14913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
14923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
14933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Returns next char from fd.  -1 if error, -2 if EOF.
14943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   NB: must always call it with the same fd */
14953b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int
14963b290486cd4cd601b20e04340e593c9ed9717e5fsewardjreadchar (int fd)
14973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
14981d76a80d63502951cb9cbf6f696d663f093083faphilippe  static unsigned char buf[PBUFSIZ+1]; // +1 for trailing \0
14993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  static int bufcnt = 0;
15003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  static unsigned char *bufp;
15013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  if (bufcnt-- > 0)
15033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     return *bufp++;
15043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15051d76a80d63502951cb9cbf6f696d663f093083faphilippe  bufcnt = read_buf (fd, buf, "static buf readchar");
15063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  if (bufcnt <= 0) {
15083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     if (bufcnt == 0) {
15093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        fprintf (stderr, "readchar: Got EOF\n");
15103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        return -2;
15113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     } else {
15123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        ERROR (errno, "readchar\n");
15133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        return -1;
15143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     }
15153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  }
15163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  bufp = buf;
15183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  bufcnt--;
15193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  return *bufp++;
15203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
15213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Read a packet from fromfd, with error checking,
15233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   and store it in BUF.
15243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns length of packet, or -1 if error or -2 if EOF.
15253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Writes ack on ackfd */
15263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15273b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int
15283b290486cd4cd601b20e04340e593c9ed9717e5fsewardjgetpkt (char *buf, int fromfd, int ackfd)
15293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
15303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  char *bp;
15313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  unsigned char csum, c1, c2;
15323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  int c;
15333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  while (1) {
15353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     csum = 0;
15363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     while (1) {
15383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        c = readchar (fromfd);
15393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        if (c == '$')
15403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           break;
15413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        DEBUG(2, "[getpkt: discarding char '%c']\n", c);
15423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        if (c < 0)
15433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           return c;
15443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     }
15453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     bp = buf;
15473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     while (1) {
15483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        c = readchar (fromfd);
15493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        if (c < 0)
15503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           return c;
15513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        if (c == '#')
15523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           break;
15533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        if (c == '*') {
15543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           int repeat;
15553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           int r;
15563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           int prev;
15573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           prev = *(bp-1);
15583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           csum += c;
15593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           repeat = readchar (fromfd);
15603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           csum += repeat;
15613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           for (r = 0; r < repeat - 29; r ++)
15623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              *bp++ = prev;
15633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        } else {
15643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           *bp++ = c;
15653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           csum += c;
15663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        }
15673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     }
15683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     *bp = 0;
15693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     c1 = fromhex (readchar (fromfd));
15713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     c2 = fromhex (readchar (fromfd));
15723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     if (csum == (c1 << 4) + c2)
15743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj	break;
15753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
15773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              (c1 << 4) + c2, csum, buf);
15783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     if (write (ackfd, "-", 1) != 1)
15793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        ERROR(0, "error when writing - (nack)\n");
15803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     else
15813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        add_written(1);
15823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  }
15833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  DEBUG(2, "getpkt (\"%s\");  [sending ack] \n", buf);
15853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  if (write (ackfd, "+", 1) != 1)
15863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     ERROR(0, "error when writing + (ack)\n");
15873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  else
15883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     add_written(1);
15893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  return bp - buf;
15903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
15913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15923b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sigint = 0;
15933b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sigterm = 0;
15943b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sigpipe = 0;
15953b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sighup = 0;
15963b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sigusr1 = 0;
15973b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sigalrm = 0;
15983b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sigusr1_fd = -1;
15993b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic pthread_t invoke_gdbserver_in_valgrind_thread;
16003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
16013b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
16023b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid received_signal (int signum)
16033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
16043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (signum == SIGINT)
16053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sigint++;
16063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else if (signum == SIGUSR1) {
16073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sigusr1++;
16083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (sigusr1_fd >= 0) {
16093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         char control_c = '\003';
16103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         write_buf(sigusr1_fd, &control_c, 1,
16113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   "write \\003 on SIGUSR1", /* notify */ True);
16123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
16133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
16143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else if (signum == SIGTERM) {
16153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      shutting_down = True;
16163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sigterm++;
16173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else if (signum == SIGHUP) {
16183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      shutting_down = True;
16193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sighup++;
16203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else if (signum == SIGPIPE) {
16213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sigpipe++;
16223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else if (signum == SIGALRM) {
16233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sigalrm++;
1624992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#if defined(VGPV_arm_linux_android)
1625992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj      /* Android has no pthread_cancel. As it also does not have
1626992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj         PTRACE_INVOKER, there is no need for cleanup action.
1627992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj         So, we just do nothing. */
1628992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj      DEBUG(1, "sigalrm received, no action on android\n");
1629992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#else
16303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* Note: we cannot directly invoke restore_and_detach : this must
16313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         be done by the thread that has attached.
16323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         We have in this thread pushed a cleanup handler that will
16333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         cleanup what is needed. */
1634992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj      DEBUG(1, "pthread_cancel invoke_gdbserver_in_valgrind_thread\n");
16353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pthread_cancel(invoke_gdbserver_in_valgrind_thread);
1636992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#endif
16373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else {
16383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      ERROR(0, "unexpected signal %d\n", signum);
16393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
16403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
16413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
16423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* install the signal handlers allowing e.g. vgdb to cleanup in
16433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case of termination. */
16443b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
16453b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid install_handlers(void)
16463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
16473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   struct sigaction action, oldaction;
16483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
16493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   action.sa_handler = received_signal;
16503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sigemptyset (&action.sa_mask);
16513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   action.sa_flags = 0;
16523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
16533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* SIGINT: when user types C-c in gdb, this sends
16543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      a SIGINT to vgdb + causes a character to be sent to remote gdbserver.
16553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      The later is enough to wakeup the valgrind process. */
16563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (sigaction (SIGINT, &action, &oldaction) != 0)
16573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "vgdb error sigaction SIGINT\n");
16583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* We might do something more intelligent than just
16593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      reporting this SIGINT E.g. behave similarly to the gdb: two
16603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      control-C without feedback from the debugged process would
16613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      mean to stop debugging it. */
16623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
16633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* SIGUSR1: this is used to facilitate automatic testing.  When
16643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      vgdb receives this signal, it will simulate the user typing C-c. */
16653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (sigaction (SIGUSR1, &action, &oldaction) != 0)
16663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "vgdb error sigaction SIGUSR1\n");
16673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
16683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
16693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* SIGTERM: can receive this signal (e.g. from gdb) to terminate vgdb
16703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      when detaching or similar. A clean shutdown will be done as both
16713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      the read and write side will detect an end of file. */
16723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (sigaction (SIGTERM, &action, &oldaction) != 0)
16733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "vgdb error sigaction SIGTERM\n");
16743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
16753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* SIGPIPE: can receive this signal when gdb detaches or kill the
16763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      process debugged: gdb will close its pipes to vgdb. vgdb
16773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      must resist to this signal to allow a clean shutdown. */
16783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (sigaction (SIGPIPE, &action, &oldaction) != 0)
16793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "vgdb error sigaction SIGPIPE\n");
16803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
16813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* SIGALRM: in case invoke thread is blocked, alarm is used
16823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      to cleanup.  */
16833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (sigaction (SIGALRM, &action, &oldaction) != 0)
16843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "vgdb error sigaction SIGALRM\n");
16853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
16863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
16873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* close the FIFOs provided connections, terminate the invoker thread.  */
16883b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
16893b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid close_connection(int to_pid, int from_pid)
16903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
16913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(1, "nr received signals: sigint %d sigterm %d sighup %d sigpipe %d\n",
16923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         sigint, sigterm, sighup, sigpipe);
16933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Note that we do not forward sigterm to the valgrind process:
16943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      a sigterm signal is (probably) received from gdb if the user wants to
16953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      kill the debugged process. The kill instruction has been given to
16963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      the valgrind process, which should execute a clean exit. */
16973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
16983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* We first close the connection to pid. The pid will then
16993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      terminates its gdbserver work. We keep the from pid
17003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      fifo opened till the invoker thread is finished.
17013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      This allows the gdbserver to finish sending its last reply. */
17023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (close(to_pid) != 0)
17033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      ERROR(errno, "close to_pid\n");
17043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
17053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* if there is a task that was busy trying to wake up valgrind
17063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      process, we wait for it to be terminated otherwise threads
17073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      in the valgrind process can stay stopped if vgdb main
17083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      exits before the invoke thread had time to detach from
17093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      all valgrind threads. */
171030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   if (max_invoke_ms > 0 || cmd_time_out != NEVER) {
17113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      int join;
17123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
17133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* It is surprisingly complex to properly shutdown or exit the
17143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         valgrind process in which gdbserver has been invoked through
17153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ptrace.  In the normal case (gdb detaches from the process,
17163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         or process is continued), the valgrind process will reach the
17173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         breakpoint place.  Using ptrace, vgdb will ensure the
17183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         previous activity of the process is resumed (e.g. restart a
17193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         blocking system call).  The special case is when gdb asks the
17203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         valgrind process to exit (using either the "kill" command or
17213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         "monitor exit").  In such a case, the valgrind process will
17223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         call exit.  But a ptraced process will be blocked in exit,
17233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         waiting for the ptracing process to detach or die. vgdb
17243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         cannot detach unconditionally as otherwise, in the normal
1725b2572b52b37d56d302408395f7fed9f509423af1sewardj         case, the valgrind process would stop abnormally with SIGSTOP
17263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         (as vgdb would not be there to catch it). vgdb can also not
17273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         die unconditionally otherwise again, similar problem.  So, we
17283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         assume that most of the time, we arrive here in the normal
17293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         case, and so, the breakpoint has been encountered by the
17303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         valgrind process, so the invoker thread will exit and the
17313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         join will succeed.  For the "kill" case, we cause an alarm
17323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         signal to be sent after a few seconds. This means that in the
17333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         normal case, the gdbserver code in valgrind process must have
17343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         returned the control in less than the alarm nr of seconds,
1735b2572b52b37d56d302408395f7fed9f509423af1sewardj         otherwise, valgrind will stop abnormally with SIGSTOP. */
17363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      (void) alarm (3);
17373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
17383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "joining with invoke_gdbserver_in_valgrind_thread\n");
17393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      join = pthread_join(invoke_gdbserver_in_valgrind_thread, NULL);
17403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (join != 0)
17413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         XERROR
17423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            (join,
17433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj             "vgdb error pthread_join invoke_gdbserver_in_valgrind_thread\n");
17443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
17453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (close(from_pid) != 0)
17463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      ERROR(errno, "close from_pid\n");
17473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
17483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
17493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Relay data between gdb and Valgrind gdbserver, till EOF or an
17503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   error is encountered. */
17513b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
17523b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid gdb_relay (int pid)
17533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
17543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int from_pid = -1; /* fd to read from pid */
17553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int to_pid = -1; /* fd to write to pid */
17563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
17573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int shutdown_loop = 0;
17583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   fprintf (stderr, "relaying data between gdb and process %d\n", pid);
17593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   fflush (stderr);
17603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
17613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (max_invoke_ms > 0)
17623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pthread_create(&invoke_gdbserver_in_valgrind_thread, NULL,
17633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     invoke_gdbserver_in_valgrind, (void *) &pid);
17643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   to_pid = open_fifo(from_gdb_to_pid, O_WRONLY, "write to pid");
17653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   acquire_lock (shared_mem_fd, pid);
17663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
17673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   from_pid = open_fifo (to_gdb_from_pid, O_RDONLY|O_NONBLOCK,
17683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                         "read mode from pid");
17693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
17703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sigusr1_fd = to_pid; /* allow simulating user typing control-c */
17713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
17723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   while (1) {
17733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      ConnectionKind ck;
17743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      int ret;
17753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      struct pollfd pollfds[NumConnectionKind];
17763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
17773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* watch data written by gdb, watch POLLERR on both gdb fd */
17783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[FROM_GDB].fd = from_gdb;
17793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[FROM_GDB].events = POLLIN;
17803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[FROM_GDB].revents = 0;
17813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[TO_GDB].fd = to_gdb;
17823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[TO_GDB].events = 0;
17833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[TO_GDB].revents = 0;
17843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
17853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* watch data written by pid, watch POLLERR on both pid fd */
17863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[FROM_PID].fd = from_pid;
17873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[FROM_PID].events = POLLIN;
17883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[FROM_PID].revents = 0;
17893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[TO_PID].fd = to_pid;
17903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[TO_PID].events = 0;
17913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[TO_PID].revents = 0;
17923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
17933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      ret = poll(pollfds,
17943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                 NumConnectionKind,
17953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                 (shutting_down ?
17963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  1 /* one second */
17973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  : -1 /* infinite */));
17983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(2, "poll ret %d errno %d\n", ret, errno);
17993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
18003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* check for unexpected error */
18013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (ret <= 0 && errno != EINTR) {
18023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR (errno, "unexpected poll ret %d\n", ret);
18033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         shutting_down = True;
18043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         break;
18053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
18063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
18073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* check for data to read */
18083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      for (ck = 0; ck < NumConnectionKind; ck ++) {
18093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (pollfds[ck].revents & POLLIN) {
18103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            switch (ck) {
18113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            case FROM_GDB:
18123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               if (!read_from_gdb_write_to_pid(to_pid))
18133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  shutting_down = True;
18143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               break;
18151d76a80d63502951cb9cbf6f696d663f093083faphilippe            case FROM_PID:
18161d76a80d63502951cb9cbf6f696d663f093083faphilippe               if (!read_from_pid_write_to_gdb(from_pid))
18171d76a80d63502951cb9cbf6f696d663f093083faphilippe                  shutting_down = True;
18181d76a80d63502951cb9cbf6f696d663f093083faphilippe               break;
18193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            default: XERROR(0, "unexpected POLLIN on %s\n",
18203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                               ppConnectionKind(ck));
18213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            }
18223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
18233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
18243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
18253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* check for an fd being in error condition */
18263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      for (ck = 0; ck < NumConnectionKind; ck ++) {
18273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (pollfds[ck].revents & POLLERR) {
18283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(1, "connection %s fd %d POLLERR error condition\n",
18293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     ppConnectionKind(ck), pollfds[ck].fd);
18303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            valgrind_dying();
18313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            shutting_down = True;
18323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
18333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (pollfds[ck].revents & POLLHUP) {
18343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(1, "connection %s fd %d POLLHUP error condition\n",
18353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  ppConnectionKind(ck), pollfds[ck].fd);
18363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            valgrind_dying();
18373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            shutting_down = True;
18383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
18393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (pollfds[ck].revents & POLLNVAL) {
18403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(1, "connection %s fd %d POLLNVAL error condition\n",
18413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  ppConnectionKind(ck), pollfds[ck].fd);
18423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            valgrind_dying();
18433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            shutting_down = True;
18443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
18453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
18463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
18473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (shutting_down) {
18483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         /* we let some time to the final packets to be transferred */
18493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         shutdown_loop++;
18503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (shutdown_loop > 3)
18513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            break;
18523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
18533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
18543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   close_connection(to_pid, from_pid);
18553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
18563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
18573b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int packet_len_for_command(char *cmd)
18583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
18593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* cmd will be send as a packet $qRcmd,xxxx....................xx#cc      */
18603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return                          7+     2*strlen(cmd)             +3  + 1;
18613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
18623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
18633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* hyper-minimal protocol implementation that
18643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sends the provided commands (using qRcmd packets)
18653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   and read and display their replies. */
18663b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
18673b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid standalone_send_commands(int pid,
18683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                              int last_command,
18693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                              char *commands[] )
18703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
18713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int from_pid = -1; /* fd to read from pid */
18723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int to_pid = -1; /* fd to write to pid */
18733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
18743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int i;
18753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int hi;
18763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   unsigned char hex[3];
18773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   unsigned char cksum;
18783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   unsigned char *hexcommand;
18791d76a80d63502951cb9cbf6f696d663f093083faphilippe   unsigned char buf[PBUFSIZ+1]; // +1 for trailing \0
18803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int buflen;
18813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int nc;
18823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
18833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
188430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   if (max_invoke_ms > 0 || cmd_time_out != NEVER)
18853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pthread_create(&invoke_gdbserver_in_valgrind_thread, NULL,
18863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     invoke_gdbserver_in_valgrind, (void *) &pid);
18873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
18883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   to_pid = open_fifo(from_gdb_to_pid, O_WRONLY, "write to pid");
18893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   acquire_lock (shared_mem_fd, pid);
18903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
18913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* first send a C-c \003 to pid, so that it wakes up the process
18923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      After that, we can open the fifo from the pid in read mode
18933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      We then start to wait for packets (normally first a resume reply)
18943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      At that point, we send our command and expect replies */
18953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   buf[0] = '\003';
18963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   write_buf(to_pid, buf, 1, "write \\003 to wake up", /* notify */ True);
18973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   from_pid = open_fifo(to_gdb_from_pid, O_RDONLY,
18983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                        "read cmd result from pid");
18993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
19003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   for (nc = 0; nc <= last_command; nc++) {
19013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      fprintf (stderr, "sending command %s to pid %d\n", commands[nc], pid);
19023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      fflush (stderr);
19033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
19043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* prepare hexcommand $qRcmd,xxxx....................xx#cc      */
19053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      hexcommand = vmalloc (packet_len_for_command(commands[nc]));
19063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      hexcommand[0] = 0;
19073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      strcat (hexcommand, "$qRcmd,");
19083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      for (i = 0; i < strlen(commands[nc]); i++) {
19093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         sprintf(hex, "%02x", commands[nc][i]);
19103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         strcat (hexcommand, hex);
19113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
19123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* checksum (but without the $) */
19133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      cksum = 0;
19143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      for (hi = 1; hi < strlen(hexcommand); hi++)
19153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         cksum+=hexcommand[hi];
19163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      strcat(hexcommand, "#");
19173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sprintf(hex, "%02x", cksum);
19183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      strcat(hexcommand, hex);
19193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      write_buf(to_pid, hexcommand, strlen(hexcommand),
19203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                "writing hex command to pid", /* notify */ True);
19213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
19223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* we exit of the below loop explicitely when the command has
19233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         been handled or because a signal handler will set
19243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         shutting_down. */
19253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      while (!shutting_down) {
19263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         buflen = getpkt(buf, from_pid, to_pid);
19273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (buflen < 0) {
19283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            ERROR (0, "error reading packet\n");
19293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            if (buflen == -2)
19303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               valgrind_dying();
19313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            break;
19323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
19333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (strlen(buf) == 0) {
19343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(0, "empty packet rcvd (packet qRcmd not recognised?)\n");
19353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            break;
19363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
19373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (strcmp(buf, "OK") == 0) {
19383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(1, "OK packet rcvd\n");
19393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            break;
19403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
19413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (buf[0] == 'E') {
19423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(0,
19433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  "E NN error packet rcvd: %s (unknown monitor command?)\n",
19443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  buf);
19453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            break;
19463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
19473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (buf[0] == 'W') {
19483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(0, "W stopped packet rcvd: %s\n", buf);
19493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            break;
19503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
19513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (buf[0] == 'T') {
19523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(1, "T resume reply packet received: %s\n", buf);
19533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            continue;
19543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
19553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
19563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         /* must be here an O packet with hex encoded string reply
19573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            => decode and print it */
19583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (buf[0] != 'O') {
19593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(0, "expecting O packet, received: %s\n", buf);
19603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            continue;
19613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
19623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         {
19633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            char buf_print[buflen/2 + 1];
19643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            for (i = 1; i < buflen; i = i + 2)
19653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               buf_print[i/2] = (fromhex(*(buf+i)) << 4)
19663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     + fromhex(*(buf+i+1));
19673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            buf_print[buflen/2] = 0;
19683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            printf("%s", buf_print);
19693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            fflush(stdout);
19703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
19713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
19723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      free (hexcommand);
19733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
19743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   shutting_down = True;
19753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
19763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   close_connection(to_pid, from_pid);
19773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
19783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
19793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* report to user the existence of a vgdb-able valgrind process
19803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   with given pid */
19813b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
198230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardjvoid report_pid (int pid, Bool on_stdout)
19833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
19843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   char cmdline_file[100];
19853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   char cmdline[1000];
19863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int fd;
19873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int i, sz;
19883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
19893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sprintf(cmdline_file, "/proc/%d/cmdline", pid);
19903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   fd = open (cmdline_file, O_RDONLY);
19913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (fd == -1) {
19923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "error opening cmdline file %s %s\n",
19933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            cmdline_file, strerror(errno));
19943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sprintf(cmdline, "(could not obtain process command line)");
19953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else {
19963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sz = read(fd, cmdline, 1000);
19973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      for (i = 0; i < sz; i++)
19983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (cmdline[i] == 0)
19993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            cmdline[i] = ' ';
20003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      cmdline[sz] = 0;
2001d8c12f178d9d03b934ce10d6fcb45c27503889dcsewardj      close (fd);
20023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
200330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   fprintf((on_stdout ? stdout : stderr), "use --pid=%d for %s\n", pid, cmdline);
200430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   fflush((on_stdout ? stdout : stderr));
20053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
20063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
200730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj/* Possibly produces additional usage information documenting the
20083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   ptrace restrictions. */
20093b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
201030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardjvoid ptrace_restrictions_msg(void)
20113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
20123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#  ifdef PR_SET_PTRACER
20133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   char *ptrace_scope_setting_file = "/proc/sys/kernel/yama/ptrace_scope";
20143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int fd = -1;
20153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   char ptrace_scope = 'X';
20163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   fd = open (ptrace_scope_setting_file, O_RDONLY, 0);
20173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (fd >= 0 && (read (fd, &ptrace_scope, 1) == 1) && (ptrace_scope != '0')) {
20183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      fprintf (stderr,
20193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               "Note: your kernel restricts ptrace invoker using %s\n"
20203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               "vgdb will only be able to attach to a Valgrind process\n"
20213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               "blocked in a system call *after* an initial successful attach\n",
20223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               ptrace_scope_setting_file);
20233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else if (ptrace_scope == 'X') {
2024d142f99836471d4245250247cc9ac7bc5a1391fasewardj      DEBUG (1,
2025d142f99836471d4245250247cc9ac7bc5a1391fasewardj             "PR_SET_PTRACER defined"
2026d142f99836471d4245250247cc9ac7bc5a1391fasewardj             " but could not determine ptrace scope from %s\n",
2027d142f99836471d4245250247cc9ac7bc5a1391fasewardj             ptrace_scope_setting_file);
20283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
20293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (fd >= 0)
20303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      close (fd);
20313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#  endif
20323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
20333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#  ifndef PTRACEINVOKER
20343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   fprintf(stderr,
20353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           "Note: ptrace invoker not implemented\n"
20363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           "For more info: read user manual section"
20373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           " 'Limitations of the Valgrind gdbserver'\n");
20383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#  endif
20393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
20403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
20413b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
20423b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid usage(void)
20433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
20443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   fprintf(stderr,
20453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"Usage: vgdb [OPTION]... [[-c] COMMAND]...\n"
20463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"vgdb (valgrind gdb) has two usages\n"
20473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"  1. standalone to send monitor commands to a Valgrind gdbserver.\n"
20483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"     The OPTION(s) must be followed by the command to send\n"
20493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"     To send more than one command, separate the commands with -c\n"
20503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"  2. relay application between gdb and a Valgrind gdbserver.\n"
20513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"     Only OPTION(s) can be given.\n"
20523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"\n"
20533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj" OPTIONS are [--pid=<number>] [--vgdb-prefix=<prefix>]\n"
205430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"             [--wait=<number>] [--max-invoke-ms=<number>]\n"
2055992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj"             [--port=<portnr>\n"
205630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"             [--cmd-time-out=<number>] [-l] [-D] [-d]\n"
205730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"             \n"
20583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"  --pid arg must be given if multiple Valgrind gdbservers are found.\n"
20593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"  --vgdb-prefix arg must be given to both Valgrind and vgdb utility\n"
20603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"      if you want to change the default prefix for the FIFOs communication\n"
20613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"      between the Valgrind gdbserver and vgdb.\n"
206230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"  --wait (default 0) tells vgdb to check during the specified number\n"
20633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"      of seconds if a Valgrind gdbserver can be found.\n"
206430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"  --max-invoke-ms (default 100) gives the nr of milli-seconds after which vgdb\n"
206530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"      will force the invocation of the Valgrind gdbserver (if the Valgrind\n"
206630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"         process is blocked in a system call).\n"
2067992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj"  --port instructs vgdb to listen for gdb on the specified port nr.\n"
206830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"  --cmd-time-out (default 99999999) tells vgdb to exit if the found Valgrind\n"
206930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"     gdbserver has not processed a command after number seconds\n"
2070d142f99836471d4245250247cc9ac7bc5a1391fasewardj"  -l  arg tells to show the list of running Valgrind gdbserver and then exit.\n"
207130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"  -D  arg tells to show shared mem status and then exit.\n"
207230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"  -d  arg tells to show debug info. Multiple -d args for more debug info\n"
2073d142f99836471d4245250247cc9ac7bc5a1391fasewardj"\n"
2074d142f99836471d4245250247cc9ac7bc5a1391fasewardj"  -h --help shows this message\n"
2075d142f99836471d4245250247cc9ac7bc5a1391fasewardj"  To get help from the Valgrind gdbserver, use vgdb help\n"
20763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"\n"
20773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           );
207830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   ptrace_restrictions_msg();
20793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
20803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
208130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj/* If show_list, outputs on stdout the list of Valgrind processes with gdbserver activated.
2082d142f99836471d4245250247cc9ac7bc5a1391fasewardj                 and then exits.
2083d142f99836471d4245250247cc9ac7bc5a1391fasewardj
2084d142f99836471d4245250247cc9ac7bc5a1391fasewardj   else if arg_pid == -1, waits maximum check_trials seconds to discover
20853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   a valgrind pid appearing.
2086d142f99836471d4245250247cc9ac7bc5a1391fasewardj
20873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Otherwise verify arg_pid is valid and corresponds to a Valgrind process
20883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   with gdbserver activated.
20893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
20903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns the pid to work with
20913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   or exits in case of error (e.g. no pid found corresponding to arg_pid */
20923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
20933b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
2094d142f99836471d4245250247cc9ac7bc5a1391fasewardjint search_arg_pid(int arg_pid, int check_trials, Bool show_list)
20953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
20963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int i;
20973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int pid = -1;
20983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
20993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (arg_pid == 0 || arg_pid < -1) {
21003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      fprintf (stderr, "vgdb error: invalid pid %d given\n", arg_pid);
21013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      exit (1);
21023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else {
21033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* search for a matching named fifo.
21043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         If we have been given a pid, we will check that the matching FIFO is
21053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         there (or wait the nr of check_trials for this to appear).
21063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         If no pid has been given, then if we find only one FIFO,
21073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         we will use this to build the pid to use.
21083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         If we find multiple processes with valid FIFO, we report them and will
21093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         exit with an error. */
21103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DIR *vgdb_dir;
21113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      char *vgdb_dir_name = vmalloc (strlen (vgdb_prefix) + 3);
21123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      struct dirent *f;
21133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      int is;
21143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      int nr_valid_pid = 0;
21153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      const char *suffix = "-from-vgdb-to-"; /* followed by pid */
21163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      char *vgdb_format = vmalloc (strlen(vgdb_prefix) + strlen(suffix) + 1);
21173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
21183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      strcpy (vgdb_format, vgdb_prefix);
21193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      strcat (vgdb_format, suffix);
21203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
21213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      strcpy (vgdb_dir_name, vgdb_prefix);
21223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
21233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      for (is = strlen(vgdb_prefix) - 1; is >= 0; is--)
21243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (vgdb_dir_name[is] == '/') {
21253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            vgdb_dir_name[is+1] = '\0';
21263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            break;
21273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
21283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (strlen(vgdb_dir_name) == 0)
21293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         strcpy (vgdb_dir_name, "./");
21303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
21313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "searching pid in directory %s format %s\n",
21323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            vgdb_dir_name, vgdb_format);
21333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
21343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* try to find FIFOs with valid pid.
21353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         On exit of the loop, pid is set to:
2136d142f99836471d4245250247cc9ac7bc5a1391fasewardj         the last pid found if show_list (or -1 if no process was listed)
21373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         -1 if no FIFOs matching a running process is found
21383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         -2 if multiple FIFOs of running processes are found
21393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         otherwise it is set to the (only) pid found that can be debugged
21403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      */
21413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      for (i = 0; i < check_trials; i++) {
21423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         DEBUG(1, "check_trial %d \n", i);
21433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (i > 0)
21443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           /* wait one second before checking again */
21453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           sleep(1);
21463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
21473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         vgdb_dir = opendir (vgdb_dir_name);
21483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (vgdb_dir == NULL)
21493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            XERROR (errno,
21503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                    "vgdb error: opening directory %s searching vgdb fifo\n",
21513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                    vgdb_dir_name);
21523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
21533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         errno = 0; /* avoid complain if vgdb_dir is empty */
21543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         while ((f = readdir (vgdb_dir))) {
21553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            struct stat st;
21563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            char pathname[strlen(vgdb_dir_name) + strlen(f->d_name)];
21573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            char *wrongpid;
21583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            int newpid;
21593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
21603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            strcpy (pathname, vgdb_dir_name);
21613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            strcat (pathname, f->d_name);
21623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(3, "trying %s\n", pathname);
21633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            if (stat (pathname, &st) != 0) {
21643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               if (debuglevel >= 3)
21653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  ERROR (errno, "vgdb error: stat %s searching vgdb fifo\n",
21663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                         pathname);
21673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            } else if (S_ISFIFO (st.st_mode)) {
21683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               DEBUG(3, "trying %s\n", pathname);
21693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               if (strncmp (pathname, vgdb_format,
21703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                            strlen (vgdb_format)) == 0) {
21713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  newpid = strtol(pathname + strlen (vgdb_format),
21723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                                  &wrongpid, 10);
2173ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian                  if (*wrongpid == '-' && newpid > 0
21743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                      && kill (newpid, 0) == 0) {
21753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     nr_valid_pid++;
2176d142f99836471d4245250247cc9ac7bc5a1391fasewardj                     if (show_list) {
217730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj                        report_pid (newpid, /*on_stdout*/ True);
2178d142f99836471d4245250247cc9ac7bc5a1391fasewardj                        pid = newpid;
2179d142f99836471d4245250247cc9ac7bc5a1391fasewardj                     } else if (arg_pid != -1) {
21803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                        if (arg_pid == newpid) {
21813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                           pid = newpid;
21823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                        }
21833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     } else if (nr_valid_pid > 1) {
21843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                        if (nr_valid_pid == 2) {
21853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                           fprintf
21863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                              (stderr,
21873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                               "no --pid= arg given"
21883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                               " and multiple valgrind pids found:\n");
218930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj                           report_pid (pid, /*on_stdout*/ False);
21903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                        }
21913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                        pid = -2;
219230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj                        report_pid (newpid, /*on_stdout*/ False);
21933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     } else {
21943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                        pid = newpid;
21953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     }
21963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  }
21973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               }
21983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            }
21993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            errno = 0; /* avoid complain if at the end of vgdb_dir */
22003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
22013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (f == NULL && errno != 0)
22023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            XERROR (errno, "vgdb error: reading directory %s for vgdb fifo\n",
22033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                    vgdb_dir_name);
22043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
22053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         closedir (vgdb_dir);
22063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (pid != -1)
22073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            break;
22083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
22093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
22103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      free (vgdb_dir_name);
22113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      free (vgdb_format);
22123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
2213d142f99836471d4245250247cc9ac7bc5a1391fasewardj
2214d142f99836471d4245250247cc9ac7bc5a1391fasewardj   if (show_list) {
2215d142f99836471d4245250247cc9ac7bc5a1391fasewardj      exit (1);
2216d142f99836471d4245250247cc9ac7bc5a1391fasewardj   } else if (pid == -1) {
22173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (arg_pid == -1)
22183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         fprintf (stderr, "vgdb error: no FIFO found and no pid given\n");
22193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      else
22203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         fprintf (stderr, "vgdb error: no FIFO found matching pid %d\n",
22213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  arg_pid);
22223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      exit (1);
22233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
22243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else if (pid == -2) {
22253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* no arg_pid given, multiple FIFOs found */
22263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      exit (1);
22273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
22283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else {
22293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return pid;
22303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
22313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
22323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
22333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* return true if the numeric value of an option of the
22343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   form --xxxxxxxxx=<number> could properly be extracted
22353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   from arg. If True is returned, *value contains the
22363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   extracted value.*/
22373b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
22383b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool numeric_val(char* arg, int *value)
22393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
22403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   const char *eq_pos = strchr(arg, '=');
22413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   char *wrong;
224230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   long long int long_value;
22433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
22443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (eq_pos == NULL)
22453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
22463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
224730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   long_value = strtoll(eq_pos+1, &wrong, 10);
224830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   if (long_value < 0 || long_value > INT_MAX)
224930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      return False;
22503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (*wrong)
22513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
22523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
225330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   *value = (int) long_value;
22543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return True;
22553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
22563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
22573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* true if arg matches the provided option */
22583b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
22593b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool is_opt(char* arg, char *option)
22603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
22613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int option_len = strlen(option);
22623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (option[option_len-1] == '=')
22633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return (0 == strncmp(option, arg, option_len));
22643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else
22653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return (0 == strcmp(option, arg));
22663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
22673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
22683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Parse command lines options. If error(s), exits.
22693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Otherwise returns the options in *p_... args.
22703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   commands must be big enough for the commands extracted from argv.
22713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   On return, *p_last_command gives the position in commands where
22723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   the last command has been allocated (using vmalloc). */
22733b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
22743b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid parse_options(int argc, char** argv,
22753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   Bool *p_show_shared_mem,
2276d142f99836471d4245250247cc9ac7bc5a1391fasewardj                   Bool *p_show_list,
22773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   int *p_arg_pid,
22783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   int *p_check_trials,
2279992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj                   int *p_port,
22803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   int *p_last_command,
22813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   char *commands[])
22823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
22833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Bool show_shared_mem = False;
2284d142f99836471d4245250247cc9ac7bc5a1391fasewardj   Bool show_list = False;
22853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int arg_pid = -1;
22863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int check_trials = 1;
22873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int last_command = -1;
2288992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   int int_port = 0;
22893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
22903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int i;
22913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int arg_errors = 0;
22923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
22933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   for (i = 1; i < argc; i++) {
22943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (is_opt(argv[i], "--help") || is_opt(argv[i], "-h")) {
22953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         usage();
22963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         exit(0);
22973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else if (is_opt(argv[i], "-d")) {
22983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         debuglevel++;
22993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else if (is_opt(argv[i], "-D")) {
23003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         show_shared_mem = True;
2301d142f99836471d4245250247cc9ac7bc5a1391fasewardj      } else if (is_opt(argv[i], "-l")) {
2302d142f99836471d4245250247cc9ac7bc5a1391fasewardj         show_list = True;
23033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else if (is_opt(argv[i], "--pid=")) {
23043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         int newpid;
23053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (!numeric_val(argv[i], &newpid)) {
230630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            fprintf (stderr, "invalid --pid argument %s\n", argv[i]);
23073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            arg_errors++;
23083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         } else if (arg_pid != -1) {
230930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            fprintf (stderr, "multiple --pid arguments given\n");
23103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            arg_errors++;
23113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         } else {
23123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            arg_pid = newpid;
23133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
23143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else if (is_opt(argv[i], "--wait=")) {
23153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (!numeric_val(argv[i], &check_trials)) {
231630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            fprintf (stderr, "invalid --wait argument %s\n", argv[i]);
23173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            arg_errors++;
23183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
23193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else if (is_opt(argv[i], "--max-invoke-ms=")) {
23203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (!numeric_val(argv[i], &max_invoke_ms)) {
232130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            fprintf (stderr, "invalid --max-invoke-ms argument %s\n", argv[i]);
232230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            arg_errors++;
232330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         }
232430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      } else if (is_opt(argv[i], "--cmd-time-out=")) {
232530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         if (!numeric_val(argv[i], &cmd_time_out)) {
232630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            fprintf (stderr, "invalid --cmd-time-out argument %s\n", argv[i]);
23273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            arg_errors++;
23283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
2329992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj      } else if (is_opt(argv[i], "--port=")) {
2330992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj         if (!numeric_val(argv[i], &int_port)) {
2331992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj            fprintf (stderr, "invalid --port argument %s\n", argv[i]);
2332992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj            arg_errors++;
2333992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj         }
23343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else if (is_opt(argv[i], "--vgdb-prefix=")) {
23353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         vgdb_prefix = argv[i] + 14;
23363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else if (is_opt(argv[i], "-c")) {
23373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         last_command++;
23383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         commands[last_command] = vmalloc (1);
23393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         commands[last_command][0] = '\0';
23403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else if (0 == strncmp(argv[i], "-", 1)) {
23413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         fprintf (stderr, "unknown or invalid argument %s\n", argv[i]);
23423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         arg_errors++;
23433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else {
23443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         int len;
23453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (last_command == -1) {
23463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            /* only one command, no -c command indicator */
23473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            last_command++;
23483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            commands[last_command] = vmalloc (1);
23493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            commands[last_command][0] = '\0';
23503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
23513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         len = strlen(commands[last_command]);
23523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         commands[last_command] = vrealloc (commands[last_command],
23533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                                            len + 1 + strlen(argv[i]) + 1);
23543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (len > 0)
23553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            strcat (commands[last_command], " ");
23563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         strcat (commands[last_command], argv[i]);
23573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (packet_len_for_command(commands[last_command]) > PBUFSIZ) {
23583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            fprintf (stderr, "command %s too long\n", commands[last_command]);
23593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            arg_errors++;
23603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
23613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
23623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
23633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
2364d142f99836471d4245250247cc9ac7bc5a1391fasewardj
2365b985e2de52983cafd2d17cc6c9e60064847777fdflorian   if (vgdb_prefix == NULL)
2366b985e2de52983cafd2d17cc6c9e60064847777fdflorian      vgdb_prefix = vgdb_prefix_default();
2367b985e2de52983cafd2d17cc6c9e60064847777fdflorian
2368d142f99836471d4245250247cc9ac7bc5a1391fasewardj   if (isatty(0)
2369d142f99836471d4245250247cc9ac7bc5a1391fasewardj       && !show_shared_mem
2370d142f99836471d4245250247cc9ac7bc5a1391fasewardj       && !show_list
2371992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj       && int_port == 0
2372d142f99836471d4245250247cc9ac7bc5a1391fasewardj       && last_command == -1) {
2373d142f99836471d4245250247cc9ac7bc5a1391fasewardj      arg_errors++;
2374d142f99836471d4245250247cc9ac7bc5a1391fasewardj      fprintf (stderr,
2375d142f99836471d4245250247cc9ac7bc5a1391fasewardj               "Using vgdb standalone implies to give -D or -l or a COMMAND\n");
2376d142f99836471d4245250247cc9ac7bc5a1391fasewardj   }
2377d142f99836471d4245250247cc9ac7bc5a1391fasewardj
2378d142f99836471d4245250247cc9ac7bc5a1391fasewardj   if (show_shared_mem && show_list) {
2379d142f99836471d4245250247cc9ac7bc5a1391fasewardj      arg_errors++;
2380d142f99836471d4245250247cc9ac7bc5a1391fasewardj      fprintf (stderr,
2381d142f99836471d4245250247cc9ac7bc5a1391fasewardj               "Can't use both -D and -l options\n");
2382d142f99836471d4245250247cc9ac7bc5a1391fasewardj   }
2383d142f99836471d4245250247cc9ac7bc5a1391fasewardj
238430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   if (max_invoke_ms > 0
238530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj       && cmd_time_out != NEVER
238630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj       && (cmd_time_out * 1000) <= max_invoke_ms) {
238730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      arg_errors++;
238830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      fprintf (stderr,
238930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj               "--max-invoke-ms must be < --cmd-time-out * 1000\n");
239030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   }
239130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj
2392d142f99836471d4245250247cc9ac7bc5a1391fasewardj   if (show_list && arg_pid != -1) {
2393d142f99836471d4245250247cc9ac7bc5a1391fasewardj      arg_errors++;
2394d142f99836471d4245250247cc9ac7bc5a1391fasewardj      fprintf (stderr,
2395d142f99836471d4245250247cc9ac7bc5a1391fasewardj               "Can't use both --pid and -l options\n");
2396d142f99836471d4245250247cc9ac7bc5a1391fasewardj   }
2397d142f99836471d4245250247cc9ac7bc5a1391fasewardj
2398992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   if (int_port > 0 && last_command != -1) {
2399992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj      arg_errors++;
2400992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj      fprintf (stderr,
2401992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj               "Can't use --port to send commands\n");
2402992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   }
2403992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj
24043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (arg_errors > 0) {
24053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      fprintf (stderr, "args error. Try `vgdb --help` for more information\n");
24063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      exit(1);
24073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
24083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
24093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   *p_show_shared_mem = show_shared_mem;
2410d142f99836471d4245250247cc9ac7bc5a1391fasewardj   *p_show_list = show_list;
24113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   *p_arg_pid = arg_pid;
24123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   *p_check_trials = check_trials;
2413992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   *p_port = int_port;
24143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   *p_last_command = last_command;
24153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
24163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
24173b290486cd4cd601b20e04340e593c9ed9717e5fsewardjint main(int argc, char** argv)
24183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
24193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int i;
24203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int pid;
24213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
24223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Bool show_shared_mem;
2423d142f99836471d4245250247cc9ac7bc5a1391fasewardj   Bool show_list;
24243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int arg_pid;
24253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int check_trials;
2426992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   int in_port;
24273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int last_command;
24283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   char *commands[argc]; // we will never have more commands than args.
24293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
24303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   parse_options(argc, argv,
24313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                 &show_shared_mem,
2432d142f99836471d4245250247cc9ac7bc5a1391fasewardj                 &show_list,
24333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                 &arg_pid,
24343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                 &check_trials,
2435992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj                 &in_port,
24363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                 &last_command,
24373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                 commands);
24383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
24393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* when we are working as a relay for gdb, handle some signals by
24403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      only reporting them (according to debug level). Also handle these
24413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      when ptrace will be used: vgdb must clean up the ptrace effect before
24423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      dying. */
24433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (max_invoke_ms > 0 || last_command == -1)
24443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      install_handlers();
24453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2446d142f99836471d4245250247cc9ac7bc5a1391fasewardj   pid = search_arg_pid (arg_pid, check_trials, show_list);
24473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
24483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   prepare_fifos_and_shared_mem(pid);
24493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2450992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   if (in_port > 0)
2451992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj      wait_for_gdb_connect(in_port);
2452992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj
24533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (show_shared_mem) {
24543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      fprintf(stderr,
24553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              "vgdb %d "
24563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              "written_by_vgdb %d "
24573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              "seen_by_valgrind %d\n"
24583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              "vgdb pid %d\n",
24593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              VS_vgdb_pid,
24603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              VS_written_by_vgdb,
24613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              VS_seen_by_valgrind,
24623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              VS_vgdb_pid);
24633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      exit (0);
24643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
24653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
24663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (last_command >= 0) {
24673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      standalone_send_commands(pid, last_command, commands);
24683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else {
24693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      gdb_relay(pid);
24703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
24713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
24723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
24733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   free (from_gdb_to_pid);
24743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   free (to_gdb_from_pid);
24753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   free (shared_mem);
24763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
24773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   for (i = 0; i <= last_command; i++)
24783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      free (commands[i]);
24793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return 0;
24803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
2481