/* Target operations for the remote server for GDB.
   Copyright (C) 2002, 2004, 2005, 2007, 2008, 2009, 2010, 2011
   Free Software Foundation, Inc.

   Contributed by MontaVista Software.

   This file is part of GDB.

   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 3 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, see <http://www.gnu.org/licenses/>.  */

#include "server.h"

struct target_ops *the_target;

void
set_desired_inferior (int use_general)
{
  struct thread_info *found;

  if (use_general == 1)
    found = find_thread_ptid (general_thread);
  else
    {
      found = NULL;

      /* If we are continuing any (all) thread(s), use step_thread
	 to decide which thread to step and/or send the specified
	 signal to.  */
      if ((!ptid_equal (step_thread, null_ptid)
	   && !ptid_equal (step_thread, minus_one_ptid))
	  && (ptid_equal (cont_thread, null_ptid)
	      || ptid_equal (cont_thread, minus_one_ptid)))
	found = find_thread_ptid (step_thread);

      if (found == NULL)
	found = find_thread_ptid (cont_thread);
    }

  if (found == NULL)
    current_inferior = (struct thread_info *) all_threads.head;
  else
    current_inferior = found;
}

int
read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
{
  int res;
  res = (*the_target->read_memory) (memaddr, myaddr, len);
  check_mem_read (memaddr, myaddr, len);
  return res;
}

int
write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr,
		       int len)
{
  /* Lacking cleanups, there is some potential for a memory leak if the
     write fails and we go through error().  Make sure that no more than
     one buffer is ever pending by making BUFFER static.  */
  static unsigned char *buffer = 0;
  int res;

  if (buffer != NULL)
    free (buffer);

  buffer = xmalloc (len);
  memcpy (buffer, myaddr, len);
  check_mem_write (memaddr, buffer, len);
  res = (*the_target->write_memory) (memaddr, buffer, len);
  free (buffer);
  buffer = NULL;

  return res;
}

ptid_t
mywait (ptid_t ptid, struct target_waitstatus *ourstatus, int options,
	int connected_wait)
{
  ptid_t ret;

  if (connected_wait)
    server_waiting = 1;

  ret = (*the_target->wait) (ptid, ourstatus, options);

  if (ourstatus->kind == TARGET_WAITKIND_EXITED)
    fprintf (stderr,
	     "\nChild exited with status %d\n", ourstatus->value.integer);
  else if (ourstatus->kind == TARGET_WAITKIND_SIGNALLED)
    fprintf (stderr, "\nChild terminated with signal = 0x%x (%s)\n",
	     target_signal_to_host (ourstatus->value.sig),
	     target_signal_to_name (ourstatus->value.sig));

  if (connected_wait)
    server_waiting = 0;

  return ret;
}

int
start_non_stop (int nonstop)
{
  if (the_target->start_non_stop == NULL)
    {
      if (nonstop)
	return -1;
      else
	return 0;
    }

  return (*the_target->start_non_stop) (nonstop);
}

void
set_target_ops (struct target_ops *target)
{
  the_target = (struct target_ops *) xmalloc (sizeof (*the_target));
  memcpy (the_target, target, sizeof (*the_target));
}

/* Convert pid to printable format.  */

const char *
target_pid_to_str (ptid_t ptid)
{
  static char buf[80];

  if (ptid_equal (ptid, minus_one_ptid))
    xsnprintf (buf, sizeof (buf), "<all threads>");
  else if (ptid_equal (ptid, null_ptid))
    xsnprintf (buf, sizeof (buf), "<null thread>");
  else if (ptid_get_tid (ptid) != 0)
    xsnprintf (buf, sizeof (buf), "Thread %d.0x%lx",
	       ptid_get_pid (ptid), ptid_get_tid (ptid));
  else if (ptid_get_lwp (ptid) != 0)
    xsnprintf (buf, sizeof (buf), "LWP %d.%ld",
	       ptid_get_pid (ptid), ptid_get_lwp (ptid));
  else
    xsnprintf (buf, sizeof (buf), "Process %d",
	       ptid_get_pid (ptid));

  return buf;
}

/* Return a pretty printed form of target_waitstatus.  */

const char *
target_waitstatus_to_string (const struct target_waitstatus *ws)
{
  static char buf[200];
  const char *kind_str = "status->kind = ";

  switch (ws->kind)
    {
    case TARGET_WAITKIND_EXITED:
      sprintf (buf, "%sexited, status = %d",
	       kind_str, ws->value.integer);
      break;
    case TARGET_WAITKIND_STOPPED:
      sprintf (buf, "%sstopped, signal = %s",
	       kind_str, target_signal_to_name (ws->value.sig));
      break;
    case TARGET_WAITKIND_SIGNALLED:
      sprintf (buf, "%ssignalled, signal = %s",
	       kind_str, target_signal_to_name (ws->value.sig));
      break;
    case TARGET_WAITKIND_LOADED:
      sprintf (buf, "%sloaded", kind_str);
      break;
    case TARGET_WAITKIND_EXECD:
      sprintf (buf, "%sexecd", kind_str);
      break;
    case TARGET_WAITKIND_SPURIOUS:
      sprintf (buf, "%sspurious", kind_str);
      break;
    case TARGET_WAITKIND_IGNORE:
      sprintf (buf, "%signore", kind_str);
      break;
    default:
      sprintf (buf, "%sunknown???", kind_str);
      break;
    }

  return buf;
}
