/* Get Dwarf Frame state for target live PID process.
   Copyright (C) 2013, 2014, 2015, 2018 Red Hat, Inc.
   This file is part of elfutils.

   This file is free software; you can redistribute it and/or modify
   it under the terms of either

     * the GNU Lesser General Public License as published by the Free
       Software Foundation; either version 3 of the License, or (at
       your option) any later version

   or

     * 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

   or both in parallel, as here.

   elfutils 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 copies of the GNU General Public License and
   the GNU Lesser General Public License along with this program.  If
   not, see <http://www.gnu.org/licenses/>.  */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include "libelfP.h"
#include "libdwflP.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <unistd.h>

#ifdef __linux__

#include <sys/uio.h>
#include <sys/ptrace.h>
#include <sys/syscall.h>
#include <sys/wait.h>

static bool
linux_proc_pid_is_stopped (pid_t pid)
{
  char buffer[64];
  FILE *procfile;
  bool retval, have_state;

  snprintf (buffer, sizeof (buffer), "/proc/%ld/status", (long) pid);
  procfile = fopen (buffer, "r");
  if (procfile == NULL)
    return false;

  have_state = false;
  while (fgets (buffer, sizeof (buffer), procfile) != NULL)
    if (strncmp (buffer, "State:", 6) == 0)
      {
	have_state = true;
	break;
      }
  retval = (have_state && strstr (buffer, "T (stopped)") != NULL);
  fclose (procfile);
  return retval;
}

bool
internal_function
__libdwfl_ptrace_attach (pid_t tid, bool *tid_was_stoppedp)
{
  if (ptrace (PTRACE_ATTACH, tid, NULL, NULL) != 0)
    {
      __libdwfl_seterrno (DWFL_E_ERRNO);
      return false;
    }
  *tid_was_stoppedp = linux_proc_pid_is_stopped (tid);
  if (*tid_was_stoppedp)
    {
      /* Make sure there is a SIGSTOP signal pending even when the process is
	 already State: T (stopped).  Older kernels might fail to generate
	 a SIGSTOP notification in that case in response to our PTRACE_ATTACH
	 above.  Which would make the waitpid below wait forever.  So emulate
	 it.  Since there can only be one SIGSTOP notification pending this is
	 safe.  See also gdb/linux-nat.c linux_nat_post_attach_wait.  */
      syscall (__NR_tkill, tid, SIGSTOP);
      ptrace (PTRACE_CONT, tid, NULL, NULL);
    }
  for (;;)
    {
      int status;
      if (waitpid (tid, &status, __WALL) != tid || !WIFSTOPPED (status))
	{
	  int saved_errno = errno;
	  ptrace (PTRACE_DETACH, tid, NULL, NULL);
	  errno = saved_errno;
	  __libdwfl_seterrno (DWFL_E_ERRNO);
	  return false;
	}
      if (WSTOPSIG (status) == SIGSTOP)
	break;
      if (ptrace (PTRACE_CONT, tid, NULL,
		  (void *) (uintptr_t) WSTOPSIG (status)) != 0)
	{
	  int saved_errno = errno;
	  ptrace (PTRACE_DETACH, tid, NULL, NULL);
	  errno = saved_errno;
	  __libdwfl_seterrno (DWFL_E_ERRNO);
	  return false;
	}
    }
  return true;
}

#ifdef HAVE_PROCESS_VM_READV
/* Note that the result word size depends on the architecture word size.
   That is sizeof long. */
