
/*--------------------------------------------------------------------*/
/*--- Handle remote gdb protocol.                    m_gdbserver.c ---*/
/*--------------------------------------------------------------------*/

/*
   This file is part of Valgrind, a dynamic binary instrumentation
   framework.

   Copyright (C) 2011-2011 Philippe Waroquiers

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307, USA.

   The GNU General Public License is contained in the file COPYING.
*/

#include "pub_core_basics.h"
#include "pub_core_vki.h"
#include "pub_core_debuglog.h"
#include "pub_core_libcproc.h"
#include "pub_core_libcprint.h"
#include "pub_core_mallocfree.h"
#include "pub_core_gdbserver.h"
#include "pub_core_options.h"
#include "pub_core_libcsetjmp.h"
#include "pub_core_threadstate.h"
#include "pub_core_transtab.h"
#include "pub_tool_hashtable.h"
#include "pub_core_libcassert.h"
#include "pub_tool_libcbase.h"
#include "pub_core_libcsignal.h"
#include "pub_tool_machine.h"     // VG_(fnptr_to_fnentry)
#include "pub_tool_debuginfo.h"
#include "pub_core_scheduler.h"
#include "pub_core_syswrap.h"

#include "server.h"

Int VG_(dyn_vgdb_error);

/* forward declarations */
VG_REGPARM(1)
void VG_(helperc_CallDebugger) ( HWord iaddr );
VG_REGPARM(1)
void VG_(helperc_invalidate_if_not_gdbserved) ( Addr addr );
static void invalidate_current_ip (ThreadId tid, char *who);

/* reasons of call to call_gdbserver. */
typedef
   enum {
      init_reason,    // initialises gdbserver resources
      vgdb_reason,    // gdbserver invocation by vgdb doing ptrace
      core_reason,    // gdbserver invocation by core (e.g. error encountered)
      break_reason,   // break encountered
      watch_reason,   // watchpoint detected by tool
      signal_reason}  // signal encountered
    CallReason;

static char* ppCallReason(CallReason reason)
{
   switch (reason) {
   case init_reason:    return "init_reason";
   case vgdb_reason:    return "vgdb_reason";
   case core_reason:    return "core_reason";
   case break_reason:   return "break_reason";
   case watch_reason:   return "watch_reason";
   case signal_reason:  return "signal_reason";
   default: vg_assert (0);
   }
}

/* An instruction instrumented for gdbserver looks like this:
    1. Ist_Mark (0x1234)
    2. Put (IP, 0x1234)
    3. helperc_CallDebugger (0x1234)   
         This will give control to gdb if there is a break at 0x1234
         or if we are single stepping
    4. ... here the real IR for the instruction at 0x1234

    When there is a break at 0x1234:
      if user does "continue" or "step" or similar, 
        then - the call to debugger returns
             - valgrind executes at 3. the real IR(s) for 0x1234

      if as part of helperc_CallDebugger, the user calls 
      some code in gdb e.g print hello_world()
        then - gdb prepares a dummy stack frame with a specific 
               return address (typically it uses _start) and
               inserts a break at this address
             - gdb then puts in EIP the address of hello_world()
             - gdb then continues (so the helperc_CallDebugger
               returns)
             - call_gdbserver() function will then return the
               control to the scheduler (using VG_MINIMAL_LONGJMP)
               to allow the block of the new EIP
               to be executed.
             - hello_world code is executed.
             - when hello_world() returns, it returns to
               _start and encounters the break at _start.
             - gdb then removes this break, put 0x1234 in EIP
               and does a "step". This causes to jump from
               _start to 0x1234, where the call to 
                helperc_CallDebugger is redone.
             - This is all ok, the user can then give new gdb 
               commands. 

    However, when continue is given, address 0x1234 is to
    be executed: gdb gives a single step, which must not 
    report again the break at 0x1234. To avoid a 2nd report
    of the same break, the below tells that the next 
    helperc_CallDebugger call must ignore a break/stop at
    this address.
*/
static Addr ignore_this_break_once = 0;


static void call_gdbserver ( ThreadId tid , CallReason reason);

/* convert from CORE_ADDR to void* */
static
void* C2v(CORE_ADDR addr)
{
   return (void*) addr;
}

/* Describes the address addr (for debugging/printing purposes).
   Last two results are kept. A third call will replace the
   oldest result. */
static char* sym (Addr addr, Bool is_code)
{
   static char buf[2][200];
   static int w = 0;
   PtrdiffT offset;
   if (w == 2) w = 0;
   if (is_code) {
      VG_(describe_IP) (addr, buf[w], 200);
   } else {
      VG_(get_datasym_and_offset) (addr, buf[w], 200, &offset);
   }
   return buf[w++];
}

/* Each time gdbserver is called, gdbserver_called is incremented
   gdbserver_exited is incremented when gdbserver is asked to exit */
static int gdbserver_called = 0;
static int gdbserver_exited = 0;

typedef
   enum {
     GS_break,
     GS_jump
   }
   GS_Kind;

typedef
   struct _GS_Address {
      struct _GS_Address* next;
      Addr    addr;
      GS_Kind kind;
   }
   GS_Address;

/* gs_addresses contains a list of all addresses that have been invalidated
   because they have been (or must be) instrumented for gdbserver. 
   An entry is added in this table when there is a break at this
   address (kind == GS_break) or if this address is the jump target of an
   exit of a block that has been instrumented for gdbserver while
   single stepping (kind == GS_jump).
   When gdbserver is not single stepping anymore, all GS_jump entries
   are removed, their translations are invalidated.

   Note for ARM: addr in GS_Address is the value without the thumb bit set.
*/
static VgHashTable gs_addresses = NULL;

// Transform addr in the form stored in the list of addresses.
// For the ARM architecture, we store it with the thumb bit set to 0.
static Addr HT_addr ( Addr addr )
{
#if defined(VGA_arm)
  return addr & ~(Addr)1;
#else
  return addr;
#endif
}

