/* 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 "ia64-tdep.h"
#include "ia64-hpux-tdep.h"
#include "solib-ia64-hpux.h"
#include "solist.h"
#include "solib.h"
#include "target.h"
#include "gdbtypes.h"
#include "inferior.h"
#include "gdbcore.h"
#include "regcache.h"
#include "opcode/ia64.h"
#include "symfile.h"
#include "objfiles.h"
#include "elf-bfd.h"
#include "exceptions.h"

/* Need to define the following macro in order to get the complete
   load_module_desc struct definition in dlfcn.h  Otherwise, it doesn't
   match the size of the struct the loader is providing us during load
   events.  */
#define _LOAD_MODULE_DESC_EXT

#include <sys/ttrace.h>
#include <dlfcn.h>
#include <elf.h>
#include <service_mgr.h>

/* The following is to have access to the definition of type load_info_t.  */
#include <crt0.h>

/* The r32 pseudo-register number.

   Like all stacked registers, r32 is treated as a pseudo-register,
   because it is not always available for read/write via the ttrace
   interface.  */
/* This is a bit of a hack, as we duplicate something hidden inside
   ia64-tdep.c, but oh well...  */
#define IA64_R32_PSEUDO_REGNUM (IA64_NAT127_REGNUM + 2)

/* Our struct so_list private data structure.  */

struct lm_info
{
  /* The shared library module descriptor.  We extract this structure
     from the loader at the time the shared library gets mapped.  */
  struct load_module_desc module_desc;

  /* The text segment address as defined in the shared library object
     (this is not the address where this segment got loaded).  This
     field is initially set to zero, and computed lazily.  */
  CORE_ADDR text_start;

  /* The data segment address as defined in the shared library object
     (this is not the address where this segment got loaded).  This
     field is initially set to zero, and computed lazily.  */
  CORE_ADDR data_start;
};

/* The list of shared libraries currently mapped by the inferior.  */

static struct so_list *so_list_head = NULL;

/* Create a new so_list element.  The result should be deallocated
   when no longer in use.  */

static struct so_list *
new_so_list (char *so_name, struct load_module_desc module_desc)
{
  struct so_list *new_so;

  new_so = (struct so_list *) XZALLOC (struct so_list);
  new_so->lm_info = (struct lm_info *) XZALLOC (struct lm_info);
  new_so->lm_info->module_desc = module_desc;

  strncpy (new_so->so_name, so_name, SO_NAME_MAX_PATH_SIZE - 1);
  new_so->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
  strcpy (new_so->so_original_name, new_so->so_name);

  return new_so;
}

/* Return non-zero if the instruction at the current PC is a breakpoint
   part of the dynamic loading process.

   We identify such instructions by checking that the instruction at
   the current pc is a break insn where no software breakpoint has been
   inserted by us.  We also verify that the operands have specific
   known values, to be extra certain.

   PTID is the ptid of the thread that should be checked, but this
   function also assumes that inferior_ptid is already equal to PTID.
   Ideally, we would like to avoid the requirement on inferior_ptid,
   but many routines still use the inferior_ptid global to access
   the relevant thread's register and memory.  We still have the ptid
   as parameter to be able to pass it to the routines that do take a ptid
   - that way we avoid increasing explicit uses of the inferior_ptid
   global.  */

