/* Handle PA64 shared libraries for GDB, the GNU Debugger.

   Copyright (C) 2004, 2007, 2008, 2009, 2010 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/>.
   
   HP in their infinite stupidity choose not to use standard ELF dynamic
   linker interfaces.  They also choose not to make their ELF dymamic
   linker interfaces compatible with the SOM dynamic linker.  The
   net result is we can not use either of the existing somsolib.c or
   solib.c.  What a crock.

   Even more disgusting.  This file depends on functions provided only
   in certain PA64 libraries.  Thus this file is supposed to only be
   used native.  When will HP ever learn that they need to provide the
   same functionality in all their libraries!  */

#include "defs.h"
#include "symtab.h"
#include "bfd.h"
#include "symfile.h"
#include "objfiles.h"
#include "gdbcore.h"
#include "target.h"
#include "inferior.h"
#include "regcache.h"

#include "hppa-tdep.h"
#include "solist.h"
#include "solib.h"
#include "solib-pa64.h"

#undef SOLIB_PA64_DBG

/* We can build this file only when running natively on 64-bit HP/UX.
   We check for that by checking for the elf_hp.h header file.  */
#if defined(HAVE_ELF_HP_H) && defined(__LP64__)

/* FIXME: kettenis/20041213: These includes should be eliminated.  */
#include <dlfcn.h>
#include <elf.h>
#include <elf_hp.h>

struct lm_info {
  struct load_module_desc desc;
  CORE_ADDR desc_addr;
};

/* When adding fields, be sure to clear them in _initialize_pa64_solib. */
typedef struct
  {
    CORE_ADDR dld_flags_addr;
    LONGEST dld_flags;
    struct bfd_section *dyninfo_sect;
    int have_read_dld_descriptor;
    int is_valid;
    CORE_ADDR load_map;
    CORE_ADDR load_map_addr;
    struct load_module_desc dld_desc;
  }
dld_cache_t;

static dld_cache_t dld_cache;

static int
read_dynamic_info (asection *dyninfo_sect, dld_cache_t *dld_cache_p);

static void
pa64_relocate_section_addresses (struct so_list *so,
				 struct target_section *sec)
{
  asection *asec = sec->the_bfd_section;
  CORE_ADDR load_offset;

  /* Relocate all the sections based on where they got loaded.  */

  load_offset = bfd_section_vma (so->abfd, asec) - asec->filepos;

  if (asec->flags & SEC_CODE)
    {
      sec->addr += so->lm_info->desc.text_base - load_offset;
      sec->endaddr += so->lm_info->desc.text_base - load_offset;
    }
  else if (asec->flags & SEC_DATA)
    {
      sec->addr += so->lm_info->desc.data_base - load_offset;
      sec->endaddr += so->lm_info->desc.data_base - load_offset;
    }
}

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

static void
pa64_clear_solib (void)
{
}

/* Wrapper for target_read_memory for dlgetmodinfo.  */

static void *
pa64_target_read_memory (void *buffer, CORE_ADDR ptr, size_t bufsiz, int ident)
{
  if (target_read_memory (ptr, buffer, bufsiz) != 0)
    return 0;
  return buffer;
}

/* Read the dynamic linker's internal shared library descriptor.

   This must happen after dld starts running, so we can't do it in
   read_dynamic_info.  Record the fact that we have loaded the
   descriptor.  If the library is archive bound or the load map
   hasn't been setup, then return zero; else return nonzero.  */

static int
read_dld_descriptor (void)
{
  char *dll_path;
  asection *dyninfo_sect;

  /* If necessary call read_dynamic_info to extract the contents of the
     .dynamic section from the shared library.  */
  if (!dld_cache.is_valid) 
    {
      if (symfile_objfile == NULL)
	error (_("No object file symbols."));

      dyninfo_sect = bfd_get_section_by_name (symfile_objfile->obfd, 
					      ".dynamic");
      if (!dyninfo_sect) 
	{
	  return 0;
	}

      if (!read_dynamic_info (dyninfo_sect, &dld_cache))
	error (_("Unable to read in .dynamic section information."));
    }

  /* Read the load map pointer.  */
  if (target_read_memory (dld_cache.load_map_addr,
			  (char *) &dld_cache.load_map,
			  sizeof (dld_cache.load_map))
      != 0)
    {
      error (_("Error while reading in load map pointer."));
    }

  if (!dld_cache.load_map)
    return 0;

  /* Read in the dld load module descriptor */
  if (dlgetmodinfo (-1, 
		    &dld_cache.dld_desc,
		    sizeof (dld_cache.dld_desc), 
		    pa64_target_read_memory, 
		    0, 
		    dld_cache.load_map)
      == 0)
    {
      error (_("Error trying to get information about dynamic linker."));
    }

  /* Indicate that we have loaded the dld descriptor.  */
  dld_cache.have_read_dld_descriptor = 1;

  return 1;
}


