/* Signal trampoline unwinder, for GDB the GNU Debugger.

   Copyright (C) 2004-2023 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 "tramp-frame.h"
#include "frame-unwind.h"
#include "gdbcore.h"
#include "symtab.h"
#include "objfiles.h"
#include "target.h"
#include "trad-frame.h"
#include "frame-base.h"

struct frame_data
{
  const struct tramp_frame *tramp_frame;
};

struct tramp_frame_cache
{
  CORE_ADDR func;
  const struct tramp_frame *tramp_frame;
  struct trad_frame_cache *trad_cache;
};

static struct trad_frame_cache *
tramp_frame_cache (frame_info_ptr this_frame,
		   void **this_cache)
{
  struct tramp_frame_cache *tramp_cache
    = (struct tramp_frame_cache *) *this_cache;

  if (tramp_cache->trad_cache == NULL)
    {
      tramp_cache->trad_cache = trad_frame_cache_zalloc (this_frame);
      tramp_cache->tramp_frame->init (tramp_cache->tramp_frame,
				      this_frame,
				      tramp_cache->trad_cache,
				      tramp_cache->func);
    }
  return tramp_cache->trad_cache;
}

static void
tramp_frame_this_id (frame_info_ptr this_frame,
		     void **this_cache,
		     struct frame_id *this_id)
{
  struct trad_frame_cache *trad_cache
    = tramp_frame_cache (this_frame, this_cache);

  trad_frame_get_id (trad_cache, this_id);
}

static struct value *
tramp_frame_prev_register (frame_info_ptr this_frame,
			   void **this_cache,
			   int prev_regnum)
{
  struct trad_frame_cache *trad_cache
    = tramp_frame_cache (this_frame, this_cache);

  return trad_frame_get_register (trad_cache, this_frame, prev_regnum);
}

static CORE_ADDR
tramp_frame_start (const struct tramp_frame *tramp,
		   frame_info_ptr this_frame, CORE_ADDR pc)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  int ti;

  /* Check if we can use this trampoline.  */
  if (tramp->validate && !tramp->validate (tramp, this_frame, &pc))
    return 0;

  /* Search through the trampoline for one that matches the
     instruction sequence around PC.  */
  for (ti = 0; tramp->insn[ti].bytes != TRAMP_SENTINEL_INSN; ti++)
    {
      CORE_ADDR func = pc - tramp->insn_size * ti;
      int i;

      for (i = 0; 1; i++)
	{
	  gdb_byte buf[sizeof (tramp->insn[0])];
	  ULONGEST insn;
	  size_t insn_size = tramp->insn_size;

	  if (tramp->insn[i].bytes == TRAMP_SENTINEL_INSN)
	    return func;
	  if (!safe_frame_unwind_memory (this_frame,
					 func + i * insn_size,
					 {buf, insn_size}))
	    break;
	  insn = extract_unsigned_integer (buf, insn_size, byte_order);
	  if (tramp->insn[i].bytes != (insn & tramp->insn[i].mask))
	    break;
	}
    }
  /* Trampoline doesn't match.  */
  return 0;
}

static int
tramp_frame_sniffer (const struct frame_unwind *self,
		     frame_info_ptr this_frame,
		     void **this_cache)
{
  const struct tramp_frame *tramp = self->unwind_data->tramp_frame;
  CORE_ADDR pc = get_frame_pc (this_frame);
  CORE_ADDR func;
  struct tramp_frame_cache *tramp_cache;

  /* tausq/2004-12-12: We used to assume if pc has a name or is in a valid 
     section, then this is not a trampoline.  However, this assumption is
     false on HPUX which has a signal trampoline that has a name; it can
     also be false when using an alternative signal stack.  */
  func = tramp_frame_start (tramp, this_frame, pc);
  if (func == 0)
    return 0;
  tramp_cache = FRAME_OBSTACK_ZALLOC (struct tramp_frame_cache);
  tramp_cache->func = func;
  tramp_cache->tramp_frame = tramp;
  (*this_cache) = tramp_cache;
  return 1;
}

void
tramp_frame_prepend_unwinder (struct gdbarch *gdbarch,
			      const struct tramp_frame *tramp_frame)
{
  struct frame_data *data;
  struct frame_unwind *unwinder;
  int i;

  /* Check that the instruction sequence contains a sentinel.  */
  for (i = 0; i < ARRAY_SIZE (tramp_frame->insn); i++)
    {
      if (tramp_frame->insn[i].bytes == TRAMP_SENTINEL_INSN)
	break;
    }
  gdb_assert (i < ARRAY_SIZE (tramp_frame->insn));
  gdb_assert (tramp_frame->insn_size <= sizeof (tramp_frame->insn[0].bytes));

  data = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_data);
  unwinder = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind);

  data->tramp_frame = tramp_frame;
  unwinder->type = tramp_frame->frame_type;
  unwinder->unwind_data = data;
  unwinder->sniffer = tramp_frame_sniffer;
  unwinder->stop_reason = default_frame_unwind_stop_reason;
  unwinder->this_id = tramp_frame_this_id;
  unwinder->prev_register = tramp_frame_prev_register;
  frame_unwind_prepend_unwinder (gdbarch, unwinder);
}