static int
ia64_hpux_at_dld_breakpoint_1_p (ptid_t ptid)
{
  struct regcache *regcache = get_thread_regcache (ptid);
  CORE_ADDR pc = regcache_read_pc (regcache);
  struct address_space *aspace = get_regcache_aspace (regcache);
  ia64_insn t0, t1, slot[3], template, insn;
  int slotnum;
  bfd_byte bundle[16];

  /* If this is a regular breakpoint, then it can not be a dld one.  */
  if (breakpoint_inserted_here_p (aspace, pc))
    return 0;

  slotnum = ((long) pc) & 0xf;
  if (slotnum > 2)
    internal_error (__FILE__, __LINE__,
		    "invalid slot (%d) for address %s", slotnum,
		    paddress (get_regcache_arch (regcache), pc));

  pc -= (pc & 0xf);
  read_memory (pc, bundle, sizeof (bundle));

  /* bundles are always in little-endian byte order */
  t0 = bfd_getl64 (bundle);
  t1 = bfd_getl64 (bundle + 8);
  template = (t0 >> 1) & 0xf;
  slot[0] = (t0 >>  5) & 0x1ffffffffffLL;
  slot[1] = ((t0 >> 46) & 0x3ffff) | ((t1 & 0x7fffff) << 18);
  slot[2] = (t1 >> 23) & 0x1ffffffffffLL;

  if (template == 2 && slotnum == 1)
    {
      /* skip L slot in MLI template: */
      slotnum = 2;
    }

  insn = slot[slotnum];

  return (insn == 0x1c0c9c0       /* break.i 0x070327 */
          || insn == 0x3c0c9c0);  /* break.i 0x0f0327 */
}

/* Same as ia64_hpux_at_dld_breakpoint_1_p above, with the following
   differences: It temporarily sets inferior_ptid to PTID, and also
   contains any exception being raised.  */

int
ia64_hpux_at_dld_breakpoint_p (ptid_t ptid)
{
  volatile struct gdb_exception e;
  ptid_t saved_ptid = inferior_ptid;
  int result = 0;

  inferior_ptid = ptid;
  TRY_CATCH (e, RETURN_MASK_ALL)
    {
      result = ia64_hpux_at_dld_breakpoint_1_p (ptid);
    }
  inferior_ptid = saved_ptid;
  if (e.reason < 0)
    warning (_("error while checking for dld breakpoint: %s"), e.message);

  return result;
}

/* Handler for library load event: Read the information provided by
   the loader, and then use it to read the shared library symbols.  */

static void
ia64_hpux_handle_load_event (struct regcache *regcache)
{
  CORE_ADDR module_desc_addr;
  ULONGEST module_desc_size;
  CORE_ADDR so_path_addr;
  char so_path[MAXPATHLEN];
  struct load_module_desc module_desc;
  struct so_list *new_so;

  /* Extract the data provided by the loader as follow:
       - r33: Address of load_module_desc structure
       - r34: size of struct load_module_desc
       - r35: Address of string holding shared library path
   */
  regcache_cooked_read_unsigned (regcache, IA64_R32_PSEUDO_REGNUM + 1,
                                 &module_desc_addr);
  regcache_cooked_read_unsigned (regcache, IA64_R32_PSEUDO_REGNUM + 2,
                                 &module_desc_size);
  regcache_cooked_read_unsigned (regcache, IA64_R32_PSEUDO_REGNUM + 3,
                                 &so_path_addr);

  if (module_desc_size != sizeof (struct load_module_desc))
    warning (_("load_module_desc size (%ld) != size returned by kernel (%s)"),
             sizeof (struct load_module_desc),
	     pulongest (module_desc_size));

  read_memory_string (so_path_addr, so_path, MAXPATHLEN);
  read_memory (module_desc_addr, (gdb_byte *) &module_desc,
	       sizeof (module_desc));

  /* Create a new so_list element and insert it at the start of our
     so_list_head (we insert at the start of the list only because
     it is less work compared to inserting it elsewhere).  */
  new_so = new_so_list (so_path, module_desc);
  new_so->next = so_list_head;
  so_list_head = new_so;
}

/* Update the value of the PC to point to the begining of the next
   instruction bundle.  */

static void
ia64_hpux_move_pc_to_next_bundle (struct regcache *regcache)
{
  CORE_ADDR pc = regcache_read_pc (regcache);

  pc -= pc & 0xf;
  pc += 16;
  ia64_write_pc (regcache, pc);
}