static void add_gs_address (Addr addr, GS_Kind kind, char* from)
{
   GS_Address *p;

   p = VG_(arena_malloc)(VG_AR_CORE, from, sizeof(GS_Address));
   p->addr = HT_addr (addr);
   p->kind = kind;
   VG_(HT_add_node)(gs_addresses, p);
   /* It should be sufficient to discard a range of 1.
      We use 2 to ensure the below is not sensitive to the presence
      of thumb bit in the range of addresses to discard. */ 
   VG_(discard_translations) (addr, 2, from);
}

static void remove_gs_address (GS_Address* g, char* from)
{
   VG_(HT_remove) (gs_addresses, g->addr);
   // See add_gs_address for the explanation for the range 2 below.
   VG_(discard_translations) (g->addr, 2, from);
   VG_(arena_free) (VG_AR_CORE, g);
}

char* VG_(ppPointKind) (PointKind kind)
{
   switch(kind) {
   case software_breakpoint: return "software_breakpoint";
   case hardware_breakpoint: return "hardware_breakpoint";
   case write_watchpoint:    return "write_watchpoint";
   case read_watchpoint:     return "read_watchpoint";
   case access_watchpoint:   return "access_watchpoint";
   default: vg_assert(0);
   }
}

typedef
   struct _GS_Watch {
      struct _GS_Watch* next;
      Addr    addr;
      SizeT   len;
      PointKind kind;
   }
   GS_Watch;

/* gs_watches contains a list of all addresses+len that are being watched. */
static VgHashTable gs_watches = NULL;


/* protocol spec tells the below must be idempotent. */
static void breakpoint (Bool insert, CORE_ADDR addr)
{
   GS_Address *g;

   g = VG_(HT_lookup) (gs_addresses, (UWord)HT_addr(addr));
   if (insert) {
      /* insert a breakpoint at addr or upgrade its kind */
      if (g == NULL) {
         add_gs_address (addr, GS_break, "m_gdbserver breakpoint insert");
      } else {
         /* already gdbserved. Normally, it must be because of a jump.
            However, due to idempotent or if connection with gdb was
            lost (kept breaks from the previous gdb), if already existing,
            we just upgrade its kind. */
         g->kind = GS_break;
      }
   } else {
      /* delete a breakpoint at addr or downgrade its kind */
      if (g != NULL && g->kind == GS_break) {
         if (valgrind_single_stepping()) {
            /* keep gdbserved instrumentation while single stepping */
            g->kind = GS_jump;
         } else {
            remove_gs_address (g, "m_gdbserver breakpoint remove");
         }
      } else {
         dlog (1, "remove break addr %p %s\n",
               C2v(addr), (g == NULL ? 
                           "NULL" : 
                           (g->kind == GS_jump ? "GS_jump" : "GS_break")));
      }
   }
}

static Bool (*tool_watchpoint) (PointKind kind, 
                                Bool insert, 
                                Addr addr,
                                SizeT len) = NULL;
void VG_(needs_watchpoint) (Bool (*watchpoint) (PointKind kind, 
                                                Bool insert, 
                                                Addr addr,
                                                SizeT len))
{
   tool_watchpoint = watchpoint;
}
     
Bool VG_(gdbserver_point) (PointKind kind, Bool insert,
                           CORE_ADDR addr, int len)
{
   Bool res;
   GS_Watch *g;
   Bool is_code = kind == software_breakpoint || kind == hardware_breakpoint;

   dlog(1, "%s %s at addr %p %s\n",
        (insert ? "insert" : "remove"), 
        VG_(ppPointKind) (kind),
        C2v(addr), 
        sym(addr, is_code));

   if (is_code) {
      breakpoint (insert, addr);
      return True;
   }

   vg_assert (kind == access_watchpoint 
              || kind == read_watchpoint 
              || kind == write_watchpoint);

   if (tool_watchpoint == NULL)
      return False;

   res = (*tool_watchpoint) (kind, insert, addr, len);
   if (!res) 
      return False; /* error or unsupported */

   g = VG_(HT_lookup) (gs_watches, (UWord)addr);
   if (insert) {
      if (g == NULL) {
         g = VG_(arena_malloc)(VG_AR_CORE, "gdbserver_point watchpoint",
                               sizeof(GS_Watch));
         g->addr = addr;
         g->len  = len;
         g->kind = kind;
         VG_(HT_add_node)(gs_watches, g);
      } else {
         g->kind = kind;
      }
   } else {
      vg_assert (g != NULL);
      VG_(HT_remove) (gs_watches, g->addr);
      VG_(arena_free) (VG_AR_CORE, g);
   }  
   return True;
}

