/* Call site information.

   Copyright (C) 2011-2024 Free Software Foundation, Inc.

   Contributed by Cygnus Support, using pieces from other GDB modules.

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

#ifndef CALL_SITE_H
#define CALL_SITE_H

#include "dwarf2/types.h"
#include "../frame.h"
#include "gdbsupport/function-view.h"

struct dwarf2_locexpr_baton;
struct dwarf2_per_cu_data;
struct dwarf2_per_objfile;

/* struct call_site_parameter can be referenced in callees by several ways.  */

enum call_site_parameter_kind
{
  /* * Use field call_site_parameter.u.dwarf_reg.  */
  CALL_SITE_PARAMETER_DWARF_REG,

  /* * Use field call_site_parameter.u.fb_offset.  */
  CALL_SITE_PARAMETER_FB_OFFSET,

  /* * Use field call_site_parameter.u.param_offset.  */
  CALL_SITE_PARAMETER_PARAM_OFFSET
};

struct call_site_target
{
  /* The kind of location held by this call site target.  */
  enum kind
  {
    /* An address.  */
    PHYSADDR,
    /* A name.  */
    PHYSNAME,
    /* A DWARF block.  */
    DWARF_BLOCK,
    /* An array of addresses.  */
    ADDRESSES,
  };

  void set_loc_physaddr (unrelocated_addr physaddr)
  {
    m_loc_kind = PHYSADDR;
    m_loc.physaddr = physaddr;
  }

  void set_loc_physname (const char *physname)
    {
      m_loc_kind = PHYSNAME;
      m_loc.physname = physname;
    }

  void set_loc_dwarf_block (dwarf2_locexpr_baton *dwarf_block)
    {
      m_loc_kind = DWARF_BLOCK;
      m_loc.dwarf_block = dwarf_block;
    }

  void set_loc_array (unsigned length, const unrelocated_addr *data)
  {
    m_loc_kind = ADDRESSES;
    m_loc.addresses.length = length;
    m_loc.addresses.values = data;
  }

  /* Callback type for iterate_over_addresses.  */

  using iterate_ftype = gdb::function_view<void (CORE_ADDR)>;

  /* Call CALLBACK for each DW_TAG_call_site's DW_AT_call_target
     address.  CALLER_FRAME (for registers) can be NULL if it is not
     known.  This function always may throw NO_ENTRY_VALUE_ERROR.  */

  void iterate_over_addresses (struct gdbarch *call_site_gdbarch,
			       const struct call_site *call_site,
			       const frame_info_ptr &caller_frame,
			       iterate_ftype callback) const;

private:

  union
  {
    /* Address.  */
    unrelocated_addr physaddr;
    /* Mangled name.  */
    const char *physname;
    /* DWARF block.  */
    struct dwarf2_locexpr_baton *dwarf_block;
    /* Array of addresses.  */
    struct
    {
      unsigned length;
      const unrelocated_addr *values;
    } addresses;
  } m_loc;

  /* * Discriminant for union field_location.  */
  enum kind m_loc_kind;
};

union call_site_parameter_u
{
  /* * DW_TAG_formal_parameter's DW_AT_location's DW_OP_regX
     as DWARF register number, for register passed
     parameters.  */

  int dwarf_reg;

  /* * Offset from the callee's frame base, for stack passed
     parameters.  This equals offset from the caller's stack
     pointer.  */

  CORE_ADDR fb_offset;

  /* * Offset relative to the start of this PER_CU to
     DW_TAG_formal_parameter which is referenced by both
     caller and the callee.  */

  cu_offset param_cu_off;
};

struct call_site_parameter
{
  ENUM_BITFIELD (call_site_parameter_kind) kind : 2;

  union call_site_parameter_u u;

  /* * DW_TAG_formal_parameter's DW_AT_call_value.  It is never NULL.  */

  const gdb_byte *value;
  size_t value_size;

  /* * DW_TAG_formal_parameter's DW_AT_call_data_value.
     It may be NULL if not provided by DWARF.  */

  const gdb_byte *data_value;
  size_t data_value_size;
};

/* * A place where a function gets called from, represented by
   DW_TAG_call_site.  It can be looked up from symtab->call_site_htab.  */

struct call_site
{
  call_site (unrelocated_addr pc, dwarf2_per_cu_data *per_cu,
	     dwarf2_per_objfile *per_objfile)
    : per_cu (per_cu), per_objfile (per_objfile), m_unrelocated_pc (pc)
  {}

  static int
  eq (const call_site *a, const call_site *b)
  {
    return a->m_unrelocated_pc == b->m_unrelocated_pc;
  }

  static hashval_t
  hash (const call_site *a)
  {
    return (hashval_t) a->m_unrelocated_pc;
  }

  static int
  eq (const void *a, const void *b)
  {
    return eq ((const call_site *)a, (const call_site *)b);
  }

  static hashval_t
  hash (const void *a)
  {
    return hash ((const call_site *)a);
  }

  /* Return the address of the first instruction after this call.  */

  CORE_ADDR pc () const;

  /* Call CALLBACK for each target address.  CALLER_FRAME (for
     registers) can be NULL if it is not known.  This function may
     throw NO_ENTRY_VALUE_ERROR.  */

  void iterate_over_addresses (struct gdbarch *call_site_gdbarch,
			       const frame_info_ptr &caller_frame,
			       call_site_target::iterate_ftype callback)
    const
  {
    return target.iterate_over_addresses (call_site_gdbarch, this,
					  caller_frame, callback);
  }

  /* * List successor with head in FUNC_TYPE.TAIL_CALL_LIST.  */

  struct call_site *tail_call_next = nullptr;

  /* * Describe DW_AT_call_target.  Missing attribute uses
     FIELD_LOC_KIND_DWARF_BLOCK with FIELD_DWARF_BLOCK == NULL.  */

  struct call_site_target target {};

  /* * Size of the PARAMETER array.  */

  unsigned parameter_count = 0;

  /* * CU of the function where the call is located.  It gets used
     for DWARF blocks execution in the parameter array below.  */

  dwarf2_per_cu_data *const per_cu = nullptr;

  /* objfile of the function where the call is located.  */

  dwarf2_per_objfile *const per_objfile = nullptr;

private:
  /* Unrelocated address of the first instruction after this call.  */
  const unrelocated_addr m_unrelocated_pc;

public:
  /* * Describe DW_TAG_call_site's DW_TAG_formal_parameter.  */

  struct call_site_parameter parameter[];
};

#endif /* CALL_SITE_H */
