/* Target operations for the remote server for GDB.
   Copyright (C) 2002, 2004, 2005, 2007, 2008, 2009
   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.sig);
  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))
    snprintf (buf, sizeof (buf), "<all threads>");
  else if (ptid_equal (ptid, null_ptid))
    snprintf (buf, sizeof (buf), "<null thread>");
  else if (ptid_get_tid (ptid) != 0)
    snprintf (buf, sizeof (buf), "Thread %d.0x%lx",
	      ptid_get_pid (ptid), ptid_get_tid (ptid));
  else if (ptid_get_lwp (ptid) != 0)
    snprintf (buf, sizeof (buf), "LWP %d.%ld",
	      ptid_get_pid (ptid), ptid_get_lwp (ptid));
  else
    snprintf (buf, sizeof (buf), "Process %d",
	      ptid_get_pid (ptid));

  return buf;
}
