/* 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];
	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;
  if (thread_callbacks == NULL || 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)