/* Read the .dynamic section and extract the information of interest,
   which is stored in dld_cache.  The routine elf_locate_base in solib.c 
   was used as a model for this.  */

static int
read_dynamic_info (asection *dyninfo_sect, dld_cache_t *dld_cache_p)
{
  char *buf;
  char *bufend;
  CORE_ADDR dyninfo_addr;
  int dyninfo_sect_size;
  CORE_ADDR entry_addr;

  /* Read in .dynamic section, silently ignore errors.  */
  dyninfo_addr = bfd_section_vma (symfile_objfile->obfd, dyninfo_sect);
  dyninfo_sect_size = bfd_section_size (exec_bfd, dyninfo_sect);
  buf = alloca (dyninfo_sect_size);
  if (target_read_memory (dyninfo_addr, buf, dyninfo_sect_size))
    return 0;

  /* Scan the .dynamic section and record the items of interest. 
     In particular, DT_HP_DLD_FLAGS */
  for (bufend = buf + dyninfo_sect_size, entry_addr = dyninfo_addr;
       buf < bufend;
       buf += sizeof (Elf64_Dyn), entry_addr += sizeof (Elf64_Dyn))
    {
      Elf64_Dyn *x_dynp = (Elf64_Dyn*)buf;
      Elf64_Sxword dyn_tag;
      CORE_ADDR	dyn_ptr;

      dyn_tag = bfd_h_get_64 (symfile_objfile->obfd, 
			      (bfd_byte*) &x_dynp->d_tag);

      /* We can't use a switch here because dyn_tag is 64 bits and HP's
	 lame comiler does not handle 64bit items in switch statements.  */
      if (dyn_tag == DT_NULL)
	break;
      else if (dyn_tag == DT_HP_DLD_FLAGS)
	{
	  /* Set dld_flags_addr and dld_flags in *dld_cache_p */
	  dld_cache_p->dld_flags_addr = entry_addr + offsetof(Elf64_Dyn, d_un);
	  if (target_read_memory (dld_cache_p->dld_flags_addr,
	  			  (char*) &dld_cache_p->dld_flags, 
				  sizeof (dld_cache_p->dld_flags))
	      != 0)
	    {
	      error (_("Error while reading in .dynamic section of the program."));
	    }
	}
      else if (dyn_tag == DT_HP_LOAD_MAP)
	{
	  /* Dld will place the address of the load map at load_map_addr
	     after it starts running.  */
	  if (target_read_memory (entry_addr + offsetof(Elf64_Dyn, 
							d_un.d_ptr),
				  (char*) &dld_cache_p->load_map_addr,
				  sizeof (dld_cache_p->load_map_addr))
	      != 0)
	    {
	      error (_("Error while reading in .dynamic section of the program."));
	    }
	}
      else 
	{
	  /* tag is not of interest */
	}
    }

  /* Record other information and set is_valid to 1. */
  dld_cache_p->dyninfo_sect = dyninfo_sect;

  /* Verify that we read in required info.  These fields are re-set to zero
     in pa64_solib_restart.  */

  if (dld_cache_p->dld_flags_addr != 0 && dld_cache_p->load_map_addr != 0) 
    dld_cache_p->is_valid = 1;
  else 
    return 0;

  return 1;
}

/*
   bfd_lookup_symbol -- lookup the value for a specific symbol

   An expensive way to lookup the value of a single symbol for
   bfd's that are only temporary anyway.  This is used by the
   shared library support to find the address of the debugger
   interface structures in the shared library.

   Note that 0 is specifically allowed as an error return (no
   such symbol).
 */

static CORE_ADDR
bfd_lookup_symbol (bfd *abfd, char *symname)
{
  unsigned int storage_needed;
  asymbol *sym;
  asymbol **symbol_table;
  unsigned int number_of_symbols;
  unsigned int i;
  struct cleanup *back_to;
  CORE_ADDR symaddr = 0;

  storage_needed = bfd_get_symtab_upper_bound (abfd);

  if (storage_needed > 0)
    {
      symbol_table = (asymbol **) xmalloc (storage_needed);
      back_to = make_cleanup (xfree, symbol_table);
      number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);

      for (i = 0; i < number_of_symbols; i++)
	{
	  sym = *symbol_table++;
	  if (strcmp (sym->name, symname) == 0)
	    {
	      /* Bfd symbols are section relative. */
	      symaddr = sym->value + sym->section->vma;
	      break;
	    }
	}
      do_cleanups (back_to);
    }
  return (symaddr);
}