/* Handle loader events.

   PTID is the ptid of the thread corresponding to the event being
   handled.  Similarly to ia64_hpux_at_dld_breakpoint_1_p, this
   function assumes that inferior_ptid is set to PTID.  */

static void
ia64_hpux_handle_dld_breakpoint_1 (ptid_t ptid)
{
  struct regcache *regcache = get_thread_regcache (ptid);
  ULONGEST arg0;

  /* The type of event is provided by the loaded via r32.  */
  regcache_cooked_read_unsigned (regcache, IA64_R32_PSEUDO_REGNUM, &arg0);
  switch (arg0)
    {
      case BREAK_DE_SVC_LOADED:
	/* Currently, the only service loads are uld and dld,
	   so we shouldn't need to do anything.  Just ignore.  */
	break;
      case BREAK_DE_LIB_LOADED:
	ia64_hpux_handle_load_event (regcache);
	solib_add (NULL, 0, &current_target, auto_solib_add);
	break;
      case BREAK_DE_LIB_UNLOADED:
      case BREAK_DE_LOAD_COMPLETE:
      case BREAK_DE_BOR:
	/* Ignore for now.  */
	break;
    }

  /* Now that we have handled the event, we can move the PC to
     the next instruction bundle, past the break instruction.  */
  ia64_hpux_move_pc_to_next_bundle (regcache);
}

/* Same as ia64_hpux_handle_dld_breakpoint_1 above, with the following
   differences: This function temporarily sets inferior_ptid to PTID,
   and also contains any exception.  */

void
ia64_hpux_handle_dld_breakpoint (ptid_t ptid)
{
  volatile struct gdb_exception e;
  ptid_t saved_ptid = inferior_ptid;

  inferior_ptid = ptid;
  TRY_CATCH (e, RETURN_MASK_ALL)
    {
      ia64_hpux_handle_dld_breakpoint_1 (ptid);
    }
  inferior_ptid = saved_ptid;
  if (e.reason < 0)
    warning (_("error detected while handling dld breakpoint: %s"), e.message);
}

/* Find the address of the code and data segments in ABFD, and update
   TEXT_START and DATA_START accordingly.  */

static void
ia64_hpux_find_start_vma (bfd *abfd, CORE_ADDR *text_start,
                          CORE_ADDR *data_start)
{
  Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
  Elf64_Phdr phdr;
  int i;

  *text_start = 0;
  *data_start = 0;

  if (bfd_seek (abfd, i_ehdrp->e_phoff, SEEK_SET) == -1)
    error (_("invalid program header offset in %s"), abfd->filename);

  for (i = 0; i < i_ehdrp->e_phnum; i++)
    {
      if (bfd_bread (&phdr, sizeof (phdr), abfd) != sizeof (phdr))
        error (_("failed to read segment %d in %s"), i, abfd->filename);

      if (phdr.p_flags & PF_X
          && (*text_start == 0 || phdr.p_vaddr < *text_start))
        *text_start = phdr.p_vaddr;

      if (phdr.p_flags & PF_W
          && (*data_start == 0 || phdr.p_vaddr < *data_start))
        *data_start = phdr.p_vaddr;
    }
}

/* The "relocate_section_addresses" target_so_ops routine for ia64-hpux.  */

static void
ia64_hpux_relocate_section_addresses (struct so_list *so,
				      struct target_section *sec)
{
  CORE_ADDR offset = 0;

  /* If we haven't computed the text & data segment addresses, do so now.
     We do this here, because we now have direct access to the associated
     bfd, whereas we would have had to open our own if we wanted to do it
     while processing the library-load event.  */
  if (so->lm_info->text_start == 0 && so->lm_info->data_start == 0)
    ia64_hpux_find_start_vma (sec->bfd, &so->lm_info->text_start,
			      &so->lm_info->data_start);

