/* Shared utility routines for GDB to interact with agent.

   Copyright (C) 2009-2020 Free Software Foundation, Inc.

   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 "common-defs.h"
#include "target/target.h"
#include "gdbsupport/symbol.h"
#include <unistd.h>
#include "filestuff.h"

#define IPA_SYM_STRUCT_NAME ipa_sym_addresses_common
#include "agent.h"

bool debug_agent = false;

/* A stdarg wrapper for debug_vprintf.  */

static void ATTRIBUTE_PRINTF (1, 2)
debug_agent_printf (const char *fmt, ...)
{
  va_list ap;

  if (!debug_agent)
    return;
  va_start (ap, fmt);
  debug_vprintf (fmt, ap);
  va_end (ap);
}

#define DEBUG_AGENT debug_agent_printf

/* Global flag to determine using agent or not.  */
bool use_agent = false;

/* Addresses of in-process agent's symbols both GDB and GDBserver cares
   about.  */

struct ipa_sym_addresses_common
{
  CORE_ADDR addr_helper_thread_id;
  CORE_ADDR addr_cmd_buf;
  CORE_ADDR addr_capability;
};

/* Cache of the helper thread id.  FIXME: this global should be made
   per-process.  */
static uint32_t helper_thread_id = 0;

static struct
{
  const char *name;
  int offset;
} symbol_list[] = {
  IPA_SYM(helper_thread_id),
  IPA_SYM(cmd_buf),
  IPA_SYM(capability),
};

static struct ipa_sym_addresses_common ipa_sym_addrs;

static bool all_agent_symbols_looked_up = false;

bool
agent_loaded_p (void)
{
  return all_agent_symbols_looked_up;
}

/* Look up all symbols needed by agent.  Return 0 if all the symbols are
   found, return non-zero otherwise.  */

int
agent_look_up_symbols (void *arg)
{
  all_agent_symbols_looked_up = false;

  for (int i = 0; i < sizeof (symbol_list) / sizeof (symbol_list[0]); i++)
    {
      CORE_ADDR *addrp =
	(CORE_ADDR *) ((char *) &ipa_sym_addrs + symbol_list[i].offset);
      struct objfile *objfile = (struct objfile *) arg;

      if (find_minimal_symbol_address (symbol_list[i].name, addrp,
				       objfile) != 0)
	{
	  DEBUG_AGENT ("symbol `%s' not found\n", symbol_list[i].name);
	  return -1;
	}
    }

  all_agent_symbols_looked_up = true;
  return 0;
}

static unsigned int
agent_get_helper_thread_id (void)
{
  if  (helper_thread_id == 0)
    {
      if (target_read_uint32 (ipa_sym_addrs.addr_helper_thread_id,
			      &helper_thread_id))
	warning (_("Error reading helper thread's id in lib"));
    }

  return helper_thread_id;
}

#ifdef HAVE_SYS_UN_H
#include <sys/socket.h>
#include <sys/un.h>
#define SOCK_DIR P_tmpdir

#ifndef UNIX_PATH_MAX
#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path)
#endif

#endif

/* Connects to synchronization socket.  PID is the pid of inferior, which is
   used to set up the connection socket.  */

static int
gdb_connect_sync_socket (int pid)
{
#ifdef HAVE_SYS_UN_H
  struct sockaddr_un addr;
  int res, fd;
  char path[UNIX_PATH_MAX];

  res = xsnprintf (path, UNIX_PATH_MAX, "%s/gdb_ust%d", P_tmpdir, pid);
  if (res >= UNIX_PATH_MAX)
    return -1;

  res = fd = gdb_socket_cloexec (PF_UNIX, SOCK_STREAM, 0);
  if (res == -1)
    {
      warning (_("error opening sync socket: %s"), safe_strerror (errno));
      return -1;
    }

  addr.sun_family = AF_UNIX;

  res = xsnprintf (addr.sun_path, UNIX_PATH_MAX, "%s", path);
  if (res >= UNIX_PATH_MAX)
    {
      warning (_("string overflow allocating socket name"));
      close (fd);
      return -1;
    }

  res = connect (fd, (struct sockaddr *) &addr, sizeof (addr));
  if (res == -1)
    {
      warning (_("error connecting sync socket (%s): %s. "
		 "Make sure the directory exists and that it is writable."),
		 path, safe_strerror (errno));
      close (fd);
      return -1;
    }

  return fd;
#else
  return -1;
#endif
}

/* Execute an agent command in the inferior.  PID is the value of pid of the
   inferior.  CMD is the buffer for command.  GDB or GDBserver will store the
   command into it and fetch the return result from CMD.  The interaction
   between GDB/GDBserver and the agent is synchronized by a synchronization
   socket.  Return zero if success, otherwise return non-zero.  */

int
agent_run_command (int pid, const char *cmd, int len)
{
  int fd;
  int tid = agent_get_helper_thread_id ();
  ptid_t ptid = ptid_t (pid, tid, 0);

  int ret = target_write_memory (ipa_sym_addrs.addr_cmd_buf,
				 (gdb_byte *) cmd, len);

  if (ret != 0)
    {
      warning (_("unable to write"));
      return -1;
    }

  DEBUG_AGENT ("agent: resumed helper thread\n");

  /* Resume helper thread.  */
  target_continue_no_signal (ptid);

  fd = gdb_connect_sync_socket (pid);
  if (fd >= 0)
    {
      char buf[1] = "";

      DEBUG_AGENT ("agent: signalling helper thread\n");

      do
	{
	  ret = write (fd, buf, 1);
	} while (ret == -1 && errno == EINTR);

	DEBUG_AGENT ("agent: waiting for helper thread's response\n");

      do
	{
	  ret = read (fd, buf, 1);
	} while (ret == -1 && errno == EINTR);

      close (fd);

      DEBUG_AGENT ("agent: helper thread's response received\n");
    }
  else
    return -1;

  /* Need to read response with the inferior stopped.  */
  if (ptid != null_ptid)
    {
      /* Stop thread PTID.  */
      DEBUG_AGENT ("agent: stop helper thread\n");
      target_stop_and_wait (ptid);
    }

  if (fd >= 0)
    {
      if (target_read_memory (ipa_sym_addrs.addr_cmd_buf, (gdb_byte *) cmd,
			      IPA_CMD_BUF_SIZE))
	{
	  warning (_("Error reading command response"));
	  return -1;
	}
    }

  return 0;
}

/* Each bit of it stands for a capability of agent.  */
static uint32_t agent_capability = 0;

/* Return true if agent has capability AGENT_CAP, otherwise return false.  */

bool
agent_capability_check (enum agent_capa agent_capa)
{
  if (agent_capability == 0)
    {
      if (target_read_uint32 (ipa_sym_addrs.addr_capability,
			      &agent_capability))
	warning (_("Error reading capability of agent"));
    }
  return (agent_capability & agent_capa) != 0;
}

/* Invalidate the cache of agent capability, so we'll read it from inferior
   again.  Call it when launches a new program or reconnect to remote stub.  */

void
agent_capability_invalidate (void)
{
  agent_capability = 0;
}