Bool VG_(is_watched)(PointKind kind, Addr addr, Int szB)
{
   GS_Watch* g;
   Bool watched = False;
   const ThreadId tid = VG_(running_tid);

   if (!gdbserver_called)
      return False;

   Addr to = addr + szB; // semi-open interval [addr, to[

   vg_assert (kind == access_watchpoint 
              || kind == read_watchpoint 
              || kind == write_watchpoint);
   dlog(1, "tid %d VG_(is_watched) %s addr %p szB %d\n",
        tid, VG_(ppPointKind) (kind), C2v(addr), szB);
   VG_(HT_ResetIter) (gs_watches);
   while ((g = VG_(HT_Next) (gs_watches))) {
      switch (g->kind) {
      case software_breakpoint:
      case hardware_breakpoint:
         break;
      case access_watchpoint:
      case read_watchpoint:
      case write_watchpoint:
         if (to <= g->addr || addr >= (g->addr + g->len))
            /* If no overlap, examine next watchpoint: */
            continue;

         watched = True; /* We have an overlap */

         /* call gdbserver if access kind reported by the tool
            matches the watchpoint kind. */
         if (kind == access_watchpoint
             || g->kind == access_watchpoint
             || g->kind == kind) {
            /* Watchpoint encountered.
               If this is a read watchpoint, we directly call gdbserver
               to report it to gdb.
               Otherwise, for a write watchpoint, we have to finish
               the instruction so as to modify the value.
               If we do not finish the instruction, then gdb sees no
               value change and continues.
               For a read watchpoint, we better call gdbserver directly:
               in case the current block is not gdbserved, Valgrind
               will execute instructions till the next block. */

            /* set the watchpoint stop address to the first read or written. */
            if (g->addr <= addr) {
               VG_(set_watchpoint_stop_address) (addr);
            } else {
               VG_(set_watchpoint_stop_address) (g->addr);
            }

            if (kind == write_watchpoint) {
               /* Let Valgrind stop as early as possible after this instruction
                  by switching to Single Stepping mode. */
               valgrind_set_single_stepping (True);
               invalidate_current_ip (tid, "m_gdbserver write watchpoint");
            } else {
               call_gdbserver (tid, watch_reason);
               VG_(set_watchpoint_stop_address) ((Addr) 0);
            }
            return True; // we are watched here.
         }
         break;
      default:
         vg_assert (0);
      }
   }
   return watched;
}

/* Returns the reason for which gdbserver instrumentation is needed */
static VgVgdb VG_(gdbserver_instrumentation_needed) (VexGuestExtents* vge)
{
   GS_Address* g;
   int e;

   if (!gdbserver_called)
      return Vg_VgdbNo;

   if (valgrind_single_stepping()) {
      dlog(2, "gdbserver_instrumentation_needed due to single stepping\n");
      return Vg_VgdbYes;
   }

   if (VG_(clo_vgdb) == Vg_VgdbYes && VG_(HT_count_nodes) (gs_addresses) == 0)
      return Vg_VgdbNo;

   /* We assume we do not have a huge nr of breakpoints.
      Otherwise, we need something more efficient e.g.
      a sorted list of breakpoints or associate extents to it or ...
   */
   VG_(HT_ResetIter) (gs_addresses);
   while ((g = VG_(HT_Next) (gs_addresses))) {
      for (e = 0; e < vge->n_used; e++) {
         if (g->addr >= HT_addr(vge->base[e]) 
             && g->addr < HT_addr(vge->base[e]) + vge->len[e]) {
            dlog(2,
                 "gdbserver_instrumentation_needed %p %s reason %s\n",
                 C2v(g->addr), sym(g->addr, /* is_code */ True),
                 (g->kind == GS_jump ? "GS_jump" : "GS_break"));
            return Vg_VgdbYes;
         }
      }
   }

   if (VG_(clo_vgdb) == Vg_VgdbFull) {
      dlog(4, "gdbserver_instrumentation_needed"
           " due to VG_(clo_vgdb) == Vg_VgdbFull\n");
      return Vg_VgdbFull;
   }


   return Vg_VgdbNo;
}

// Clear gdbserved_addresses in gs_addresses.
// If clear_only_jumps, clears only the addresses that are served
// for jump reasons.
// Otherwise, clear all the addresses.
// Cleared addresses are invalidated so as to have them re-translated.
static void clear_gdbserved_addresses(Bool clear_only_jumps)
{
   GS_Address** ag;
   UInt n_elems;
   int i;

   dlog(1,
        "clear_gdbserved_addresses: scanning hash table nodes %d\n", 
        VG_(HT_count_nodes) (gs_addresses));
   ag = (GS_Address**) VG_(HT_to_array) (gs_addresses, &n_elems);
   for (i = 0; i < n_elems; i++)
      if (!clear_only_jumps || ag[i]->kind == GS_jump)
         remove_gs_address (ag[i], "clear_gdbserved_addresses");
   VG_(free) (ag);
}

// Clear watched addressed in gs_watches
static void clear_watched_addresses(void)
{
   GS_Watch** ag;
   UInt n_elems;
   int i;

   dlog(1,
        "clear_watched_addresses: scanning hash table nodes %d\n", 
        VG_(HT_count_nodes) (gs_watches));
   ag = (GS_Watch**) VG_(HT_to_array) (gs_watches, &n_elems);
   for (i = 0; i < n_elems; i++) {
      if (!VG_(gdbserver_point) (ag[i]->kind,
                                 /* insert */ False,
                                 ag[i]->addr,
                                 ag[i]->len)) {
         vg_assert (0);
      }
   }
   VG_(free) (ag);
}

static void invalidate_if_jump_not_yet_gdbserved (Addr addr, char* from)
{
   if (VG_(HT_lookup) (gs_addresses, (UWord)HT_addr(addr)))
      return;
   add_gs_address (addr, GS_jump, from);
}

static void invalidate_current_ip (ThreadId tid, char *who)
{
   invalidate_if_jump_not_yet_gdbserved (VG_(get_IP) (tid), who);
}

void VG_(gdbserver_prerun_action) (ThreadId tid)
{
   // Using VG_(dyn_vgdb_error) allows the user to control if gdbserver
   // stops after a fork.
   if (VG_(dyn_vgdb_error) == 0) {
      /* The below call allows gdb to attach at startup
         before the first guest instruction is executed. */
      VG_(umsg)("(action at startup) vgdb me ... \n");
      VG_(gdbserver)(tid); 
   } else {
      /* User has activated gdbserver => initialize now the FIFOs
         to let vgdb/gdb contact us either via the scheduler poll
         mechanism or via vgdb ptrace-ing valgrind. */
      if (VG_(gdbserver_activity) (tid))
         VG_(gdbserver) (tid);
   }
}

/* when fork is done, various cleanup is needed in the child process.
   In particular, child must have its own connection to avoid stealing 
   data from its parent */
