/* Virtual tail call frames unwinder for GDB.

   Copyright (C) 2010, 2011 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

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

#include "defs.h"
#include "gdb_assert.h"
#include "frame.h"
#include "dwarf2-frame-tailcall.h"
#include "dwarf2loc.h"
#include "frame-unwind.h"
#include "block.h"
#include "hashtab.h"
#include "exceptions.h"
#include "gdbtypes.h"
#include "regcache.h"
#include "value.h"
#include "dwarf2-frame.h"

/* Contains struct tailcall_cache indexed by next_bottom_frame.  */
static htab_t cache_htab;

/* Associate structure of the unwinder to call_site_chain.  Lifetime of this
   structure is maintained by REFC decremented by dealloc_cache, all of them
   get deleted during reinit_frame_cache.  */
struct tailcall_cache
{
  /* It must be the first one of this struct.  It is the furthest callee.  */
  struct frame_info *next_bottom_frame;

  /* Reference count.  The whole chain of virtual tail call frames shares one
     tailcall_cache.  */
  int refc;

  /* Associated found virtual taill call frames chain, it is never NULL.  */
  struct call_site_chain *chain;

  /* Cached pretended_chain_levels result.  */
  int chain_levels;

  /* Unwound PC from the top (caller) frame, as it is not contained
     in CHAIN.  */
  CORE_ADDR prev_pc;

  /* Compensate SP in caller frames appropriately.  prev_sp and
     entry_cfa_sp_offset are valid only if PREV_SP_P.  PREV_SP is SP at the top
     (caller) frame.  ENTRY_CFA_SP_OFFSET is shift of SP in tail call frames
     against next_bottom_frame SP.  */
  unsigned prev_sp_p : 1;
  CORE_ADDR prev_sp;
  LONGEST entry_cfa_sp_offset;
};

/* hash_f for htab_create_alloc of cache_htab.  */

static hashval_t
cache_hash (const void *arg)
{
  const struct tailcall_cache *cache = arg;

  return htab_hash_pointer (cache->next_bottom_frame);
}

/* eq_f for htab_create_alloc of cache_htab.  */

static int
cache_eq (const void *arg1, const void *arg2)
{
  const struct tailcall_cache *cache1 = arg1;
  const struct tailcall_cache *cache2 = arg2;

  return cache1->next_bottom_frame == cache2->next_bottom_frame;
}

/* Create new tailcall_cache for NEXT_BOTTOM_FRAME, NEXT_BOTTOM_FRAME must not
   yet have been indexed by cache_htab.  Caller holds one reference of the new
   tailcall_cache.  */

static struct tailcall_cache *
cache_new_ref1 (struct frame_info *next_bottom_frame)
{
  struct tailcall_cache *cache;
  void **slot;

  cache = xzalloc (sizeof (*cache));

  cache->next_bottom_frame = next_bottom_frame;
  cache->refc = 1;

  slot = htab_find_slot (cache_htab, cache, INSERT);
  gdb_assert (*slot == NULL);
  *slot = cache;

  return cache;
}

/* Create new reference to CACHE.  */

static void
cache_ref (struct tailcall_cache *cache)
{
  gdb_assert (cache->refc > 0);

  cache->refc++;
}

/* Drop reference to CACHE, possibly fully freeing it and unregistering it from
   cache_htab.  */

static void
cache_unref (struct tailcall_cache *cache)
{
  gdb_assert (cache->refc > 0);

  if (!--cache->refc)
    {
      gdb_assert (htab_find_slot (cache_htab, cache, NO_INSERT) != NULL);
      htab_remove_elt (cache_htab, cache);

      xfree (cache->chain);
      xfree (cache);
    }
}

/* Return 1 if FI is a non-bottom (not the callee) tail call frame.  Otherwise
   return 0.  */

static int
frame_is_tailcall (struct frame_info *fi)
{
  return frame_unwinder_is (fi, &dwarf2_tailcall_frame_unwind);
}

/* Try to find tailcall_cache in cache_htab if FI is a part of its virtual tail
   call chain.  Otherwise return NULL.  No new reference is created.  */

static struct tailcall_cache *
cache_find (struct frame_info *fi)
{
  struct tailcall_cache *cache;
  void **slot;

  while (frame_is_tailcall (fi))
    {
      fi = get_next_frame (fi);
      gdb_assert (fi != NULL);
    }

  slot = htab_find_slot (cache_htab, &fi, NO_INSERT);
  if (slot == NULL)
    return NULL;

  cache = *slot;
  gdb_assert (cache != NULL);
  return cache;
}

/* Number of virtual frames between THIS_FRAME and CACHE->NEXT_BOTTOM_FRAME.
   If THIS_FRAME is CACHE-> NEXT_BOTTOM_FRAME return -1.  */

static int
existing_next_levels (struct frame_info *this_frame,
		      struct tailcall_cache *cache)
{
  int retval = (frame_relative_level (this_frame)
		- frame_relative_level (cache->next_bottom_frame) - 1);