/* This hook gets called just before the first instruction in the
   inferior process is executed.

   This is our opportunity to set magic flags in the inferior so
   that GDB can be notified when a shared library is mapped in and
   to tell the dynamic linker that a private copy of the library is
   needed (so GDB can set breakpoints in the library).

   We need to set DT_HP_DEBUG_CALLBACK to indicate that we want the
   dynamic linker to call the breakpoint routine for significant events.
   We used to set DT_HP_DEBUG_PRIVATE to indicate that shared libraries
   should be mapped private.  However, this flag can be set using
   "chatr +dbg enable".  Not setting DT_HP_DEBUG_PRIVATE allows debugging
   with shared libraries mapped shareable.  */

static void
pa64_solib_create_inferior_hook (int from_tty)
{
  struct minimal_symbol *msymbol;
  unsigned int dld_flags, status;
  asection *shlib_info, *interp_sect;
  char buf[4];
  struct objfile *objfile;
  CORE_ADDR anaddr;

  /* First, remove all the solib event breakpoints.  Their addresses
     may have changed since the last time we ran the program.  */
  remove_solib_event_breakpoints ();

  if (symfile_objfile == NULL)
    return;

  /* First see if the objfile was dynamically linked.  */
  shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, ".dynamic");
  if (!shlib_info)
    return;

  /* It's got a .dynamic section, make sure it's not empty.  */
  if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0)
    return;

  /* Read in the .dynamic section.  */
  if (! read_dynamic_info (shlib_info, &dld_cache))
    error (_("Unable to read the .dynamic section."));

  /* If the libraries were not mapped private, warn the user.  */
  if ((dld_cache.dld_flags & DT_HP_DEBUG_PRIVATE) == 0)
    warning
      (_("Private mapping of shared library text was not specified\n"
	 "by the executable; setting a breakpoint in a shared library which\n"
	 "is not privately mapped will not work.  See the HP-UX 11i v3 chatr\n"
	 "manpage for methods to privately map shared library text."));

  /* Turn on the flags we care about.  */
  dld_cache.dld_flags |= DT_HP_DEBUG_CALLBACK;
  status = target_write_memory (dld_cache.dld_flags_addr,
				(char *) &dld_cache.dld_flags,
				sizeof (dld_cache.dld_flags));
  if (status != 0)
    error (_("Unable to modify dynamic linker flags."));

  /* Now we have to create a shared library breakpoint in the dynamic
     linker.  This can be somewhat tricky since the symbol is inside
     the dynamic linker (for which we do not have symbols or a base
     load address!   Luckily I wrote this code for solib.c years ago.  */
  interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
  if (interp_sect)
    {
      unsigned int interp_sect_size;
      char *buf;
      CORE_ADDR load_addr;
      bfd *tmp_bfd;
      CORE_ADDR sym_addr = 0;

      /* Read the contents of the .interp section into a local buffer;
	 the contents specify the dynamic linker this program uses.  */
      interp_sect_size = bfd_section_size (exec_bfd, interp_sect);
      buf = alloca (interp_sect_size);
      bfd_get_section_contents (exec_bfd, interp_sect,
				buf, 0, interp_sect_size);

      /* Now we need to figure out where the dynamic linker was
	 loaded so that we can load its symbols and place a breakpoint
	 in the dynamic linker itself.

	 This address is stored on the stack.  However, I've been unable
	 to find any magic formula to find it for Solaris (appears to
	 be trivial on GNU/Linux).  Therefore, we have to try an alternate
	 mechanism to find the dynamic linker's base address.  */
      tmp_bfd = bfd_openr (buf, gnutarget);
      if (tmp_bfd == NULL)
	return;

      /* Make sure the dynamic linker's really a useful object.  */
      if (!bfd_check_format (tmp_bfd, bfd_object))
	{
	  warning (_("Unable to grok dynamic linker %s as an object file"), buf);
	  bfd_close (tmp_bfd);
	  return;
	}

      /* We find the dynamic linker's base address by examining the
	 current pc (which point at the entry point for the dynamic
	 linker) and subtracting the offset of the entry point. 

	 Also note the breakpoint is the second instruction in the
	 routine.  */
      load_addr = regcache_read_pc (get_current_regcache ())
		  - tmp_bfd->start_address;
      sym_addr = bfd_lookup_symbol (tmp_bfd, "__dld_break");
      sym_addr = load_addr + sym_addr + 4;
      
      /* Create the shared library breakpoint.  */
      {
	struct breakpoint *b
	  = create_solib_event_breakpoint (target_gdbarch, sym_addr);

	/* The breakpoint is actually hard-coded into the dynamic linker,
	   so we don't need to actually insert a breakpoint instruction
	   there.  In fact, the dynamic linker's code is immutable, even to
	   ttrace, so we shouldn't even try to do that.  For cases like
	   this, we have "permanent" breakpoints.  */
	make_breakpoint_permanent (b);
      }

      /* We're done with the temporary bfd.  */
      bfd_close (tmp_bfd);
    }
}