static void gdbserver_cleanup_in_child_after_fork(ThreadId me)
{
   dlog(1, "thread %d gdbserver_cleanup_in_child_after_fork pid %d\n",
        me, VG_(getpid) ());

   /* finish connection inheritated from parent */
   remote_finish(reset_after_fork);

   /* ensure next call to gdbserver will be considered as a brand
      new call that will initialize a fresh gdbserver. */
   if (gdbserver_called) {
      gdbserver_called = 0;
      vg_assert (gs_addresses != NULL);
      vg_assert (gs_watches != NULL);
      clear_gdbserved_addresses(/* clear only jumps */ False);
      VG_(HT_destruct) (gs_addresses);
      gs_addresses = NULL;
      clear_watched_addresses();
      VG_(HT_destruct) (gs_watches);
      gs_watches = NULL;
   } else {
      vg_assert (gs_addresses == NULL);
      vg_assert (gs_watches == NULL);
   }

   
   if (VG_(clo_trace_children)) {
      VG_(gdbserver_prerun_action) (me);
   }
}

/* If reason is init_reason, creates the connection resources (e.g.
      the FIFOs) to allow a gdb connection to be detected by polling
      using remote_desc_activity.
   Otherwise (other reasons):
       If connection with gdb not yet opened, opens the connection with gdb.
       reads gdb remote protocol packets and executes the requested commands.
*/
static void call_gdbserver ( ThreadId tid , CallReason reason)
{
   ThreadState*     tst = VG_(get_ThreadState)(tid);
   int stepping;
   Addr saved_pc;

   dlog(1, 
        "entering call_gdbserver %s ... pid %d tid %d status %s "
        "sched_jmpbuf_valid %d\n",
        ppCallReason (reason),
        VG_(getpid) (), tid, VG_(name_of_ThreadStatus)(tst->status),
        tst->sched_jmpbuf_valid);

   vg_assert(VG_(is_valid_tid)(tid));
   saved_pc = VG_(get_IP) (tid);

   if (gdbserver_exited) {
      dlog(0, "call_gdbserver called when gdbserver_exited %d\n",
           gdbserver_exited);
      return;
   }

   if (gdbserver_called == 0) {
      vg_assert (gs_addresses == NULL);
      vg_assert (gs_watches == NULL);
      gs_addresses = VG_(HT_construct)( "gdbserved_addresses" );
      gs_watches = VG_(HT_construct)( "gdbserved_watches" );
      VG_(atfork)(NULL, NULL, gdbserver_cleanup_in_child_after_fork);
   }
   vg_assert (gs_addresses != NULL);
   vg_assert (gs_watches != NULL);
   
   gdbserver_called++;

   /* call gdbserver_init if this is the first call to gdbserver. */
   if (gdbserver_called == 1)
      gdbserver_init();

   if (reason == init_reason || gdbserver_called == 1)
      remote_open(VG_(clo_vgdb_prefix));

   /* if the call reason is to initialize, then return control to
      valgrind. After this initialization, gdbserver will be called
      again either if there is an error detected by valgrind or
      if vgdb sends data to the valgrind process. */
   if (reason == init_reason) {
      return;
   }

   stepping = valgrind_single_stepping();

   server_main();

   ignore_this_break_once = valgrind_get_ignore_break_once();
   if (ignore_this_break_once)
      dlog(1, "!!! will ignore_this_break_once %s\n", 
           sym(ignore_this_break_once, /* is_code */ True));
      

   if (valgrind_single_stepping()) {
      /* we are single stepping. If we were not stepping on entry,
         then invalidate the current program counter so as to properly
         do single step. In case the program counter was changed by
         gdb, this will also invalidate the target address we will
         jump to. */
      if (!stepping && tid != 0) {
         invalidate_current_ip (tid, "m_gdbserver single step");
      }
   } else {
      /* We are not single stepping.  If we were stepping on entry,
         then clear the gdbserved addresses.  This will cause all
         these gdbserved blocks to be invalidated so that they can be
         re-translated without being gdbserved. */
      if (stepping)
         clear_gdbserved_addresses(/* clear only jumps */ True);
   }
   
   /* can't do sanity check at beginning. At least the stack
      check is not yet possible. */
   if (gdbserver_called > 1)
      VG_(sanity_check_general) (/* force_expensive */ False);

   /* If the PC has been changed by gdb, then we VG_MINIMAL_LONGJMP to
      the scheduler to execute the block of the new PC.
      Otherwise we just return to continue executing the
      current block. */
   if (VG_(get_IP) (tid) != saved_pc) {
      dlog(1, "tid %d %s PC changed from %s to %s\n",
           tid, VG_(name_of_ThreadStatus) (tst->status),
           sym(saved_pc, /* is_code */ True),
           sym(VG_(get_IP) (tid), /* is_code */ True));
      if (tst->status == VgTs_Yielding) {
         SysRes sres;
         VG_(memset)(&sres, 0, sizeof(SysRes));
         VG_(acquire_BigLock)(tid, "gdbsrv VG_MINIMAL_LONGJMP");
      }
      if (tst->sched_jmpbuf_valid) {
         /* resume scheduler */
         VG_MINIMAL_LONGJMP(tst->sched_jmpbuf);
      }
      /* else continue to run */
   }
   /* continue to run */
}

/* busy > 0 when gdbserver is currently being called.
   busy is used to to avoid vgdb invoking gdbserver
   while gdbserver by Valgrind. */
static volatile int busy = 0;

void VG_(gdbserver) ( ThreadId tid )
{
   busy++;
   /* called by the rest of valgrind for 
         --vgdb-error=0 reason
      or by scheduler "poll/debug/interrupt" reason
      or to terminate. */
   if (tid != 0) {
      call_gdbserver (tid, core_reason);
   } else {
      if (gdbserver_called == 0) {
         dlog(1, "VG_(gdbserver) called to terminate, nothing to terminate\n");
      } else if (gdbserver_exited) {
         dlog(0, "VG_(gdbserver) called to terminate again %d\n",
              gdbserver_exited);
      } else {
         gdbserver_terminate();
         gdbserver_exited++;
      }
   }
   busy--;
}

