/* Target-dependent code for OpenVMS IA-64.

   Copyright (C) 2012-2016 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 "frame-unwind.h"
#include "ia64-tdep.h"
#include "osabi.h"
#include "gdbtypes.h"
#include "gdbcore.h"

#ifdef HAVE_LIBUNWIND_IA64_H

/* Libunwind callback accessor function to acquire procedure unwind-info.  */

static int
ia64_vms_find_proc_info_x (unw_addr_space_t as, unw_word_t ip,
                           unw_proc_info_t *pi,
                           int need_unwind_info, void *arg)
{
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
  unw_dyn_info_t di;
  int ret;
  gdb_byte buf[32];
  const char *annex = core_addr_to_string (ip);
  LONGEST res;
  CORE_ADDR table_addr;
  unsigned int info_len;

  res = target_read (&current_target, TARGET_OBJECT_OPENVMS_UIB,
                     annex + 2, buf, 0, sizeof (buf));

  if (res != sizeof (buf))
    return -UNW_ENOINFO;

  pi->format = UNW_INFO_FORMAT_REMOTE_TABLE;
  pi->start_ip = extract_unsigned_integer (buf + 0, 8, byte_order);
  pi->end_ip = extract_unsigned_integer (buf + 8, 8, byte_order);
  pi->gp = extract_unsigned_integer (buf + 24, 8, byte_order);
  table_addr = extract_unsigned_integer (buf + 16, 8, byte_order);

  if (table_addr == 0)
    {
      /* No unwind data.  */
      pi->unwind_info = NULL;
      pi->unwind_info_size = 0;
      return 0;
    }

  res = target_read_memory (table_addr, buf, 8);
  if (res != 0)
    return -UNW_ENOINFO;

  /* Check version.  */
  if (extract_unsigned_integer (buf + 6, 2, byte_order) != 1)
    return -UNW_EBADVERSION;
  info_len = extract_unsigned_integer (buf + 0, 4, byte_order);
  pi->unwind_info_size = 8 * info_len;

  /* Read info.  */
  pi->unwind_info = xmalloc (pi->unwind_info_size);

  res = target_read_memory (table_addr + 8,
                            pi->unwind_info, pi->unwind_info_size);
  if (res != 0)
    {
      xfree (pi->unwind_info);
      pi->unwind_info = NULL;
      return -UNW_ENOINFO;
    }

  /* FIXME: Handle OSSD (OS Specific Data).  This extension to ia64 unwind
     information by OpenVMS is currently not handled by libunwind, but
     looks to be used only in very specific context, and is not generated by
     GCC.  */

  pi->lsda = table_addr + 8 + pi->unwind_info_size;
  if (extract_unsigned_integer (buf + 4, 2, byte_order) & 3)
    {
      pi->lsda += 8;
      /* There might be an handler, but this is not used for unwinding.  */
      pi->handler = 0;
    }

  return 0;
}

/* Libunwind callback accessor function for cleanup.  */

static void
ia64_vms_put_unwind_info (unw_addr_space_t as,
                          unw_proc_info_t *pip, void *arg)
{
  /* Nothing required for now.  */
}

/* Libunwind callback accessor function to get head of the dynamic
   unwind-info registration list.  */

static int
ia64_vms_get_dyn_info_list (unw_addr_space_t as,
                            unw_word_t *dilap, void *arg)
{
  return -UNW_ENOINFO;
}

/* Set of libunwind callback acccessor functions.  */
static unw_accessors_t ia64_vms_unw_accessors;
static unw_accessors_t ia64_vms_unw_rse_accessors;

/* Set of ia64-libunwind-tdep gdb callbacks and data for generic
   ia64-libunwind-tdep code to use.  */
static struct libunwind_descr ia64_vms_libunwind_descr;

#endif /* HAVE_LIBUNWIND_IA64_H */

static void
ia64_openvms_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
  set_gdbarch_long_double_format (gdbarch, floatformats_ia64_quad);

#ifdef HAVE_LIBUNWIND_IA64_H
  /* Override the default descriptor.  */
  ia64_vms_unw_accessors = ia64_unw_accessors;
  ia64_vms_unw_accessors.find_proc_info = ia64_vms_find_proc_info_x;
  ia64_vms_unw_accessors.put_unwind_info = ia64_vms_put_unwind_info;
  ia64_vms_unw_accessors.get_dyn_info_list_addr = ia64_vms_get_dyn_info_list;

  ia64_vms_unw_rse_accessors = ia64_unw_rse_accessors;
  ia64_vms_unw_rse_accessors.find_proc_info = ia64_vms_find_proc_info_x;
  ia64_vms_unw_rse_accessors.put_unwind_info = ia64_vms_put_unwind_info;
  ia64_vms_unw_rse_accessors.get_dyn_info_list_addr = ia64_vms_get_dyn_info_list;

  ia64_vms_libunwind_descr = ia64_libunwind_descr;
  ia64_vms_libunwind_descr.accessors = &ia64_vms_unw_accessors;
  ia64_vms_libunwind_descr.special_accessors = &ia64_vms_unw_rse_accessors;

  libunwind_frame_set_descr (gdbarch, &ia64_vms_libunwind_descr);
#endif
}

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

void
_initialize_ia64_vms_tdep (void)
{
  gdbarch_register_osabi (bfd_arch_ia64, 0, GDB_OSABI_OPENVMS,
			  ia64_openvms_init_abi);
}