static void
pa64_special_symbol_handling (void)
{
}

static struct so_list *
pa64_current_sos (void)
{
  struct so_list *head = 0;
  struct so_list **link_ptr = &head;
  int dll_index;

  /* Read in the load map pointer if we have not done so already.  */
  if (! dld_cache.have_read_dld_descriptor)
    if (! read_dld_descriptor ())
      return NULL;

  for (dll_index = -1; ; dll_index++)
    {
      struct load_module_desc dll_desc;
      char *dll_path;
      struct so_list *new;
      struct cleanup *old_chain;

      if (dll_index == 0)
        continue;

      /* Read in the load module descriptor.  */
      if (dlgetmodinfo (dll_index, &dll_desc, sizeof (dll_desc),
			pa64_target_read_memory, 0, dld_cache.load_map)
	  == 0)
	break;

      /* Get the name of the shared library.  */
      dll_path = (char *)dlgetname (&dll_desc, sizeof (dll_desc),
			    pa64_target_read_memory,
			    0, dld_cache.load_map);

      new = (struct so_list *) xmalloc (sizeof (struct so_list));
      memset (new, 0, sizeof (struct so_list));
      new->lm_info = (struct lm_info *) xmalloc (sizeof (struct lm_info));
      memset (new->lm_info, 0, sizeof (struct lm_info));

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

      memcpy (&new->lm_info->desc, &dll_desc, sizeof (dll_desc));

#ifdef SOLIB_PA64_DBG
      {
        struct load_module_desc *d = &new->lm_info->desc;
	printf ("\n+ library \"%s\" is described at index %d\n", new->so_name, 
		dll_index);
	printf ("    text_base = 0x%llx\n", d->text_base); 
	printf ("    text_size = 0x%llx\n", d->text_size); 
	printf ("    data_base = 0x%llx\n", d->data_base); 
	printf ("    data_size = 0x%llx\n", d->data_size); 
	printf ("    unwind_base = 0x%llx\n", d->unwind_base); 
	printf ("    linkage_ptr = 0x%llx\n", d->linkage_ptr); 
	printf ("    phdr_base = 0x%llx\n", d->phdr_base); 
	printf ("    tls_size = 0x%llx\n", d->tls_size); 
	printf ("    tls_start_addr = 0x%llx\n", d->tls_start_addr); 
	printf ("    unwind_size = 0x%llx\n", d->unwind_size); 
	printf ("    tls_index = 0x%llx\n", d->tls_index); 
      }
#endif

      /* Link the new object onto the list.  */
      new->next = NULL;
      *link_ptr = new;
      link_ptr = &new->next;
    }

  return head;
}

static int
pa64_open_symbol_file_object (void *from_ttyp)
{
  int from_tty = *(int *)from_ttyp;
  char buf[4];
  struct load_module_desc dll_desc;
  char *dll_path;

  if (symfile_objfile)
    if (!query (_("Attempt to reload symbols from process? ")))
      return 0;

  /* Read in the load map pointer if we have not done so already.  */
  if (! dld_cache.have_read_dld_descriptor)
    if (! read_dld_descriptor ())
      return 0;

  /* Read in the load module descriptor.  */
  if (dlgetmodinfo (0, &dll_desc, sizeof (dll_desc),
		    pa64_target_read_memory, 0, dld_cache.load_map) == 0)
    return 0;

  /* Get the name of the shared library.  */
  dll_path = (char *)dlgetname (&dll_desc, sizeof (dll_desc),
				pa64_target_read_memory,
				0, dld_cache.load_map);

  /* Have a pathname: read the symbol file.  */
  symbol_file_add_main (dll_path, from_tty);

  return 1;
}