// nr of invoke_gdbserver while gdbserver is already executing.
static int interrupts_while_busy = 0;

// nr of invoke_gdbserver while gdbserver is not executing.
static int interrupts_non_busy = 0;

// nr of invoke_gdbserver when some threads are not interruptible.
static int interrupts_non_interruptible = 0;

/* When all threads are blocked in a system call, the Valgrind
   scheduler cannot poll the shared memory for gdbserver activity.  In
   such a case, vgdb will force the invokation of gdbserver using
   ptrace. To do that, vgdb 'pushes' a call to invoke_gdbserver
   on the stack using ptrace. invoke_gdbserver must not return.
   Instead, it must call give_control_back_to_vgdb.
   vgdb expects to receive a SIGSTOP, which this function generates.
   When vgdb gets this SIGSTOP, it knows invoke_gdbserver call
   is finished and can reset the Valgrind process in the state prior to
   the 'pushed call' (using ptrace again).
   This all works well. However, the user must avoid
   'kill-9ing' vgdb during such a pushed call, otherwise
   the SIGSTOP generated below will be seen by the Valgrind core,
   instead of being handled by vgdb. The OS will then handle the SIGSTOP
   by stopping the Valgrind process.
   We use SIGSTOP as this process cannot be masked. */

static void give_control_back_to_vgdb(void)
{
   /* cause a SIGSTOP to be sent to ourself, so that vgdb takes control.
      vgdb will then restore the stack so as to resume the activity
      before the ptrace (typically do_syscall_WRK). */
   if (VG_(kill)(VG_(getpid)(), VKI_SIGSTOP) != 0)
      vg_assert2(0, "SIGSTOP for vgdb could not be generated\n");

   /* If we arrive here, it means a call was pushed on the stack
      by vgdb, but during this call, vgdb and/or connection
      died. Alternatively, it is a bug in the vgdb<=>Valgrind gdbserver
      ptrace handling. */
   vg_assert2(0, 
              "vgdb did not took control. Did you kill vgdb ?\n"
              "busy %d vgdb_interrupted_tid %d\n",
              busy, vgdb_interrupted_tid);
}

/* Using ptrace calls, vgdb will force an invocation of gdbserver.
   VG_(invoke_gdbserver) is the entry point called through the
   vgdb ptrace technique. */
void VG_(invoke_gdbserver) ( int check )
{
   /* ******* Avoid non-reentrant function call from here ..... 
      till the ".... till here" below. */

   /* We need to determine the state of the various threads to decide
      if we directly invoke gdbserver or if we rather indicate to the
      scheduler to invoke the gdbserver.  To decide that, it is
      critical to avoid any "coregrind" function call as the ptrace
      might have stopped the process in the middle of this (possibly)
      non-rentrant function.  So, it is only when all threads are in
      an "interruptible" state that we can safely invoke
      gdbserver. Otherwise, we let the valgrind scheduler invoke
      gdbserver at the next poll.  This poll will be made very soon
      thanks to a call to VG_(force_vgdb_poll). */
   int n_tid;

   vg_assert (check == 0x8BADF00D);

   if (busy) {
      interrupts_while_busy++;
      give_control_back_to_vgdb();
   }
   interrupts_non_busy++;

   /* check if all threads are in an "interruptible" state.  If yes,
      we invoke gdbserver. Otherwise, we tell the scheduler to wake up
      asap. */
   for (n_tid = 1; n_tid < VG_N_THREADS; n_tid++) {
      switch (VG_(threads)[n_tid].status) {
      /* interruptible states. */
      case VgTs_WaitSys:
      case VgTs_Yielding:
         if (vgdb_interrupted_tid == 0) vgdb_interrupted_tid = n_tid;
         break;

      case VgTs_Empty:     
      case VgTs_Zombie:
         break;

      /* non interruptible states. */
      case VgTs_Init:
      case VgTs_Runnable:
         interrupts_non_interruptible++;
         VG_(force_vgdb_poll) ();
         give_control_back_to_vgdb();

      default:             vg_assert(0);
      }
   }

   /* .... till here.
      From here onwards, function calls are ok: it is
      safe to call valgrind core functions: all threads are blocked in
      a system call or are yielding or ... */
   dlog(1, "invoke_gdbserver running_tid %d vgdb_interrupted_tid %d\n",
        VG_(running_tid), vgdb_interrupted_tid);
   call_gdbserver (vgdb_interrupted_tid, vgdb_reason);
   vgdb_interrupted_tid = 0;
   dlog(1,
        "exit invoke_gdbserver running_tid %d\n", VG_(running_tid));
   give_control_back_to_vgdb();

   vg_assert2(0, "end of invoke_gdbserver reached");

}

Bool VG_(gdbserver_activity) (ThreadId tid)
{
   Bool ret;
   busy++;
   if (!gdbserver_called)
      call_gdbserver (tid, init_reason);
   switch (remote_desc_activity("VG_(gdbserver_activity)")) {
   case 0: ret = False; break;
   case 1: ret = True; break;
   case 2: call_gdbserver (tid, init_reason); ret = False; break;
   default: vg_assert (0);
   }
   busy--;
   return ret;
}