  /* Determine the relocation offset based on which segment
     the section belongs to.  */
  if ((so->lm_info->text_start < so->lm_info->data_start
       && sec->addr < so->lm_info->data_start)
      || (so->lm_info->text_start > so->lm_info->data_start
          && sec->addr >= so->lm_info->text_start))
    offset = so->lm_info->module_desc.text_base - so->lm_info->text_start;
  else if ((so->lm_info->text_start < so->lm_info->data_start
            && sec->addr >= so->lm_info->data_start)
           || (so->lm_info->text_start > so->lm_info->data_start
	       && sec->addr < so->lm_info->text_start))
    offset = so->lm_info->module_desc.data_base - so->lm_info->data_start;

  /* And now apply the relocation.  */
  sec->addr += offset;
  sec->endaddr += offset;

  /* Best effort to set addr_high/addr_low.  This is used only by
     'info sharedlibrary'.  */
  if (so->addr_low == 0 || sec->addr < so->addr_low)
    so->addr_low = sec->addr;

  if (so->addr_high == 0 || sec->endaddr > so->addr_high)
    so->addr_high = sec->endaddr;
}

/* The "free_so" target_so_ops routine for ia64-hpux.  */

static void
ia64_hpux_free_so (struct so_list *so)
{
  xfree (so->lm_info);
}

/* The "clear_solib" target_so_ops routine for ia64-hpux.  */

static void
ia64_hpux_clear_solib (void)
{
  struct so_list *so;

  while (so_list_head != NULL)
    {
      so = so_list_head;
      so_list_head = so_list_head->next;

      ia64_hpux_free_so (so);
      xfree (so);
    }
}

/* Assuming the inferior just stopped on an EXEC event, return
   the address of the load_info_t structure.  */

static CORE_ADDR
ia64_hpux_get_load_info_addr (void)
{
  struct type *data_ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
  CORE_ADDR addr;
  int status;

  /* The address of the load_info_t structure is stored in the 4th
     argument passed to the initial thread of the process (in other
     words, in argv[3]).  So get the address of these arguments,
     and extract the 4th one.  */
  status = ttrace (TT_PROC_GET_ARGS, ptid_get_pid (inferior_ptid),
		   0, (uintptr_t) &addr, sizeof (CORE_ADDR), 0);
  if (status == -1 && errno)
    perror_with_name (_("Unable to get argument list"));
  return (read_memory_typed_address (addr + 3 * 8, data_ptr_type));
}

/* A structure used to aggregate some information extracted from
   the dynamic section of the main executable.  */

struct dld_info
{
  ULONGEST dld_flags;
  CORE_ADDR load_map;
};

/* Scan the ".dynamic" section referenced by ABFD and DYN_SECT,
   and extract the information needed to fill in INFO.  */

static void
ia64_hpux_read_dynamic_info (struct gdbarch *gdbarch, bfd *abfd,
			     asection *dyn_sect, struct dld_info *info)
{
  int sect_size;
  char *buf;
  char *buf_end;

  /* Make sure that info always has initialized data, even if we fail
     to read the syn_sect section.  */
  memset (info, 0, sizeof (struct dld_info));

  sect_size = bfd_section_size (abfd, dyn_sect);
  buf = alloca (sect_size);
  buf_end = buf + sect_size;

  if (bfd_seek (abfd, dyn_sect->filepos, SEEK_SET) != 0
      || bfd_bread (buf, sect_size, abfd) != sect_size)
    error (_("failed to read contents of .dynamic section"));

  for (; buf < buf_end; buf += sizeof (Elf64_Dyn))
    {
      Elf64_Dyn *dynp = (Elf64_Dyn *) buf;
      Elf64_Sxword d_tag;

      d_tag = bfd_h_get_64 (abfd, &dynp->d_tag);
      switch (d_tag)
        {
          case DT_HP_DLD_FLAGS:
            info->dld_flags = bfd_h_get_64 (abfd, &dynp->d_un);
            break;

          case DT_HP_LOAD_MAP:
            {
              CORE_ADDR load_map_addr = bfd_h_get_64 (abfd, &dynp->d_un.d_ptr);

              if (target_read_memory (load_map_addr, (char *) &info->load_map,
                                      sizeof (info->load_map)) != 0)
		error (_("failed to read load map at %s"),
		       paddress (gdbarch, load_map_addr));
            }
            break;
        }
    }
}

