/* Remote target system call support.
   Copyright 1997-2023 Free Software Foundation, Inc.
   Contributed by Cygnus Solutions.

   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/>.  */

/* This interface isn't intended to be specific to any particular kind
   of remote (hardware, simulator, whatever).  As such, support for it
   (e.g. sim/common/callback.c) should *not* live in the simulator source
   tree, nor should it live in the gdb source tree.  K&R C must be
   supported.  */

/* This must come before any other includes.  */
#include "defs.h"

#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>

#include "ansidecl.h"
#include "libiberty.h"

#include "sim/callback.h"

#ifndef ENOSYS
#define ENOSYS EINVAL
#endif
#ifndef ENAMETOOLONG
#define ENAMETOOLONG EINVAL
#endif

/* Maximum length of a path name.  */
#ifndef MAX_PATH_LEN
#define MAX_PATH_LEN 1024
#endif

/* When doing file read/writes, do this many bytes at a time.  */
#define FILE_XFR_SIZE 4096

/* FIXME: for now, need to consider target word size.  */
#define TWORD long
#define TADDR unsigned long

/* Path to be prepended to syscalls with absolute paths, and to be
   chdir:ed at startup, if not empty.  */
char *simulator_sysroot = "";

/* Utility of cb_syscall to fetch a path name or other string from the target.
   The result is 0 for success or a host errno value.  */

int
cb_get_string (host_callback *cb, CB_SYSCALL *sc, char *buf, int buflen,
	       TADDR addr)
{
  char *p, *pend;

  for (p = buf, pend = buf + buflen; p < pend; ++p, ++addr)
    {
      /* No, it isn't expected that this would cause one transaction with
	 the remote target for each byte.  The target could send the
	 path name along with the syscall request, and cache the file
	 name somewhere (or otherwise tweak this as desired).  */
      unsigned int count = (*sc->read_mem) (cb, sc, addr, p, 1);

      if (count != 1)
	return EINVAL;
      if (*p == 0)
	break;
    }
  if (p == pend)
    return ENAMETOOLONG;
  return 0;
}

/* Utility of cb_syscall to fetch a path name.
   The buffer is malloc'd and the address is stored in BUFP.
   The result is that of get_string, but prepended with
   simulator_sysroot if the string starts with '/'.
   If an error occurs, no buffer is left malloc'd.  */

static int
get_path (host_callback *cb, CB_SYSCALL *sc, TADDR addr, char **bufp)
{
  char *buf = xmalloc (MAX_PATH_LEN);
  int result;
  int sysroot_len = strlen (simulator_sysroot);

  result = cb_get_string (cb, sc, buf, MAX_PATH_LEN - sysroot_len, addr);
  if (result == 0)
    {
      /* Prepend absolute paths with simulator_sysroot.  Relative paths
	 are supposed to be relative to a chdir within that path, but at
	 this point unknown where.  */
      if (simulator_sysroot[0] != '\0' && *buf == '/')
	{
	  /* Considering expected rareness of syscalls with absolute
	     file paths (compared to relative file paths and insn
	     execution), it does not seem worthwhile to rearrange things
	     to get rid of the string moves here; we'd need at least an
	     extra call to check the initial '/' in the path.  */
	  memmove (buf + sysroot_len, buf, sysroot_len);
	  memcpy (buf, simulator_sysroot, sysroot_len);
	}

      *bufp = buf;
    }
  else
    free (buf);
  return result;
}

/* Perform a system call on behalf of the target.  */