Bool VG_(gdbserver_report_signal) (Int sigNo, ThreadId tid)
{
   dlog(1, "signal %d tid %d\n", sigNo, tid);

   /* if gdbserver is currently not connected, then signal
      is to be given to the process */
   if (!remote_connected()) {
      dlog(1, "not connected => pass\n");
      return True;
   }
   /* if gdb has informed gdbserver that this signal can be
      passed directly without informing gdb, then signal is
      to be given to the process. */
   if (pass_signals[sigNo]) {
      dlog(1, "pass_signals => pass\n");
      return True;
   }
   
   /* indicate to gdbserver that there is a signal */
   gdbserver_signal_encountered (sigNo);

   /* let gdbserver do some work, e.g. show the signal to the user */
   call_gdbserver (tid, signal_reason);
   
   /* ask gdbserver what is the final decision */
   if (gdbserver_deliver_signal (sigNo)) {
      dlog(1, "gdbserver deliver signal\n");
      return True;
   } else {
      dlog(1, "gdbserver ignore signal\n");
      return False;
   }
}

// Check if single_stepping or if there is a break requested at iaddr. 
// If yes, call debugger
VG_REGPARM(1)
void VG_(helperc_CallDebugger) ( HWord iaddr )
{
   GS_Address* g;

   // For Vg_VgdbFull, after a fork, we might have calls to this helper
   // while gdbserver is not yet initialized.
   if (!gdbserver_called)
      return;

   if (valgrind_single_stepping() ||
       ((g = VG_(HT_lookup) (gs_addresses, (UWord)HT_addr(iaddr))) &&
        (g->kind == GS_break))) {
      if (iaddr == HT_addr(ignore_this_break_once)) {
         dlog(1, "ignoring ignore_this_break_once %s\n", 
              sym(ignore_this_break_once, /* is_code */ True));
         ignore_this_break_once = 0;
      } else {
         call_gdbserver (VG_(get_running_tid)(), break_reason);
      }
   }
}

/* software_breakpoint support --------------------------------------*/
/* When a block is instrumented for gdbserver, single step and breaks
   will be obeyed in this block.  However, if a jump to another block
   is executed while single_stepping is active, we must ensure that
   this block is also instrumented. For this, when a block is
   instrumented for gdbserver while single_stepping, the target of all
   the Jump instructions in this block will be checked to verify if
   the block is already instrumented for gdbserver.  The below will
   ensure that if not already instrumented for gdbserver, the target
   block translation containing addr will be invalidated.  The list of
   gdbserved Addr will also be kept so that translations can be
   dropped automatically by gdbserver when going out of single step
   mode.

   Call the below at translation time if the jump target is a constant. 
   Otherwise, rather use VG_(add_stmt_call_invalidate_if_not_gdbserved).

   To instrument the target exit statement, you can call
   VG_(add_stmt_call_invalidate_exit_target_if_not_gdbserved) rather
   than check the kind of target exit. */
static void VG_(invalidate_if_not_gdbserved) (Addr addr)
{
   if (valgrind_single_stepping())
      invalidate_if_jump_not_yet_gdbserved
         (addr, "gdbserver target jump (instrument)");
}

// same as VG_(invalidate_if_not_gdbserved) but is intended to be called 
// at runtime (only difference is the invalidate reason which traces 
// it is at runtime)
VG_REGPARM(1)
void VG_(helperc_invalidate_if_not_gdbserved) ( Addr addr )
{
   if (valgrind_single_stepping())
      invalidate_if_jump_not_yet_gdbserved
         (addr, "gdbserver target jump (runtime)");
}

static void VG_(add_stmt_call_invalidate_if_not_gdbserved)
     ( IRSB* sb_in,
       VexGuestLayout* layout, 
       VexGuestExtents* vge,
       IRTemp jmp, 
       IRSB* irsb)
{
   
   void*    fn;
   HChar*   nm;
   IRExpr** args;
   Int      nargs;
   IRDirty* di;

   fn    = &VG_(helperc_invalidate_if_not_gdbserved);
   nm    = "VG_(helperc_invalidate_if_not_gdbserved)";
   args  = mkIRExprVec_1(IRExpr_RdTmp (jmp));
   nargs = 1;
   
   di = unsafeIRDirty_0_N( nargs/*regparms*/, nm, 
                           VG_(fnptr_to_fnentry)( fn ), args );

   di->nFxState = 0;

   addStmtToIRSB(irsb, IRStmt_Dirty(di));
}

/* software_breakpoint support --------------------------------------*/
/* If a tool wants to allow gdbserver to do something at Addr, then
   VG_(add_stmt_call_gdbserver) will add in IRSB a call to a helper
   function.  This helper function will check if the process must be
   stopped at the instruction Addr: either there is a break at Addr or
   the process is being single-stepped.  Typical usage of the below is to
   instrument an Ist_IMark to allow the debugger to interact at any
   instruction being executed.  As soon as there is one break in a block,
   then to allow single stepping in this block (and possible insertions
   of other breaks in the same sb_in while the process is stopped), a
   debugger statement will be inserted for all instructions of a block. */
