/* Get Dwarf Frame state for target PID or core file.
   Copyright (C) 2013, 2014 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/>.  */

#include "libdwflP.h"
#include <sys/ptrace.h>
#include <unistd.h>

/* Set STATE->pc_set from STATE->regs according to the backend.  Return true on
   success, false on error.  */
static bool
state_fetch_pc (Dwfl_Frame *state)
{
  switch (state->pc_state)
    {
    case DWFL_FRAME_STATE_PC_SET:
      return true;
    case DWFL_FRAME_STATE_PC_UNDEFINED:
      abort ();
    case DWFL_FRAME_STATE_ERROR:
      {
	Ebl *ebl = state->thread->process->ebl;
	Dwarf_CIE abi_info;
	if (ebl_abi_cfi (ebl, &abi_info) != 0)
	  {
	    __libdwfl_seterrno (DWFL_E_LIBEBL);
	    return false;
	  }
	unsigned ra = abi_info.return_address_register;
	/* dwarf_frame_state_reg_is_set is not applied here.  */
	if (ra >= ebl_frame_nregs (ebl))
	  {
	    __libdwfl_seterrno (DWFL_E_LIBEBL_BAD);
	    return false;
	  }
	state->pc = state->regs[ra] + ebl_ra_offset (ebl);
	state->pc_state = DWFL_FRAME_STATE_PC_SET;
      }
      return true;
    }
  abort ();
}

/* Do not call it on your own, to be used by thread_* functions only.  */

static void
state_free (Dwfl_Frame *state)
{
  Dwfl_Thread *thread = state->thread;
  assert (thread->unwound == state);
  thread->unwound = state->unwound;
  free (state);
}

static void
thread_free_all_states (Dwfl_Thread *thread)
{
  while (thread->unwound)
    state_free (thread->unwound);
}

static Dwfl_Frame *
state_alloc (Dwfl_Thread *thread)
{
  assert (thread->unwound == NULL);
  Ebl *ebl = thread->process->ebl;
  size_t nregs = ebl_frame_nregs (ebl);
  if (nregs == 0)
    return NULL;
  assert (nregs < sizeof (((Dwfl_Frame *) NULL)->regs_set) * 8);
  Dwfl_Frame *state = malloc (sizeof (*state) + sizeof (*state->regs) * nregs);
  if (state == NULL)
    return NULL;
  state->thread = thread;
  state->signal_frame = false;
  state->initial_frame = true;
  state->pc_state = DWFL_FRAME_STATE_ERROR;
  memset (state->regs_set, 0, sizeof (state->regs_set));
  thread->unwound = state;
  state->unwound = NULL;
  return state;
}

void
internal_function
__libdwfl_process_free (Dwfl_Process *process)
{
  Dwfl *dwfl = process->dwfl;
  if (process->callbacks->detach != NULL)
    process->callbacks->detach (dwfl, process->callbacks_arg);
  assert (dwfl->process == process);
  dwfl->process = NULL;
  if (process->ebl_close)
    ebl_closebackend (process->ebl);
  free (process);
  dwfl->attacherr = DWFL_E_NOERROR;
}

/* Allocate new Dwfl_Process for DWFL.  */
static void
process_alloc (Dwfl *dwfl)
{
  Dwfl_Process *process = malloc (sizeof (*process));
  if (process == NULL)
    return;
  process->dwfl = dwfl;
  dwfl->process = process;
}