/* Return nonzero if PC is an address inside the dynamic linker.  */
static int
pa64_in_dynsym_resolve_code (CORE_ADDR pc)
{
  asection *shlib_info;

  if (symfile_objfile == NULL)
    return 0;

  if (!dld_cache.have_read_dld_descriptor)
    if (!read_dld_descriptor ())
      return 0;

  return (pc >= dld_cache.dld_desc.text_base
	  && pc < dld_cache.dld_desc.text_base + dld_cache.dld_desc.text_size);
}


/* Return the GOT value for the shared library in which ADDR belongs.  If
   ADDR isn't in any known shared library, return zero.  */

static CORE_ADDR
pa64_solib_get_got_by_pc (CORE_ADDR addr)
{
  struct so_list *so_list = master_so_list ();
  CORE_ADDR got_value = 0;

  while (so_list)
    {
      if (so_list->lm_info->desc.text_base <= addr
	  && ((so_list->lm_info->desc.text_base
	       + so_list->lm_info->desc.text_size)
	      > addr))
        {
	  got_value = so_list->lm_info->desc.linkage_ptr;
 	  break;
	}
      so_list = so_list->next;
    }
  return got_value;
}

/* Get some HPUX-specific data from a shared lib.  */
static CORE_ADDR
pa64_solib_thread_start_addr (struct so_list *so)
{
  return so->lm_info->desc.tls_start_addr;
}


/* Return the address of the handle of the shared library in which ADDR
   belongs.  If ADDR isn't in any known shared library, return zero.  */

static CORE_ADDR
pa64_solib_get_solib_by_pc (CORE_ADDR addr)
{
  struct so_list *so_list = master_so_list ();
  CORE_ADDR retval = 0;

  while (so_list)
    {
      if (so_list->lm_info->desc.text_base <= addr
	  && ((so_list->lm_info->desc.text_base
	       + so_list->lm_info->desc.text_size)
	      > addr))
	{
	  retval = so_list->lm_info->desc_addr;
	  break;
	}
      so_list = so_list->next;
    }
  return retval;
}

/* pa64 libraries do not seem to set the section offsets in a standard (i.e. 
   SVr4) way; the text section offset stored in the file doesn't correspond
   to the place where the library is actually loaded into memory.  Instead,
   we rely on the dll descriptor to tell us where things were loaded.  */
static CORE_ADDR
pa64_solib_get_text_base (struct objfile *objfile)
{
  struct so_list *so;

  for (so = master_so_list (); so; so = so->next)
    if (so->objfile == objfile)
      return so->lm_info->desc.text_base;
  
  return 0;
}

static struct target_so_ops pa64_so_ops;

extern initialize_file_ftype _initialize_pa64_solib; /* -Wmissing-prototypes */

void
_initialize_pa64_solib (void)
{
  pa64_so_ops.relocate_section_addresses = pa64_relocate_section_addresses;
  pa64_so_ops.free_so = pa64_free_so;
  pa64_so_ops.clear_solib = pa64_clear_solib;
  pa64_so_ops.solib_create_inferior_hook = pa64_solib_create_inferior_hook;
  pa64_so_ops.special_symbol_handling = pa64_special_symbol_handling;
  pa64_so_ops.current_sos = pa64_current_sos;
  pa64_so_ops.open_symbol_file_object = pa64_open_symbol_file_object;
  pa64_so_ops.in_dynsym_resolve_code = pa64_in_dynsym_resolve_code;
  pa64_so_ops.bfd_open = solib_bfd_open;

  memset (&dld_cache, 0, sizeof (dld_cache));
}

void pa64_solib_select (struct gdbarch *gdbarch)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  set_solib_ops (gdbarch, &pa64_so_ops);

  tdep->solib_thread_start_addr = pa64_solib_thread_start_addr;
  tdep->solib_get_got_by_pc = pa64_solib_get_got_by_pc;
  tdep->solib_get_solib_by_pc = pa64_solib_get_solib_by_pc;
  tdep->solib_get_text_base = pa64_solib_get_text_base;
}

#else /* HAVE_ELF_HP_H */

extern initialize_file_ftype _initialize_pa64_solib; /* -Wmissing-prototypes */

void
_initialize_pa64_solib (void)
{
}

void pa64_solib_select (struct gdbarch *gdbarch)
{
  /* For a SOM-only target, there is no pa64 solib support.  This is needed
     for hppa-hpux-tdep.c to build.  */
  error (_("Cannot select pa64 solib support for this configuration."));
}
#endif