static void VG_(add_stmt_call_gdbserver) 
     (IRSB* sb_in,                /* block being translated */
      VexGuestLayout* layout, 
      VexGuestExtents* vge,
      IRType gWordTy, IRType hWordTy,
      Addr  iaddr,                /* Addr of instruction being instrumented */
      UChar delta,                /* delta to add to iaddr to obtain IP */
      IRSB* irsb)                 /* irsb block to which call is added */
{
   void*    fn;
   HChar*   nm;
   IRExpr** args;
   Int      nargs;
   IRDirty* di;

   /* first store the address in the program counter so that the check
      done by VG_(helperc_CallDebugger) will be based on the correct
      program counter.  We might make this more efficient by rather
      searching for assignement to program counter and instrumenting
      that but the below is easier and I guess that the optimiser will
      remove the redundant store. And in any case, when debugging a
      piece of code, the efficiency requirement is not critical: very
      few blocks will be instrumented for debugging. */

   /* For platforms on which the IP can differ from the addr of the instruction
      being executed, we need to add the delta to obtain the IP.
      This IP will be given to gdb (e.g. if a breakpoint is put at iaddr).

      For ARM, this delta will ensure that the thumb bit is set in the
      IP when executing thumb code. gdb uses this thumb bit a.o.
      to properly guess the next IP for the 'step' and 'stepi' commands. */
   vg_assert(delta <= 1);
   addStmtToIRSB(irsb, IRStmt_Put(layout->offset_IP ,
                                  mkIRExpr_HWord(iaddr + (Addr)delta)));

   fn    = &VG_(helperc_CallDebugger);
   nm    = "VG_(helperc_CallDebugger)";
   args  = mkIRExprVec_1(mkIRExpr_HWord (iaddr));
   nargs = 1;
   
   di = unsafeIRDirty_0_N( nargs/*regparms*/, nm, 
                           VG_(fnptr_to_fnentry)( fn ), args );

   /* Note: in fact, a debugger call can read whatever register
      or memory. It can also write whatever register or memory.
      So, in theory, we have to indicate the whole universe
      can be read and modified. It is however not critical
      to indicate precisely what is being read/written
      as such indications are needed for tool error detection
      and we do not want to have errors being detected for
      gdb interactions. */
   
   di->nFxState = 2;
   di->fxState[0].fx     = Ifx_Read;
   di->fxState[0].offset = layout->offset_SP;
   di->fxState[0].size   = layout->sizeof_SP;
   di->fxState[1].fx     = Ifx_Modify;
   di->fxState[1].offset = layout->offset_IP;
   di->fxState[1].size   = layout->sizeof_IP;

   addStmtToIRSB(irsb, IRStmt_Dirty(di));

}


/* Invalidate the target of the exit if needed:
   If target is constant, it is invalidated at translation time.
   Otherwise, a call to a helper function is generated to invalidate
   the translation at run time.
   The below is thus calling either VG_(invalidate_if_not_gdbserved)
   or VG_(add_stmt_call_invalidate_if_not_gdbserved).  */
static void VG_(add_stmt_call_invalidate_exit_target_if_not_gdbserved)
   (IRSB* sb_in,
    VexGuestLayout* layout,
    VexGuestExtents* vge,
    IRType gWordTy,
    IRSB* irsb)
{
   if (sb_in->next->tag == Iex_Const) {
     VG_(invalidate_if_not_gdbserved) (gWordTy == Ity_I64 ?
                                       sb_in->next->Iex.Const.con->Ico.U64 
                                       : sb_in->next->Iex.Const.con->Ico.U32);
   } else if (sb_in->next->tag == Iex_RdTmp) {
     VG_(add_stmt_call_invalidate_if_not_gdbserved)
       (sb_in, layout, vge, sb_in->next->Iex.RdTmp.tmp, irsb);
   } else {
     vg_assert (0); /* unexpected expression tag in exit. */
   }
}

IRSB* VG_(instrument_for_gdbserver_if_needed)
     (IRSB* sb_in,
      VexGuestLayout* layout,
      VexGuestExtents* vge,
      IRType gWordTy, IRType hWordTy)
{
   IRSB* sb_out;
   Int i;
   const VgVgdb instr_needed = VG_(gdbserver_instrumentation_needed) (vge);

   if (instr_needed == Vg_VgdbNo)
     return sb_in;


   /* here, we need to instrument for gdbserver */
   sb_out = deepCopyIRSBExceptStmts(sb_in);

   for (i = 0; i < sb_in->stmts_used; i++) {
      IRStmt* st = sb_in->stmts[i];
      
      if (!st || st->tag == Ist_NoOp) continue;
      
      if (st->tag == Ist_Exit && instr_needed == Vg_VgdbYes) {
        VG_(invalidate_if_not_gdbserved) 
          (hWordTy == Ity_I64 ? 
           st->Ist.Exit.dst->Ico.U64 : 
           st->Ist.Exit.dst->Ico.U32);
      }
      addStmtToIRSB( sb_out, st );
      if (st->tag == Ist_IMark) {
         /* For an Ist_Mark, add a call to debugger. */
         switch (instr_needed) {
         case Vg_VgdbNo: vg_assert (0);
         case Vg_VgdbYes:
         case Vg_VgdbFull:
            VG_(add_stmt_call_gdbserver) ( sb_in, layout, vge,
                                           gWordTy, hWordTy,
                                           st->Ist.IMark.addr,
                                           st->Ist.IMark.delta,
                                           sb_out);
            /* There is an optimisation possible here for Vg_VgdbFull:
               Put a guard ensuring we only call gdbserver if 'FullCallNeeded'.
               FullCallNeeded would be set to 1 we have just switched on
               Single Stepping or have just encountered a watchpoint
               or have just inserted a breakpoint.
               (as gdb by default removes and re-insert breakpoints), we would
               need to also implement the notion of 'breakpoint pending removal'
               to remove at the next 'continue/step' packet. */
            break;
         default: vg_assert (0);
         }
      }
   }

   if (instr_needed == Vg_VgdbYes) {
      VG_(add_stmt_call_invalidate_exit_target_if_not_gdbserved) (sb_in,
                                                                  layout, vge,
                                                                  gWordTy,
                                                                  sb_out);
   }

   return sb_out;
}

struct mon_out_buf {
   char buf[DATASIZ+1];
   int next;
   UInt ret;
};

static void mon_out (HChar c, void *opaque)
{
   struct mon_out_buf *b = (struct mon_out_buf *) opaque;
   b->ret++;
   b->buf[b->next] = c;
   b->next++;
   if (b->next == DATASIZ) {
      b->buf[b->next] = '\0';
      monitor_output(b->buf);
      b->next = 0;
   }
}
UInt VG_(gdb_printf) ( const HChar *format, ... )
{
   struct mon_out_buf b;

   b.next = 0;
   b.ret = 0;
   
   va_list vargs;
   va_start(vargs, format);
   VG_(vcbprintf) (mon_out, &b, format, vargs);
   va_end(vargs);
   
   if (b.next > 0) {
      b.buf[b.next] = '\0';
      monitor_output(b.buf);
   }
   return b.ret;
}