bool
dwfl_attach_state (Dwfl *dwfl, Elf *elf, pid_t pid,
		   const Dwfl_Thread_Callbacks *thread_callbacks, void *arg)
{
  if (dwfl->process != NULL)
    {
      __libdwfl_seterrno (DWFL_E_ATTACH_STATE_CONFLICT);
      return false;
    }

  /* Reset any previous error, we are just going to try again.  */
  dwfl->attacherr = DWFL_E_NOERROR;
  /* thread_callbacks is declared NN */
  if (thread_callbacks->next_thread == NULL
      || thread_callbacks->set_initial_registers == NULL)
    {
      dwfl->attacherr = DWFL_E_INVALID_ARGUMENT;
    fail:
      dwfl->attacherr = __libdwfl_canon_error (dwfl->attacherr);
      __libdwfl_seterrno (dwfl->attacherr);
      return false;
    }

  Ebl *ebl;
  bool ebl_close;
  if (elf != NULL)
    {
      ebl = ebl_openbackend (elf);
      ebl_close = true;
    }
  else
    {
      ebl = NULL;
      for (Dwfl_Module *mod = dwfl->modulelist; mod != NULL; mod = mod->next)
	{
	  /* Reading of the vDSO or (deleted) modules may fail as
	     /proc/PID/mem is unreadable without PTRACE_ATTACH and
	     we may not be PTRACE_ATTACH-ed now.  MOD would not be
	     re-read later to unwind it when we are already
	     PTRACE_ATTACH-ed to PID.  This happens when this function
	     is called from dwfl_linux_proc_attach with elf == NULL.
	     __libdwfl_module_getebl will call __libdwfl_getelf which
	     will call the find_elf callback.  */
	  if (strncmp (mod->name, "[vdso: ", 7) == 0
	      || strcmp (strrchr (mod->name, ' ') ?: "",
			 " (deleted)") == 0)
	    continue;
	  Dwfl_Error error = __libdwfl_module_getebl (mod);
	  if (error != DWFL_E_NOERROR)
	    continue;
	  ebl = mod->ebl;
	  break;
	}
      ebl_close = false;
    }
  if (ebl == NULL)
    {
      /* Not identified EBL from any of the modules.  */
      dwfl->attacherr = DWFL_E_PROCESS_NO_ARCH;
      goto fail;
    }
  process_alloc (dwfl);
  Dwfl_Process *process = dwfl->process;
  if (process == NULL)
    {
      if (ebl_close)
	ebl_closebackend (ebl);
      dwfl->attacherr = DWFL_E_NOMEM;
      goto fail;
    }
  process->ebl = ebl;
  process->ebl_close = ebl_close;
  process->pid = pid;
  process->callbacks = thread_callbacks;
  process->callbacks_arg = arg;
  return true;
}
INTDEF(dwfl_attach_state)

pid_t
dwfl_pid (Dwfl *dwfl)
{
  if (dwfl->attacherr != DWFL_E_NOERROR)
    {
      __libdwfl_seterrno (dwfl->attacherr);
      return -1;
    }

  if (dwfl->process == NULL)
    {
      __libdwfl_seterrno (DWFL_E_NO_ATTACH_STATE);
      return -1;
    }
  return dwfl->process->pid;
}
INTDEF(dwfl_pid)

Dwfl *
dwfl_thread_dwfl (Dwfl_Thread *thread)
{
  return thread->process->dwfl;
}
INTDEF(dwfl_thread_dwfl)

pid_t
dwfl_thread_tid (Dwfl_Thread *thread)
{
  return thread->tid;
}
INTDEF(dwfl_thread_tid)

Dwfl_Thread *
dwfl_frame_thread (Dwfl_Frame *state)
{
  return state->thread;
}
INTDEF(dwfl_frame_thread)

int
dwfl_getthreads (Dwfl *dwfl, int (*callback) (Dwfl_Thread *thread, void *arg),
		 void *arg)
{
  if (dwfl->attacherr != DWFL_E_NOERROR)
    {
      __libdwfl_seterrno (dwfl->attacherr);
      return -1;
    }

  Dwfl_Process *process = dwfl->process;
  if (process == NULL)
    {
      __libdwfl_seterrno (DWFL_E_NO_ATTACH_STATE);
      return -1;
    }

  Dwfl_Thread thread;
  thread.process = process;
  thread.unwound = NULL;
  thread.callbacks_arg = NULL;
  for (;;)
    {
      thread.tid = process->callbacks->next_thread (dwfl,
						    process->callbacks_arg,
						    &thread.callbacks_arg);
      if (thread.tid < 0)
	{
	  Dwfl_Error saved_errno = dwfl_errno ();
	  thread_free_all_states (&thread);
	  __libdwfl_seterrno (saved_errno);
	  return -1;
	}
      if (thread.tid == 0)
	{
	  thread_free_all_states (&thread);
	  __libdwfl_seterrno (DWFL_E_NOERROR);
	  return 0;
	}
      int err = callback (&thread, arg);
      if (err != DWARF_CB_OK)
	{
	  thread_free_all_states (&thread);
	  return err;
	}
      assert (thread.unwound == NULL);
    }
  /* NOTREACHED */
}
INTDEF(dwfl_getthreads)

struct one_arg
{
  pid_t tid;
  bool seen;
  int (*callback) (Dwfl_Thread *thread, void *arg);
  void *arg;
  int ret;
};

static int
get_one_thread_cb (Dwfl_Thread *thread, void *arg)
{
  struct one_arg *oa = (struct one_arg *) arg;
  if (! oa->seen && INTUSE(dwfl_thread_tid) (thread) == oa->tid)
    {
      oa->seen = true;
      oa->ret = oa->callback (thread, oa->arg);
      return DWARF_CB_ABORT;
    }

  return DWARF_CB_OK;
}

