/* Virtual tail call frames unwinder for GDB.

   Copyright (C) 2010-2012 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);
}