  gdb_assert (retval >= -1);

  return retval;
}

/* The number of virtual tail call frames in CHAIN.  With no virtual tail call
   frames the function would return 0 (but CHAIN does not exist in such
   case).  */

static int
pretended_chain_levels (struct call_site_chain *chain)
{
  int chain_levels;

  gdb_assert (chain != NULL);

  if (chain->callers == chain->length && chain->callees == chain->length)
    return chain->length;

  chain_levels = chain->callers + chain->callees;
  gdb_assert (chain_levels < chain->length);

  return chain_levels;
}

/* Implementation of frame_this_id_ftype.  THIS_CACHE must be already
   initialized with tailcall_cache, THIS_FRAME must be a part of THIS_CACHE.

   Specific virtual tail call frames are tracked by INLINE_DEPTH.  */

static void
tailcall_frame_this_id (struct frame_info *this_frame, void **this_cache,
			struct frame_id *this_id)
{
  struct tailcall_cache *cache = *this_cache;
  struct frame_info *next_frame;

  /* Tail call does not make sense for a sentinel frame.  */
  next_frame = get_next_frame (this_frame);
  gdb_assert (next_frame != NULL);

  *this_id = get_frame_id (next_frame);
  (*this_id).code_addr = get_frame_pc (this_frame);
  (*this_id).code_addr_p = 1;
  (*this_id).inline_depth = (cache->chain_levels
			     - existing_next_levels (this_frame, cache));
  gdb_assert ((*this_id).inline_depth > 0);
}

/* Find PC to be unwound from THIS_FRAME.  THIS_FRAME must be a part of
   CACHE.  */

static CORE_ADDR
pretend_pc (struct frame_info *this_frame, struct tailcall_cache *cache)
{
  int next_levels = existing_next_levels (this_frame, cache);
  struct call_site_chain *chain = cache->chain;
  int caller_no;

  gdb_assert (chain != NULL);

  next_levels++;
  gdb_assert (next_levels >= 0);

  if (next_levels < chain->callees)
    return chain->call_site[chain->length - next_levels - 1]->pc;
  next_levels -= chain->callees;

  /* Otherwise CHAIN->CALLEES are already covered by CHAIN->CALLERS.  */
  if (chain->callees != chain->length)
    {
      if (next_levels < chain->callers)
	return chain->call_site[chain->callers - next_levels - 1]->pc;
      next_levels -= chain->callers;
    }

  gdb_assert (next_levels == 0);
  return cache->prev_pc;
}

/* Implementation of frame_prev_register_ftype.  If no specific register
   override is supplied NULL is returned (this is incompatible with
   frame_prev_register_ftype semantics).  next_bottom_frame and tail call
   frames unwind the NULL case differently.  */

struct value *
dwarf2_tailcall_prev_register_first (struct frame_info *this_frame,
				     void **tailcall_cachep, int regnum)
{
  struct gdbarch *this_gdbarch = get_frame_arch (this_frame);
  struct tailcall_cache *cache = *tailcall_cachep;
  CORE_ADDR addr;

  if (regnum == gdbarch_pc_regnum (this_gdbarch))
    addr = pretend_pc (this_frame, cache);
  else if (cache->prev_sp_p && regnum == gdbarch_sp_regnum (this_gdbarch))
    {
      int next_levels = existing_next_levels (this_frame, cache);

      if (next_levels == cache->chain_levels - 1)
	addr = cache->prev_sp;
      else
	addr = dwarf2_frame_cfa (this_frame) - cache->entry_cfa_sp_offset;
    }
  else
    return NULL;

  return frame_unwind_got_address (this_frame, regnum, addr);
}

/* Implementation of frame_prev_register_ftype for tail call frames.  Register
   set of virtual tail call frames is assumed to be the one of the top (caller)
   frame - assume unchanged register value for NULL from
   dwarf2_tailcall_prev_register_first.  */

static struct value *
tailcall_frame_prev_register (struct frame_info *this_frame,
			       void **this_cache, int regnum)
{
  struct tailcall_cache *cache = *this_cache;
  struct value *val;

  gdb_assert (this_frame != cache->next_bottom_frame);

  val = dwarf2_tailcall_prev_register_first (this_frame, this_cache, regnum);
  if (val)
    return val;

  return frame_unwind_got_register (this_frame, regnum, regnum);
}

/* Implementation of frame_sniffer_ftype.  It will never find a new chain, use
   dwarf2_tailcall_sniffer_first for the bottom (callee) frame.  It will find
   all the predecessing virtual tail call frames, it will return false when
   there exist no more tail call frames in this chain.  */

static int
tailcall_frame_sniffer (const struct frame_unwind *self,
			 struct frame_info *this_frame, void **this_cache)
{
  struct frame_info *next_frame;
  int next_levels;
  struct tailcall_cache *cache;

  /* Inner tail call element does not make sense for a sentinel frame.  */
  next_frame = get_next_frame (this_frame);
  if (next_frame == NULL)
    return 0;