/* Note not currently exported, will be when there are more Dwfl_Thread
   properties to query.  Use dwfl_getthread_frames for now directly.  */
static int
getthread (Dwfl *dwfl, pid_t tid,
	   int (*callback) (Dwfl_Thread *thread, void *arg),
	   void *arg)
{
  if (dwfl->attacherr != DWFL_E_NOERROR)
    {
      __libdwfl_seterrno (dwfl->attacherr);
      return -1;
    }

  Dwfl_Process *process = dwfl->process;
  if (process == NULL)
    {
      __libdwfl_seterrno (DWFL_E_NO_ATTACH_STATE);
      return -1;
    }

  if (process->callbacks->get_thread != NULL)
    {
      Dwfl_Thread thread;
      thread.process = process;
      thread.unwound = NULL;
      thread.callbacks_arg = NULL;

      if (process->callbacks->get_thread (dwfl, tid, process->callbacks_arg,
					  &thread.callbacks_arg))
	{
	  int err;
	  thread.tid = tid;
	  err = callback (&thread, arg);
	  thread_free_all_states (&thread);
	  return err;
	}

      return -1;
    }

   struct one_arg oa = { .tid = tid, .callback = callback,
			 .arg = arg, .seen = false };
   int err = INTUSE(dwfl_getthreads) (dwfl, get_one_thread_cb, &oa);

   if (err == DWARF_CB_ABORT && oa.seen)
     return oa.ret;

   if (err == DWARF_CB_OK && ! oa.seen)
     {
	errno = ESRCH;
	__libdwfl_seterrno (DWFL_E_ERRNO);
	return -1;
     }

   return err;
}

struct one_thread
{
  int (*callback) (Dwfl_Frame *frame, void *arg);
  void *arg;
};

static int
get_one_thread_frames_cb (Dwfl_Thread *thread, void *arg)
{
  struct one_thread *ot = (struct one_thread *) arg;
  return INTUSE(dwfl_thread_getframes) (thread, ot->callback, ot->arg);
}

int
dwfl_getthread_frames (Dwfl *dwfl, pid_t tid,
		       int (*callback) (Dwfl_Frame *frame, void *arg),
		       void *arg)
{
  struct one_thread ot = { .callback = callback, .arg = arg };
  return getthread (dwfl, tid, get_one_thread_frames_cb, &ot);
}
INTDEF(dwfl_getthread_frames)

int
dwfl_thread_getframes (Dwfl_Thread *thread,
		       int (*callback) (Dwfl_Frame *state, void *arg),
		       void *arg)
{
  if (thread->unwound != NULL)
    {
      /* We had to be called from inside CALLBACK.  */
      __libdwfl_seterrno (DWFL_E_ATTACH_STATE_CONFLICT);
      return -1;
    }
  Ebl *ebl = thread->process->ebl;
  if (ebl_frame_nregs (ebl) == 0)
    {
      __libdwfl_seterrno (DWFL_E_NO_UNWIND);
      return -1;
    }
  if (state_alloc (thread) == NULL)
    {
      __libdwfl_seterrno (DWFL_E_NOMEM);
      return -1;
    }
  Dwfl_Process *process = thread->process;
  if (! process->callbacks->set_initial_registers (thread,
						   thread->callbacks_arg))
    {
      thread_free_all_states (thread);
      return -1;
    }
  if (! state_fetch_pc (thread->unwound))
    {
      if (process->callbacks->thread_detach)
	process->callbacks->thread_detach (thread, thread->callbacks_arg);
      thread_free_all_states (thread);
      return -1;
    }

  Dwfl_Frame *state;
  do
    {
      state = thread->unwound;
      int err = callback (state, arg);
      if (err != DWARF_CB_OK)
	{
	  if (process->callbacks->thread_detach)
	    process->callbacks->thread_detach (thread, thread->callbacks_arg);
	  thread_free_all_states (thread);
	  return err;
	}
      __libdwfl_frame_unwind (state);
      /* The old frame is no longer needed.  */
      state_free (thread->unwound);
      state = thread->unwound;
    }
  while (state && state->pc_state == DWFL_FRAME_STATE_PC_SET);

  Dwfl_Error err = dwfl_errno ();
  if (process->callbacks->thread_detach)
    process->callbacks->thread_detach (thread, thread->callbacks_arg);
  if (state == NULL || state->pc_state == DWFL_FRAME_STATE_ERROR)
    {
      thread_free_all_states (thread);
      __libdwfl_seterrno (err);
      return -1;
    }
  assert (state->pc_state == DWFL_FRAME_STATE_PC_UNDEFINED);
  thread_free_all_states (thread);
  return 0;
}
INTDEF(dwfl_thread_getframes)