Int VG_(keyword_id) (Char* keywords, Char* input_word, kwd_report_error report)
{
   const Int il = (input_word == NULL ? 0 : VG_(strlen) (input_word));
   Char  iw[il+1];
   Char  kwds[VG_(strlen)(keywords)+1];
   Char  *kwdssaveptr;

   Char* kw; /* current keyword, its length, its position */
   Int   kwl;
   Int   kpos = -1;

   Int pass; 
   /* pass 0 = search, optional pass 1 = output message multiple matches */

   Int pass1needed = 0;

   Int partial_match = -1;
   Int full_match = -1;

   if (input_word == NULL) {
      iw[0] = 0;
      partial_match = 0; /* to force an empty string to cause an error */
   } else {
      VG_(strcpy) (iw, input_word);
   }

   for (pass = 0; pass < 2; pass++) {
      VG_(strcpy) (kwds, keywords);
      if (pass == 1)
         VG_(gdb_printf) ("%s can match", 
                          (il == 0 ? "<empty string>" : (char *) iw));
      for (kw = VG_(strtok_r) (kwds, " ", &kwdssaveptr); 
           kw != NULL; 
           kw = VG_(strtok_r) (NULL, " ", &kwdssaveptr)) {
         kwl = VG_(strlen) (kw);
         kpos++;
         
         if (il > kwl) {
            ; /* ishtar !~ is */
         } else if (il == kwl) {
            if (VG_(strcmp) (kw, iw) == 0) {
               /* exact match */
               if (pass == 1)
                  VG_(gdb_printf) (" %s", kw);
               if (full_match != -1)
                  pass1needed++;
               full_match = kpos;
            }
         } else {
            /* il < kwl */
            if (VG_(strncmp) (iw, kw, il) == 0) {
               /* partial match */
               if (pass == 1)
                  VG_(gdb_printf) (" %s", kw);
               if (partial_match != -1)
                  pass1needed++;
               partial_match = kpos;
            }
         }
      }
      /* check for success or for no match at all */
      if (pass1needed == 0) {
         if (full_match != -1) {
            return full_match;
         } else {
            if (report == kwd_report_all && partial_match == -1) {
               VG_(gdb_printf) ("%s does not match any of '%s'\n", 
                                iw, keywords);
            }
            return partial_match;
         }
      }

      /* here we have duplicated match error */
      if (pass == 1 || report == kwd_report_none) {
         if (report != kwd_report_none) {
            VG_(gdb_printf) ("\n");
         }
         if (partial_match != -1 || full_match != -1)
            return -2;
         else
            return -1;
      }
   }
   /* UNREACHED */
   vg_assert (0);
}

/* True if string can be a 0x number */
static Bool is_zero_x (Char *s)
{
   if (strlen (s) >= 3 && s[0] == '0' && s[1] == 'x')
      return True;
   else
      return False;
}

/* True if string can be a 0b number */
static Bool is_zero_b (Char *s)
{
   if (strlen (s) >= 3 && s[0] == '0' && s[1] == 'b')
      return True;
   else
      return False;
}

void VG_(strtok_get_address_and_size) (Addr* address, 
                                       SizeT* szB, 
                                       Char **ssaveptr)
{
   Char* wa;
   Char* ws;
   Char* endptr;
   UChar *ppc;

   wa = VG_(strtok_r) (NULL, " ", ssaveptr);
   ppc = wa;
   if (ppc == NULL || !VG_(parse_Addr) (&ppc, address)) {
      VG_(gdb_printf) ("missing or malformed address\n");
      *address = (Addr) 0;
      *szB = 0;
      return;
   }
   ws = VG_(strtok_r) (NULL, " ", ssaveptr);
   if (ws == NULL) {
      /* Do nothing, i.e. keep current value of szB. */ ;
   } else if (is_zero_x (ws)) {
      *szB = VG_(strtoull16) (ws, &endptr);
   } else if (is_zero_b (ws)) {
      Int j;
      Char *parsews = ws;
      Int n_bits = VG_(strlen) (ws) - 2;
      *szB = 0;
      ws = NULL; // assume the below loop gives a correct nr.
      for (j = 0; j < n_bits; j++) {
         if      ('0' == parsews[j+2]) { /* do nothing */ }
         else if ('1' == parsews[j+2]) *szB |= (1 << (n_bits-j-1));
         else {
            /* report malformed binary integer */
            ws = parsews;
            endptr = ws + j + 2;
            break;
         }
      }
   } else {
      *szB = VG_(strtoull10) (ws, &endptr);
   }

   if (ws != NULL && *endptr != '\0') {
      VG_(gdb_printf) ("malformed integer, expecting "
                       "hex 0x..... or dec ...... or binary .....b\n");
      *address = (Addr) 0;
      *szB = 0;
      return;
   }
}

void VG_(gdbserver_status_output)(void)
{
   const int nr_gdbserved_addresses 
      = (gs_addresses == NULL ? -1 : VG_(HT_count_nodes) (gs_addresses));
   const int nr_watchpoints
      = (gs_watches == NULL ? -1 : VG_(HT_count_nodes) (gs_watches));
   remote_utils_output_status();
   VG_(umsg)
      ("nr of calls to gdbserver: %d\n"
       "single stepping %d\n"
       "interrupts intr_tid %d gs_non_busy %d gs_busy %d tid_non_intr %d\n"
       "gdbserved addresses %d (-1 = not initialized)\n"
       "watchpoints %d (-1 = not initialized)\n"
       "vgdb-error %d\n",
       gdbserver_called,
       valgrind_single_stepping(),
       
       vgdb_interrupted_tid, 
       interrupts_non_busy, 
       interrupts_while_busy,
       interrupts_non_interruptible,
       
       nr_gdbserved_addresses,
       nr_watchpoints,
       VG_(dyn_vgdb_error));
}
