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

#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 (startswith (mod->name, "[vdso: ")
	      || 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)