static bool
read_cached_memory (struct __libdwfl_pid_arg *pid_arg,
		    Dwarf_Addr addr, Dwarf_Word *result)
{
  /* Let the ptrace fallback deal with the corner case of the address
     possibly crossing a page boundery.  */
  if ((addr & ((Dwarf_Addr)__LIBDWFL_REMOTE_MEM_CACHE_SIZE - 1))
      > (Dwarf_Addr)__LIBDWFL_REMOTE_MEM_CACHE_SIZE - sizeof (unsigned long))
    return false;

  struct __libdwfl_remote_mem_cache *mem_cache = pid_arg->mem_cache;
  if (mem_cache == NULL)
    {
      size_t mem_cache_size = sizeof (struct __libdwfl_remote_mem_cache);
      mem_cache = (struct __libdwfl_remote_mem_cache *) malloc (mem_cache_size);
      if (mem_cache == NULL)
	return false;

      mem_cache->addr = 0;
      mem_cache->len = 0;
      pid_arg->mem_cache = mem_cache;
    }

  unsigned char *d;
  if (addr >= mem_cache->addr && addr - mem_cache->addr < mem_cache->len)
    {
      d = &mem_cache->buf[addr - mem_cache->addr];
      if ((((uintptr_t) d) & (sizeof (unsigned long) - 1)) == 0)
	*result = *(unsigned long *) d;
      else
	memcpy (result, d, sizeof (unsigned long));
      return true;
    }

  struct iovec local, remote;
  mem_cache->addr = addr & ~((Dwarf_Addr)__LIBDWFL_REMOTE_MEM_CACHE_SIZE - 1);
  local.iov_base = mem_cache->buf;
  local.iov_len = __LIBDWFL_REMOTE_MEM_CACHE_SIZE;
  remote.iov_base = (void *) (uintptr_t) mem_cache->addr;
  remote.iov_len = __LIBDWFL_REMOTE_MEM_CACHE_SIZE;

  ssize_t res = process_vm_readv (pid_arg->tid_attached,
				  &local, 1, &remote, 1, 0);
  if (res != __LIBDWFL_REMOTE_MEM_CACHE_SIZE)
    {
      mem_cache->len = 0;
      return false;
    }

  mem_cache->len = res;
  d = &mem_cache->buf[addr - mem_cache->addr];
  if ((((uintptr_t) d) & (sizeof (unsigned long) - 1)) == 0)
    *result = *(unsigned long *) d;
  else
    memcpy (result, d, sizeof (unsigned long));
  return true;
}
#endif /* HAVE_PROCESS_VM_READV */

static void
clear_cached_memory (struct __libdwfl_pid_arg *pid_arg)
{
  struct __libdwfl_remote_mem_cache *mem_cache = pid_arg->mem_cache;
  if (mem_cache != NULL)
    mem_cache->len = 0;
}

/* Note that the result word size depends on the architecture word size.
   That is sizeof long. */
static bool
pid_memory_read (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Word *result, void *arg)
{
  struct __libdwfl_pid_arg *pid_arg = arg;
  pid_t tid = pid_arg->tid_attached;
  assert (tid > 0);

#ifdef HAVE_PROCESS_VM_READV
  if (read_cached_memory (pid_arg, addr, result))
    return true;
#endif

  Dwfl_Process *process = dwfl->process;
  if (ebl_get_elfclass (process->ebl) == ELFCLASS64)
    {
#if SIZEOF_LONG == 8
      errno = 0;
      *result = ptrace (PTRACE_PEEKDATA, tid, (void *) (uintptr_t) addr, NULL);
      return errno == 0;
#else /* SIZEOF_LONG != 8 */
      /* This should not happen.  */
      return false;
#endif /* SIZEOF_LONG != 8 */
    }
#if SIZEOF_LONG == 8
  /* We do not care about reads unaliged to 4 bytes boundary.
     But 0x...ffc read of 8 bytes could overrun a page.  */
  bool lowered = (addr & 4) != 0;
  if (lowered)
    addr -= 4;
#endif /* SIZEOF_LONG == 8 */
  errno = 0;
  *result = ptrace (PTRACE_PEEKDATA, tid, (void *) (uintptr_t) addr, NULL);
  if (errno != 0)
    return false;
#if SIZEOF_LONG == 8
# if BYTE_ORDER == BIG_ENDIAN
  if (! lowered)
    *result >>= 32;
# else
  if (lowered)
    *result >>= 32;
# endif
#endif /* SIZEOF_LONG == 8 */
  *result &= 0xffffffff;
  return true;
}

static pid_t
pid_next_thread (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg,
		 void **thread_argp)
{
  struct __libdwfl_pid_arg *pid_arg = dwfl_arg;
  struct dirent *dirent;
  /* Start fresh on first traversal. */
  if (*thread_argp == NULL)
    rewinddir (pid_arg->dir);
  do
    {
      errno = 0;
      dirent = readdir (pid_arg->dir);
      if (dirent == NULL)
	{
	  if (errno != 0)
	    {
	      __libdwfl_seterrno (DWFL_E_ERRNO);
	      return -1;
	    }
	  return 0;
	}
    }
  while (strcmp (dirent->d_name, ".") == 0
	 || strcmp (dirent->d_name, "..") == 0);
  char *end;
  errno = 0;
  long tidl = strtol (dirent->d_name, &end, 10);
  if (errno != 0)
    {
      __libdwfl_seterrno (DWFL_E_ERRNO);
      return -1;
    }
  pid_t tid = tidl;
  if (tidl <= 0 || (end && *end) || tid != tidl)
    {
      __libdwfl_seterrno (DWFL_E_PARSE_PROC);
      return -1;
    }
  *thread_argp = dwfl_arg;
  return tid;
}