/* Wrapper around target_read_memory used with libdl.  */

static void *
ia64_hpux_read_tgt_mem (void *buffer, uint64_t ptr, size_t bufsiz, int ident)
{
  if (target_read_memory (ptr, (gdb_byte *) buffer, bufsiz) != 0)
    return 0;
  else
    return buffer;
}

/* Create a new so_list object for a shared library, and store that
   new so_list object in our SO_LIST_HEAD list.

   SO_INDEX is an index specifying the placement of the loaded shared
   library in the dynamic loader's search list.  Normally, this index
   is strictly positive, but an index of -1 refers to the loader itself.

   Return nonzero if the so_list object could be created.  A null
   return value with a positive SO_INDEX normally means that there are
   no more entries in the dynamic loader's search list at SO_INDEX or
   beyond.  */

static int
ia64_hpux_add_so_from_dld_info (struct dld_info info, int so_index)
{
  struct load_module_desc module_desc;
  uint64_t so_handle;
  char *so_path;
  struct so_list *so;

  so_handle = dlgetmodinfo (so_index, &module_desc, sizeof (module_desc),
			    ia64_hpux_read_tgt_mem, 0, info.load_map);

  if (so_handle == 0)
    /* No such entry.  We probably reached the end of the list.  */
    return 0;

  so_path = dlgetname (&module_desc, sizeof (module_desc),
                       ia64_hpux_read_tgt_mem, 0, info.load_map);
  if (so_path == NULL)
    {
      /* Should never happen, but let's not crash if it does.  */
      warning (_("unable to get shared library name, symbols not loaded"));
      return 0;
    }

  /* Create a new so_list and insert it at the start of our list.
     The order is not extremely important, but it's less work to do so
     at the end of the list.  */
  so = new_so_list (so_path, module_desc);
  so->next = so_list_head;
  so_list_head = so;

  return 1;
}

/* Assuming we just attached to a process, update our list of shared
   libraries (SO_LIST_HEAD) as well as GDB's list.  */

static void
ia64_hpux_solib_add_after_attach (void)
{
  bfd *abfd;
  asection *dyn_sect;
  struct dld_info info;
  int i;

  if (symfile_objfile == NULL)
    return;

  abfd = symfile_objfile->obfd;
  dyn_sect = bfd_get_section_by_name (abfd, ".dynamic");

  if (dyn_sect == NULL || bfd_section_size (abfd, dyn_sect) == 0)
    return;

  ia64_hpux_read_dynamic_info (get_objfile_arch (symfile_objfile), abfd,
			       dyn_sect, &info);

  if ((info.dld_flags & DT_HP_DEBUG_PRIVATE) == 0)
    {
      warning (_(
"The shared libraries were not privately mapped; setting a breakpoint\n\
in a shared library will not work until you rerun the program.\n\
Use the following command to enable debugging of shared libraries.\n\
chatr +dbg enable a.out"));
    }

  /* Read the symbols of the dynamic loader (dld.so).  */
  ia64_hpux_add_so_from_dld_info (info, -1);

  /* Read the symbols of all the other shared libraries.  */
  for (i = 1; ; i++)
    if (!ia64_hpux_add_so_from_dld_info (info, i))
      break;  /* End of list.  */

  /* Resync the library list at the core level.  */
  solib_add (NULL, 1, &current_target, auto_solib_add);
}

/* The "create_inferior_hook" target_so_ops routine for ia64-hpux.  */