CB_RC
cb_syscall (host_callback *cb, CB_SYSCALL *sc)
{
  TWORD result = 0, errcode = 0;

  if (sc->magic != CB_SYSCALL_MAGIC)
    abort ();

  switch (cb_target_to_host_syscall (cb, sc->func))
    {
    case CB_SYS_argc:
      result = countargv (cb->argv);
      break;

    case CB_SYS_argnlen:
      {
	if (sc->arg1 >= 0 && sc->arg1 < countargv (cb->argv))
	  result = strlen (cb->argv[sc->arg1]);
	else
	  {
	    result = -1;
	    errcode = EINVAL;
	  }
      }
      break;

    case CB_SYS_argn:
      {
	if (sc->arg1 >= 0 && sc->arg1 < countargv (cb->argv))
	  {
	    const char *argn = cb->argv[sc->arg1];
	    int len = strlen (argn);
	    int written = sc->write_mem (cb, sc, sc->arg2, argn, len + 1);

	    if (written == len + 1)
	      result = sc->arg2;
	    else
	      {
		result = -1;
		errcode = EINVAL;
	      }
	  }
	else
	  {
	    result = -1;
	    errcode = EINVAL;
	  }
      }
      break;

    case CB_SYS_argvlen :
      {
	/* Compute how much space is required to store the argv,envp
	   strings so that the program can allocate the space and then
	   call SYS_argv to fetch the values.  */
	int argc, envc, arglen, envlen;
	char **argv = cb->argv;
	char **envp = cb->envp;

	argc = arglen = 0;
	if (argv)
	  {
	    for ( ; argv[argc]; ++argc)
	      arglen += strlen (argv[argc]) + 1;
	  }
	envc = envlen = 0;
	if (envp)
	  {
	    for ( ; envp[envc]; ++envc)
	      envlen += strlen (envp[envc]) + 1;
	  }
	result = arglen + 1 + envlen + 1;
	break;
      }

    case CB_SYS_argv :
      {
	/* Pointer to target's buffer.  */
	TADDR tbuf = sc->arg1;
	/* Buffer size.  */
	int bufsize = sc->arg2;
	int written = 0;
	/* Q is the target address of where all the strings go.  */
	TADDR q;
	int i, argc, envc, len, ret;
	char **argv = cb->argv;
	char **envp = cb->envp;

	result = -1;

	argc = 0;
	if (argv)
	  {
	    for ( ; argv[argc]; ++argc)
	      {
		len = strlen (argv[argc]) + 1;
		if (written + len > bufsize)
		  goto efault;

		ret = (*sc->write_mem) (cb, sc, tbuf + written, argv[argc],
					len);
		if (ret != len)
		  goto einval;

		written += ret;
	      }
	  }
	/* Double NUL bytes indicates end of strings.  */
	if (written >= bufsize)
	  goto efault;
	if ((*sc->write_mem) (cb, sc, tbuf + written, "", 1) != 1)
	  goto einval;
	++written;

	envc = 0;
	if (envp)
	  {
	    for ( ; envp[envc]; ++envc)
	      {
		len = strlen (envp[envc]) + 1;
		if (written + len > bufsize)
		  goto efault;

		ret = (*sc->write_mem) (cb, sc, tbuf + written, envp[envc],
					len);
		if (ret != len)
		  goto einval;
		written += ret;
	      }
	  }
	/* Double NUL bytes indicates end of strings.  */
	if (written >= bufsize)
	  goto efault;
	if ((*sc->write_mem) (cb, sc, tbuf + written, "", 1) != 1)
	  goto einval;

	result = argc;
	sc->result2 = envc;
	break;

 efault:
	errcode = EFAULT;
	goto FinishSyscall;

 einval:
	errcode = EINVAL;
	goto FinishSyscall;
      }

    case CB_SYS_exit :
      /* Caller must catch and handle; see sim_syscall as an example.  */
      break;

    case CB_SYS_open :
      {
	char *path;

	errcode = get_path (cb, sc, sc->arg1, &path);
	if (errcode != 0)
	  {
	    result = -1;
	    goto FinishSyscall;
	  }
	result = (*cb->open) (cb, path, sc->arg2 /*, sc->arg3*/);
	free (path);
	if (result < 0)
	  goto ErrorFinish;
      }
      break;

    case CB_SYS_close :
      result = (*cb->close) (cb, sc->arg1);
      if (result < 0)
	goto ErrorFinish;
      break;

    case CB_SYS_read :
      {
	/* ??? Perfect handling of error conditions may require only one
	   call to cb->read.  One can't assume all the data is
	   contiguously stored in host memory so that would require
	   malloc'ing/free'ing the space.  Maybe later.  */
	char buf[FILE_XFR_SIZE];
	int fd = sc->arg1;
	TADDR addr = sc->arg2;
	size_t count = sc->arg3;
	size_t bytes_read = 0;
	int bytes_written;

	while (count > 0)
	  {
	    if (cb_is_stdin (cb, fd))
	      result = (int) (*cb->read_stdin) (cb, buf,
						(count < FILE_XFR_SIZE
						 ? count : FILE_XFR_SIZE));
	    else
	      result = (int) (*cb->read) (cb, fd, buf,
					  (count < FILE_XFR_SIZE
					   ? count : FILE_XFR_SIZE));
	    if (result == -1)
	      goto ErrorFinish;
	    if (result == 0)	/* EOF */
	      break;
	    bytes_written = (*sc->write_mem) (cb, sc, addr, buf, result);
	    if (bytes_written != result)
	      {
		result = -1;
		errcode = EINVAL;
		goto FinishSyscall;
	      }
	    bytes_read += result;
	    count -= result;
	    addr += result;
	    /* If this is a short read, don't go back for more */
	    if (result != FILE_XFR_SIZE)
	      break;
	  }
	result = bytes_read;
      }
      break;

    case CB_SYS_write :
      {
	/* ??? Perfect handling of error conditions may require only one
	   call to cb->write.  One can't assume all the data is
	   contiguously stored in host memory so that would require
	   malloc'ing/free'ing the space.  Maybe later.  */
	char buf[FILE_XFR_SIZE];
	int fd = sc->arg1;
	TADDR addr = sc->arg2;
	size_t count = sc->arg3;
	int bytes_read;
	size_t bytes_written = 0;

	while (count > 0)
	  {
	    int bytes_to_read = count < FILE_XFR_SIZE ? count : FILE_XFR_SIZE;
	    bytes_read = (*sc->read_mem) (cb, sc, addr, buf, bytes_to_read);
	    if (bytes_read != bytes_to_read)
	      {
		result = -1;
		errcode = EINVAL;
		goto FinishSyscall;
	      }
	    if (cb_is_stdout (cb, fd))
	      {
		result = (int) (*cb->write_stdout) (cb, buf, bytes_read);
		(*cb->flush_stdout) (cb);
	      }
	    else if (cb_is_stderr (cb, fd))
	      {
		result = (int) (*cb->write_stderr) (cb, buf, bytes_read);
		(*cb->flush_stderr) (cb);
	      }
	    else
	      result = (int) (*cb->write) (cb, fd, buf, bytes_read);
	    if (result == -1)
	      goto ErrorFinish;
	    bytes_written += result;
	    count -= result;
	    addr += result;
	  }
	result = bytes_written;
      }
      break;

    case CB_SYS_lseek :
      {
	int fd = sc->arg1;
	unsigned long offset = sc->arg2;
	int whence = sc->arg3;

	result = (*cb->lseek) (cb, fd, offset, whence);
	if (result < 0)
	  goto ErrorFinish;
      }
      break;

    case CB_SYS_unlink :
      {
	char *path;

	errcode = get_path (cb, sc, sc->arg1, &path);
	if (errcode != 0)
	  {
	    result = -1;
	    goto FinishSyscall;
	  }
	result = (*cb->unlink) (cb, path);
	free (path);
	if (result < 0)
	  goto ErrorFinish;
      }
      break;

    case CB_SYS_truncate :
      {
	char *path;
	long len = sc->arg2;

	errcode = get_path (cb, sc, sc->arg1, &path);
	if (errcode != 0)
	  {
	    result = -1;
	    errcode = EFAULT;
	    goto FinishSyscall;
	  }
	result = (*cb->truncate) (cb, path, len);
	free (path);
	if (result < 0)
	  goto ErrorFinish;
      }
      break;

    case CB_SYS_ftruncate :
      {
	int fd = sc->arg1;
	long len = sc->arg2;

	result = (*cb->ftruncate) (cb, fd, len);
	if (result < 0)
	  goto ErrorFinish;
      }
      break;

    case CB_SYS_rename :
      {
	char *path1, *path2;

	errcode = get_path (cb, sc, sc->arg1, &path1);
	if (errcode != 0)
	  {
	    result = -1;
	    errcode = EFAULT;
	    goto FinishSyscall;
	  }
	errcode = get_path (cb, sc, sc->arg2, &path2);
	if (errcode != 0)
	  {
	    result = -1;
	    errcode = EFAULT;
	    free (path1);
	    goto FinishSyscall;
	  }
	result = (*cb->rename) (cb, path1, path2);
	free (path1);
	free (path2);
	if (result < 0)
	  goto ErrorFinish;
      }
      break;

    case CB_SYS_stat :
      {
	char *path,*buf;
	int buflen;
	struct stat statbuf;
	TADDR addr = sc->arg2;

	errcode = get_path (cb, sc, sc->arg1, &path);
	if (errcode != 0)
	  {
	    result = -1;
	    goto FinishSyscall;
	  }
	result = (*cb->to_stat) (cb, path, &statbuf);
	free (path);
	if (result < 0)
	  goto ErrorFinish;
	buflen = cb_host_to_target_stat (cb, NULL, NULL);
	buf = xmalloc (buflen);
	if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen)
	  {
	    /* The translation failed.  This is due to an internal
	       host program error, not the target's fault.  */
	    free (buf);
	    errcode = ENOSYS;
	    result = -1;
	    goto FinishSyscall;
	  }
	if ((*sc->write_mem) (cb, sc, addr, buf, buflen) != buflen)
	  {
	    free (buf);
	    errcode = EINVAL;
	    result = -1;
	    goto FinishSyscall;
	  }
	free (buf);
      }
      break;

    case CB_SYS_fstat :
      {
	char *buf;
	int buflen;
	struct stat statbuf;
	TADDR addr = sc->arg2;

	result = (*cb->to_fstat) (cb, sc->arg1, &statbuf);
	if (result < 0)
	  goto ErrorFinish;
	buflen = cb_host_to_target_stat (cb, NULL, NULL);
	buf = xmalloc (buflen);
	if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen)
	  {
	    /* The translation failed.  This is due to an internal
	       host program error, not the target's fault.  */
	    free (buf);
	    errcode = ENOSYS;
	    result = -1;
	    goto FinishSyscall;
	  }
	if ((*sc->write_mem) (cb, sc, addr, buf, buflen) != buflen)
	  {
	    free (buf);
	    errcode = EINVAL;
	    result = -1;
	    goto FinishSyscall;
	  }
	free (buf);
      }
      break;

    case CB_SYS_lstat :
      {
	char *path, *buf;
	int buflen;
	struct stat statbuf;
	TADDR addr = sc->arg2;

	errcode = get_path (cb, sc, sc->arg1, &path);
	if (errcode != 0)
	  {
	    result = -1;
	    goto FinishSyscall;
	  }
	result = (*cb->to_lstat) (cb, path, &statbuf);
	free (path);
	if (result < 0)
	  goto ErrorFinish;

	buflen = cb_host_to_target_stat (cb, NULL, NULL);
	buf = xmalloc (buflen);
	if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen)
	  {
	    /* The translation failed.  This is due to an internal
	       host program error, not the target's fault.
	       Unfortunately, it's hard to test this case, so there's no
	       test-case for this execution path.  */
	    free (buf);
	    errcode = ENOSYS;
	    result = -1;
	    goto FinishSyscall;
	  }

	if ((*sc->write_mem) (cb, sc, addr, buf, buflen) != buflen)
	  {
	    free (buf);
	    errcode = EINVAL;
	    result = -1;
	    goto FinishSyscall;
	  }

	free (buf);
      }
      break;

    case CB_SYS_pipe :
      {
	int p[2];
	char *target_p = xcalloc (1, cb->target_sizeof_int * 2);

	result = (*cb->pipe) (cb, p);
	if (result != 0)
	  goto ErrorFinish;

	cb_store_target_endian (cb, target_p, cb->target_sizeof_int, p[0]);
	cb_store_target_endian (cb, target_p + cb->target_sizeof_int,
				cb->target_sizeof_int, p[1]);
	if ((*sc->write_mem) (cb, sc, sc->arg1, target_p,
			      cb->target_sizeof_int * 2)
	    != cb->target_sizeof_int * 2)
	  {
	    /* Close the pipe fd:s.  */
	    (*cb->close) (cb, p[0]);
	    (*cb->close) (cb, p[1]);
	    errcode = EFAULT;
	    result = -1;
	  }

	free (target_p);
      }
      break;

    case CB_SYS_getpid:
      /* POSIX says getpid always succeeds.  */
      result = (*cb->getpid) (cb);
      break;

    case CB_SYS_kill:
      /* If killing self, leave it to the caller to process so it can send the
	 signal to the engine.  */
      if (sc->arg1 == (*cb->getpid) (cb))
	{
	  result = -1;
	  errcode = ENOSYS;
	}
      else
	{
	  int signum = cb_target_to_host_signal (cb, sc->arg2);

	  result = (*cb->kill) (cb, sc->arg1, signum);
	  cb->last_errno = errno;
	  goto ErrorFinish;
	}
      break;

    case CB_SYS_time :
      {
	/* FIXME: May wish to change CB_SYS_time to something else.
	   We might also want gettimeofday or times, but if system calls
	   can be built on others, we can keep the number we have to support
	   here down.  */
	time_t t = (*cb->time) (cb);
	result = t;
	/* It is up to target code to process the argument to time().  */
      }
      break;

    case CB_SYS_chdir :
    case CB_SYS_chmod :
    case CB_SYS_utime :
      /* fall through for now */

    default :
      result = -1;
      errcode = ENOSYS;
      break;
    }

 FinishSyscall:
  sc->result = result;
  if (errcode == 0)
    sc->errcode = 0;
  else
    sc->errcode = cb_host_to_target_errno (cb, errcode);
  return CB_RC_OK;

 ErrorFinish:
  sc->result = result;
  sc->errcode = (*cb->get_errno) (cb);
  return CB_RC_OK;
}
