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

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

#include "libdwflP.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
free_states (Dwfl_Frame *state)
{
  while (state)
    {
      Dwfl_Frame *next = state->unwound;
      free(state);
      state = next;
    }
}

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)
	return -1;
      if (thread.tid == 0)
	{
	  __libdwfl_seterrno (DWFL_E_NOERROR);
	  return 0;
	}
      int err = callback (&thread, arg);
      if (err != DWARF_CB_OK)
	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))
	{
	  thread.tid = tid;
	  return callback (&thread, arg);
	}

      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)
{
  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))
    {
      free_states (thread->unwound);
      thread->unwound = NULL;
      return -1;
    }
  Dwfl_Frame *state = thread->unwound;
  thread->unwound = NULL;
  if (! state_fetch_pc (state))
    {
      if (process->callbacks->thread_detach)
	process->callbacks->thread_detach (thread, thread->callbacks_arg);
      free_states (state);
      return -1;
    }
  do
    {
      int err = callback (state, arg);
      if (err != DWARF_CB_OK)
	{
	  if (process->callbacks->thread_detach)
	    process->callbacks->thread_detach (thread, thread->callbacks_arg);
	  free_states (state);
	  return err;
	}
      __libdwfl_frame_unwind (state);
      Dwfl_Frame *next = state->unwound;
      /* The old frame is no longer needed.  */
      free (state);
      state = next;
    }
  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)
    {
      free_states (state);
      __libdwfl_seterrno (err);
      return -1;
    }
  assert (state->pc_state == DWFL_FRAME_STATE_PC_UNDEFINED);
  free_states (state);
  return 0;
}
INTDEF(dwfl_thread_getframes)