/* Just checks that the thread id exists.  */
static bool
pid_getthread (Dwfl *dwfl __attribute__ ((unused)), pid_t tid,
	       void *dwfl_arg, void **thread_argp)
{
  *thread_argp = dwfl_arg;
  if (kill (tid, 0) < 0)
    {
      __libdwfl_seterrno (DWFL_E_ERRNO);
      return false;
    }
  return true;
}

/* Implement the ebl_set_initial_registers_tid setfunc callback.  */

static bool
pid_thread_state_registers_cb (int firstreg, unsigned nregs,
			       const Dwarf_Word *regs, void *arg)
{
  Dwfl_Thread *thread = (Dwfl_Thread *) arg;
  if (firstreg < 0)
    {
      assert (firstreg == -1);
      assert (nregs == 1);
      INTUSE(dwfl_thread_state_register_pc) (thread, *regs);
      return true;
    }
  assert (nregs > 0);
  return INTUSE(dwfl_thread_state_registers) (thread, firstreg, nregs, regs);
}

static bool
pid_set_initial_registers (Dwfl_Thread *thread, void *thread_arg)
{
  struct __libdwfl_pid_arg *pid_arg = thread_arg;
  assert (pid_arg->tid_attached == 0);
  pid_t tid = INTUSE(dwfl_thread_tid) (thread);
  if (! pid_arg->assume_ptrace_stopped
      && ! __libdwfl_ptrace_attach (tid, &pid_arg->tid_was_stopped))
    return false;
  pid_arg->tid_attached = tid;
  Dwfl_Process *process = thread->process;
  Ebl *ebl = process->ebl;
  return ebl_set_initial_registers_tid (ebl, tid,
					pid_thread_state_registers_cb, thread);
}

static void
pid_detach (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg)
{
  struct __libdwfl_pid_arg *pid_arg = dwfl_arg;
  elf_end (pid_arg->elf);
  free (pid_arg->mem_cache);
  close (pid_arg->elf_fd);
  closedir (pid_arg->dir);
  free (pid_arg);
}

void
internal_function
__libdwfl_ptrace_detach (pid_t tid, bool tid_was_stopped)
{
  /* This handling is needed only on older Linux kernels such as
     2.6.32-358.23.2.el6.ppc64.  Later kernels such as
     3.11.7-200.fc19.x86_64 remember the T (stopped) state
     themselves and no longer need to pass SIGSTOP during
     PTRACE_DETACH.  */
  ptrace (PTRACE_DETACH, tid, NULL,
	  (void *) (intptr_t) (tid_was_stopped ? SIGSTOP : 0));
}

static void
pid_thread_detach (Dwfl_Thread *thread, void *thread_arg)
{
  struct __libdwfl_pid_arg *pid_arg = thread_arg;
  pid_t tid = INTUSE(dwfl_thread_tid) (thread);
  assert (pid_arg->tid_attached == tid);
  pid_arg->tid_attached = 0;
  clear_cached_memory (pid_arg);
  if (! pid_arg->assume_ptrace_stopped)
    __libdwfl_ptrace_detach (tid, pid_arg->tid_was_stopped);
}

static const Dwfl_Thread_Callbacks pid_thread_callbacks =
{
  pid_next_thread,
  pid_getthread,
  pid_memory_read,
  pid_set_initial_registers,
  pid_detach,
  pid_thread_detach,
};