  cache = cache_find (next_frame);
  if (cache == NULL)
    return 0;

  cache_ref (cache);

  next_levels = existing_next_levels (this_frame, cache);

  /* NEXT_LEVELS is -1 only in dwarf2_tailcall_sniffer_first.  */
  gdb_assert (next_levels >= 0);
  gdb_assert (next_levels <= cache->chain_levels);

  if (next_levels == cache->chain_levels)
    {
      cache_unref (cache);
      return 0;
    }

  *this_cache = cache;
  return 1;
}

/* The initial "sniffer" whether THIS_FRAME is a bottom (callee) frame of a new
   chain to create.  Keep TAILCALL_CACHEP NULL if it did not find any chain,
   initialize it otherwise.  No tail call chain is created if there are no
   unambiguous virtual tail call frames to report.
   
   ENTRY_CFA_SP_OFFSETP is NULL if no special SP handling is possible,
   otherwise *ENTRY_CFA_SP_OFFSETP is the number of bytes to subtract from tail
   call frames frame base to get the SP value there - to simulate return
   address pushed on the stack.  */

void
dwarf2_tailcall_sniffer_first (struct frame_info *this_frame,
			       void **tailcall_cachep,
			       const LONGEST *entry_cfa_sp_offsetp)
{
  CORE_ADDR prev_pc = 0, prev_sp = 0;	/* GCC warning.  */
  int prev_sp_p = 0;
  CORE_ADDR this_pc, pc;
  struct gdbarch *prev_gdbarch;
  struct call_site_chain *chain = NULL;
  struct frame_info *fi;
  struct tailcall_cache *cache;
  volatile struct gdb_exception except;

  gdb_assert (*tailcall_cachep == NULL);

  this_pc = get_frame_pc (this_frame);

  /* Catch any unwinding errors.  */
  TRY_CATCH (except, RETURN_MASK_ERROR)
    {
      int sp_regnum;

      prev_gdbarch = frame_unwind_arch (this_frame);

      /* Simulate frame_unwind_pc without setting this_frame->prev_pc.p.  */
      prev_pc = gdbarch_unwind_pc (prev_gdbarch, this_frame);

      /* call_site_find_chain can throw an exception.  */
      chain = call_site_find_chain (prev_gdbarch, prev_pc, this_pc);

      if (entry_cfa_sp_offsetp == NULL)
	break;
      sp_regnum = gdbarch_sp_regnum (prev_gdbarch);
      if (sp_regnum == -1)
	break;
      prev_sp = frame_unwind_register_unsigned (this_frame, sp_regnum);
      prev_sp_p = 1;
    }
  if (except.reason < 0)
    {
      if (entry_values_debug)
	exception_print (gdb_stdout, except);
      return;
    }

  /* Ambiguous unwind or unambiguous unwind verified as matching.  */
  if (chain == NULL || chain->length == 0)
    {
      xfree (chain);
      return;
    }

  cache = cache_new_ref1 (this_frame);
  *tailcall_cachep = cache;
  cache->chain = chain;
  cache->prev_pc = prev_pc;
  cache->chain_levels = pretended_chain_levels (chain);
  cache->prev_sp_p = prev_sp_p;
  if (cache->prev_sp_p)
    {
      cache->prev_sp = prev_sp;
      cache->entry_cfa_sp_offset = *entry_cfa_sp_offsetp;
    }
  gdb_assert (cache->chain_levels > 0);
}

/* Implementation of frame_dealloc_cache_ftype.  It can be called even for the
   bottom chain frame from dwarf2_frame_dealloc_cache which is not a real
   TAILCALL_FRAME.  */

static void
tailcall_frame_dealloc_cache (struct frame_info *self, void *this_cache)
{
  struct tailcall_cache *cache = this_cache;

  cache_unref (cache);
}

/* Implementation of frame_prev_arch_ftype.  We assume all the virtual tail
   call frames have gdbarch of the bottom (callee) frame.  */

static struct gdbarch *
tailcall_frame_prev_arch (struct frame_info *this_frame,
			  void **this_prologue_cache)
{
  struct tailcall_cache *cache = *this_prologue_cache;

  return get_frame_arch (cache->next_bottom_frame);
}

/* Virtual tail call frame unwinder if dwarf2_tailcall_sniffer_first finds
   a chain to create.  */

const struct frame_unwind dwarf2_tailcall_frame_unwind =
{
  TAILCALL_FRAME,
  default_frame_unwind_stop_reason,
  tailcall_frame_this_id,
  tailcall_frame_prev_register,
  NULL,
  tailcall_frame_sniffer,
  tailcall_frame_dealloc_cache,
  tailcall_frame_prev_arch
};

/* Provide a prototype to silence -Wmissing-prototypes.  */
extern initialize_file_ftype _initialize_tailcall_frame;

void
_initialize_tailcall_frame (void)
{
  cache_htab = htab_create_alloc (50, cache_hash, cache_eq, NULL, xcalloc,
				  xfree);
}