static void
ia64_hpux_solib_create_inferior_hook (int from_tty)
{
  CORE_ADDR load_info_addr;
  load_info_t load_info;

  /* Initially, we were thinking about adding a check that the program
     (accessible through symfile_objfile) was linked against some shared
     libraries, by searching for a ".dynamic" section.  However, could
     this break in the case of a statically linked program that later
     uses dlopen?  Programs that are fully statically linked are very
     rare, and we will worry about them when we encounter one that
     causes trouble.  */

  /* Set the LI_TRACE flag in the load_info_t structure.  This enables
     notifications when shared libraries are being mapped.  */
  load_info_addr = ia64_hpux_get_load_info_addr ();
  read_memory (load_info_addr, (gdb_byte *) &load_info, sizeof (load_info));
  load_info.li_flags |= LI_TRACE;
  write_memory (load_info_addr, (gdb_byte *) &load_info, sizeof (load_info));

  /* If we just attached to our process, some shard libraries have
     already been mapped.  Find which ones they are...  */
  if (current_inferior ()->attach_flag)
    ia64_hpux_solib_add_after_attach ();
}

/* The "special_symbol_handling" target_so_ops routine for ia64-hpux.  */

static void
ia64_hpux_special_symbol_handling (void)
{
  /* Nothing to do.  */
}

/* The "current_sos" target_so_ops routine for ia64-hpux.  */

static struct so_list *
ia64_hpux_current_sos (void)
{
  /* Return a deep copy of our own list.  */
  struct so_list *new_head = NULL, *prev_new_so = NULL;
  struct so_list *our_so;

  for (our_so = so_list_head; our_so != NULL; our_so = our_so->next)
    {
      struct so_list *new_so;

      new_so = new_so_list (our_so->so_name, our_so->lm_info->module_desc);
      if (prev_new_so != NULL)
        prev_new_so->next = new_so;
      prev_new_so = new_so;
      if (new_head == NULL)
        new_head = new_so;
    }

  return new_head;
}

/* The "open_symbol_file_object" target_so_ops routine for ia64-hpux.  */

static int
ia64_hpux_open_symbol_file_object (void *from_ttyp)
{
  return 0;
}

/* The "in_dynsym_resolve_code" target_so_ops routine for ia64-hpux.  */

static int
ia64_hpux_in_dynsym_resolve_code (CORE_ADDR pc)
{
  return 0;
}

/* If FADDR is the address of a function inside one of the shared
   libraries, return the shared library linkage address.  */

CORE_ADDR
ia64_hpux_get_solib_linkage_addr (CORE_ADDR faddr)
{
  struct so_list *so = so_list_head;

  while (so != NULL)
    {
      struct load_module_desc module_desc = so->lm_info->module_desc;

      if (module_desc.text_base <= faddr
          && (module_desc.text_base + module_desc.text_size) > faddr)
        return module_desc.linkage_ptr;

      so = so->next;
    }

  return 0;
}

/* Create a new target_so_ops structure suitable for ia64-hpux, and
   return its address.  */

static struct target_so_ops *
ia64_hpux_target_so_ops (void)
{
  struct target_so_ops *ops = XZALLOC (struct target_so_ops);

  ops->relocate_section_addresses = ia64_hpux_relocate_section_addresses;
  ops->free_so = ia64_hpux_free_so;
  ops->clear_solib = ia64_hpux_clear_solib;
  ops->solib_create_inferior_hook = ia64_hpux_solib_create_inferior_hook;
  ops->special_symbol_handling = ia64_hpux_special_symbol_handling;
  ops->current_sos = ia64_hpux_current_sos;
  ops->open_symbol_file_object = ia64_hpux_open_symbol_file_object;
  ops->in_dynsym_resolve_code = ia64_hpux_in_dynsym_resolve_code;
  ops->bfd_open = solib_bfd_open;

  return ops;
}

/* Prevent warning from -Wmissing-prototypes.  */
void _initialize_solib_ia64_hpux (void);

void
_initialize_solib_ia64_hpux (void)
{
  ia64_hpux_so_ops = ia64_hpux_target_so_ops ();
}