int
dwfl_linux_proc_attach (Dwfl *dwfl, pid_t pid, bool assume_ptrace_stopped)
{
  char buffer[36];
  FILE *procfile;
  int err = 0; /* The errno to return and set for dwfl->attcherr.  */

  /* Make sure to report the actual PID (thread group leader) to
     dwfl_attach_state.  */
  snprintf (buffer, sizeof (buffer), "/proc/%ld/status", (long) pid);
  procfile = fopen (buffer, "r");
  if (procfile == NULL)
    {
      err = errno;
    fail:
      if (dwfl->process == NULL && dwfl->attacherr == DWFL_E_NOERROR)
	{
	  errno = err;
	  dwfl->attacherr = __libdwfl_canon_error (DWFL_E_ERRNO);
	}
      return err;
    }

  char *line = NULL;
  size_t linelen = 0;
  while (getline (&line, &linelen, procfile) >= 0)
    if (strncmp (line, "Tgid:", 5) == 0)
      {
	errno = 0;
	char *endptr;
	long val = strtol (&line[5], &endptr, 10);
	if ((errno == ERANGE && val == LONG_MAX)
	    || *endptr != '\n' || val < 0 || val != (pid_t) val)
	  pid = 0;
	else
	  pid = (pid_t) val;
	break;
      }
  free (line);
  fclose (procfile);

  if (pid == 0)
    {
      err = ESRCH;
      goto fail;
    }

  char name[64];
  int i = snprintf (name, sizeof (name), "/proc/%ld/task", (long) pid);
  if (i <= 0 || i >= (ssize_t) sizeof (name) - 1)
    {
      errno = -ENOMEM;
      goto fail;
    }
  DIR *dir = opendir (name);
  if (dir == NULL)
    {
      err = errno;
      goto fail;
    }

  Elf *elf;
  i = snprintf (name, sizeof (name), "/proc/%ld/exe", (long) pid);
  assert (i > 0 && i < (ssize_t) sizeof (name) - 1);
  int elf_fd = open (name, O_RDONLY);
  if (elf_fd >= 0)
    {
      elf = elf_begin (elf_fd, ELF_C_READ_MMAP, NULL);
      if (elf == NULL)
	{
	  /* Just ignore, dwfl_attach_state will fall back to trying
	     to associate the Dwfl with one of the existing DWfl_Module
	     ELF images (to know the machine/class backend to use).  */
	  close (elf_fd);
	  elf_fd = -1;
	}
    }
  else
    elf = NULL;
  struct __libdwfl_pid_arg *pid_arg = malloc (sizeof *pid_arg);
  if (pid_arg == NULL)
    {
      elf_end (elf);
      close (elf_fd);
      closedir (dir);
      err = ENOMEM;
      goto fail;
    }
  pid_arg->dir = dir;
  pid_arg->elf = elf;
  pid_arg->elf_fd = elf_fd;
  pid_arg->mem_cache = NULL;
  pid_arg->tid_attached = 0;
  pid_arg->assume_ptrace_stopped = assume_ptrace_stopped;
  if (! INTUSE(dwfl_attach_state) (dwfl, elf, pid, &pid_thread_callbacks,
				   pid_arg))
    {
      elf_end (elf);
      close (elf_fd);
      closedir (dir);
      free (pid_arg);
      return -1;
    }
  return 0;
}
INTDEF (dwfl_linux_proc_attach)

struct __libdwfl_pid_arg *
internal_function
__libdwfl_get_pid_arg (Dwfl *dwfl)
{
  if (dwfl != NULL && dwfl->process != NULL
      && dwfl->process->callbacks == &pid_thread_callbacks)
    return (struct __libdwfl_pid_arg *) dwfl->process->callbacks_arg;

  return NULL;
}

#else	/* __linux__ */

bool
internal_function
__libdwfl_ptrace_attach (pid_t tid __attribute__ ((unused)),
			 bool *tid_was_stoppedp __attribute__ ((unused)))
{
  errno = ENOSYS;
  __libdwfl_seterrno (DWFL_E_ERRNO);
  return false;
}

void
internal_function
__libdwfl_ptrace_detach (pid_t tid __attribute__ ((unused)),
			 bool tid_was_stopped __attribute__ ((unused)))
{
}

int
dwfl_linux_proc_attach (Dwfl *dwfl __attribute__ ((unused)),
			pid_t pid __attribute__ ((unused)),
			bool assume_ptrace_stopped __attribute__ ((unused)))
{
  return ENOSYS;
}
INTDEF (dwfl_linux_proc_attach)

struct __libdwfl_pid_arg *
internal_function
__libdwfl_get_pid_arg (Dwfl *dwfl __attribute__ ((unused)))
{
  return NULL;
}

#endif /* ! __linux __ */

