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

   Copyright 1999, 2000, 2001, 2002, 2003, 2004 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 2 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, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.

   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 <dlfcn.h>
#include <elf.h>
#include <elf_hp.h>

#include "defs.h"

#include "frame.h"
#include "bfd.h"
#include "libhppa.h"
#include "gdbcore.h"
#include "symtab.h"
#include "breakpoint.h"
#include "symfile.h"
#include "objfiles.h"
#include "inferior.h"
#include "gdb-stabs.h"
#include "gdb_stat.h"
#include "gdbcmd.h"
#include "language.h"
#include "regcache.h"
#include "exec.h"
#include "hppa-tdep.h"

#include <fcntl.h>

#ifndef O_BINARY
#define O_BINARY 0
#endif

static CORE_ADDR bfd_lookup_symbol (bfd *, char *);
/* This lives in hppa-tdep.c. */
extern struct unwind_table_entry *find_unwind_entry (CORE_ADDR pc);

/* These ought to be defined in some public interface, but aren't.  They
   identify dynamic linker events.  */
#define DLD_CB_LOAD     1
#define DLD_CB_UNLOAD   0

/* A structure to keep track of all the known shared objects.  */
struct so_list
  {
    bfd *abfd;
    char *name;
    struct so_list *next;
    struct objfile *objfile;
    CORE_ADDR pa64_solib_desc_addr;
    struct load_module_desc pa64_solib_desc;
    struct section_table *sections;
    struct section_table *sections_end;
    int loaded;
  };

static struct so_list *so_list_head;

/* This is the cumulative size in bytes of the symbol tables of all
   shared objects on the so_list_head list.  (When we say size, here
   we mean of the information before it is brought into memory and
   potentially expanded by GDB.)  When adding a new shlib, this value
   is compared against a threshold size, held by auto_solib_limit (in
   megabytes).  If adding symbols for the new shlib would cause the
   total size to exceed the threshold, then the new shlib's symbols
   are not loaded. */
static LONGEST pa64_solib_total_st_size;

/* When the threshold is reached for any shlib, we refuse to add
   symbols for subsequent shlibs, even if those shlibs' symbols would
   be small enough to fit under the threshold.  Although this may
   result in one, early large shlib preventing the loading of later,
   smaller shlibs' symbols, it allows us to issue one informational
   message.  The alternative, to issue a message for each shlib whose
   symbols aren't loaded, could be a big annoyance where the threshold
   is exceeded due to a very large number of shlibs. */
static int pa64_solib_st_size_threshold_exceeded;

/* 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 void pa64_sharedlibrary_info_command (char *, int);

static void pa64_solib_sharedlibrary_command (char *, int);

static void *pa64_target_read_memory (void *, CORE_ADDR, size_t, int);

static int read_dld_descriptor (struct target_ops *, int readsyms);

static int read_dynamic_info (asection *, dld_cache_t *);

static void add_to_solist (int, char *, int, struct load_module_desc *,
			   CORE_ADDR, struct target_ops *);

/* When examining the shared library for debugging information we have to
   look for HP debug symbols, stabs and dwarf2 debug symbols.  */
static char *pa64_debug_section_names[] = {
  ".debug_header", ".debug_gntt", ".debug_lntt", ".debug_slt", ".debug_vt",
  ".stabs", ".stabstr", ".debug_info", ".debug_abbrev", ".debug_aranges",
  ".debug_macinfo", ".debug_line", ".debug_loc", ".debug_pubnames",
  ".debug_str", NULL
};

/* Return a ballbark figure for the amount of memory GDB will need to
   allocate to read in the debug symbols from FILENAME.  */
static LONGEST
pa64_solib_sizeof_symbol_table (char *filename)
{
  bfd *abfd;
  int i;
  int desc;
  char *absolute_name;
  LONGEST st_size = (LONGEST) 0;
  asection *sect;

  /* We believe that filename was handed to us by the dynamic linker, and
     is therefore always an absolute path.  */
  desc = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, filename,
		O_RDONLY | O_BINARY, 0, &absolute_name);
  if (desc < 0)
    {
      perror_with_name (filename);
    }
  filename = absolute_name;

  abfd = bfd_fdopenr (filename, gnutarget, desc);
  if (!abfd)
    {
      close (desc);
      make_cleanup (xfree, filename);
      error (_("\"%s\": can't open to read symbols: %s."), filename,
	     bfd_errmsg (bfd_get_error ()));
    }

  if (!bfd_check_format (abfd, bfd_object))
    {
      bfd_close (abfd);
      make_cleanup (xfree, filename);
      error (_("\"%s\": can't read symbols: %s."), filename,
	     bfd_errmsg (bfd_get_error ()));
    }

  /* Sum the sizes of the various sections that compose debug info. */
  for (i = 0; pa64_debug_section_names[i] != NULL; i++)
    {
      asection *sect;

      sect = bfd_get_section_by_name (abfd, pa64_debug_section_names[i]);
      if (sect)
	st_size += (LONGEST)bfd_section_size (abfd, sect);
    }

  bfd_close (abfd);
  xfree (filename);

  /* Unfortunately, just summing the sizes of various debug info
     sections isn't a very accurate measurement of how much heap
     space the debugger will need to hold them.  It also doesn't
     account for space needed by linker (aka "minimal") symbols.

     Anecdotal evidence suggests that just summing the sizes of
     debug-info-related sections understates the heap space needed
     to represent it internally by about an order of magnitude.

     Since it's not exactly brain surgery we're doing here, rather
     than attempt to more accurately measure the size of a shlib's
     symbol table in GDB's heap, we'll just apply a 10x fudge-
     factor to the debug info sections' size-sum.  No, this doesn't
     account for minimal symbols in non-debuggable shlibs.  But it
     all roughly washes out in the end.  */
  return st_size * (LONGEST) 10;
}

/* Add a shared library to the objfile list and load its symbols into
   GDB's symbol table.  */
static void
pa64_solib_add_solib_objfile (struct so_list *so, char *name, int from_tty,
			      CORE_ADDR text_addr)
{
  bfd *tmp_bfd;
  asection *sec;
  struct hppa_objfile_private *obj_private;
  struct section_addr_info *section_addrs;
  struct cleanup *my_cleanups;

  /* We need the BFD so that we can look at its sections.  We open up the
     file temporarily, then close it when we are done.  */
  tmp_bfd = bfd_openr (name, gnutarget);
  if (tmp_bfd == NULL)
    {
      perror_with_name (name);
      return;
    }

  if (!bfd_check_format (tmp_bfd, bfd_object))
    {
      bfd_close (tmp_bfd);
      error (_("\"%s\" is not an object file: %s"), name,
	     bfd_errmsg (bfd_get_error ()));
    }


  /* Undo some braindamage from symfile.c.

     First, symfile.c will subtract the VMA of the first .text section
     in the shared library that it finds.  Undo that.  */
  sec = bfd_get_section_by_name (tmp_bfd, ".text");
  text_addr += bfd_section_vma (tmp_bfd, sec);

  /* Now find the true lowest section in the shared library.  */
  sec = NULL;
  bfd_map_over_sections (tmp_bfd, find_lowest_section, &sec);

  if (sec)
    {
      /* Subtract out the VMA of the lowest section.  */
      text_addr -= bfd_section_vma (tmp_bfd, sec);

      /* ??? Add back in the filepos of that lowest section. */
      text_addr += sec->filepos;
    }

  section_addrs = alloc_section_addr_info (bfd_count_sections (tmp_bfd));
  my_cleanups = make_cleanup (xfree, section_addrs);

  /* We are done with the temporary bfd.  Get rid of it and make sure
     nobody else can us it.  */
  bfd_close (tmp_bfd);
  tmp_bfd = NULL;

  /* Now let the generic code load up symbols for this library.  */
  section_addrs->other[0].addr = text_addr;
  section_addrs->other[0].name = ".text";
  so->objfile = symbol_file_add (name, from_tty, section_addrs, 0, OBJF_SHARED);
  so->abfd = so->objfile->obfd;

  /* Mark this as a shared library and save private data.  */
  so->objfile->flags |= OBJF_SHARED;

  obj_private = (struct hppa_objfile_private *)
	        objfile_data (so->objfile, hppa_objfile_priv_data);
  if (obj_private == NULL)
    {
      obj_private = (struct hppa_objfile_private *)
	obstack_alloc (&so->objfile->objfile_obstack,
		       sizeof (struct hppa_objfile_private));
      set_objfile_data (so->objfile, hppa_objfile_priv_data, obj_private);
      obj_private->unwind_info = NULL;
      obj_private->so_info = NULL;
    }

  obj_private->so_info = so;
  obj_private->dp = so->pa64_solib_desc.linkage_ptr;
  do_cleanups (my_cleanups);
}

/* Load debugging information for a shared library.  TARGET may be
   NULL if we are not attaching to a process or reading a core file.  */

static void
pa64_solib_load_symbols (struct so_list *so, char *name, int from_tty,
			 CORE_ADDR text_addr, struct target_ops *target)
{
  struct section_table *p;
  asection *sec;
  int status;
  char buf[4];
  CORE_ADDR presumed_data_start;

  if (text_addr == 0)
    text_addr = so->pa64_solib_desc.text_base;

  pa64_solib_add_solib_objfile (so, name, from_tty, text_addr);

  /* Now we need to build a section table for this library since
     we might be debugging a core file from a dynamically linked
     executable in which the libraries were not privately mapped.  */
  if (build_section_table (so->abfd,
			   &so->sections,
			   &so->sections_end))
    {
      error (_("Unable to build section table for shared library\n."));
      return;
    }

  (so->objfile->section_offsets)->offsets[SECT_OFF_TEXT (so->objfile)]
    = so->pa64_solib_desc.text_base;
  (so->objfile->section_offsets)->offsets[SECT_OFF_DATA (so->objfile)]
    = so->pa64_solib_desc.data_base;

  /* Relocate all the sections based on where they got loaded.  */
  for (p = so->sections; p < so->sections_end; p++)
    {
      if (p->the_bfd_section->flags & SEC_CODE)
	{
	  p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT (so->objfile));
	  p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT (so->objfile));
	}
      else if (p->the_bfd_section->flags & SEC_DATA)
	{
	  p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA (so->objfile));
	  p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA (so->objfile));
	}
    }

  /* Now see if we need to map in the text and data for this shared
     library (for example debugging a core file which does not use
     private shared libraries.). 

     Carefully peek at the first text address in the library.  If the
     read succeeds, then the libraries were privately mapped and were
     included in the core dump file.

     If the peek failed, then the libraries were not privately mapped
     and are not in the core file, we'll have to read them in ourselves.  */
  status = target_read_memory (text_addr, buf, 4);
  if (status != 0)
    {
      int new, old;
      
      new = so->sections_end - so->sections;

      old = target_resize_to_sections (target, new);
      
      /* Copy over the old data before it gets clobbered.  */
      memcpy ((char *) (target->to_sections + old),
	      so->sections,
	      ((sizeof (struct section_table)) * new));
    }
}


/* Add symbols from shared libraries into the symtab list, unless the
   size threshold specified by auto_solib_limit (in megabytes) would
   be exceeded.  */

void
pa64_solib_add (char *arg_string, int from_tty, struct target_ops *target, int readsyms)
{
  struct minimal_symbol *msymbol;
  CORE_ADDR addr;
  asection *shlib_info;
  int status;
  unsigned int dld_flags;
  char buf[4], *re_err;
  int threshold_warning_given = 0;
  int dll_index;
  struct load_module_desc dll_desc;
  char *dll_path;

  /* First validate our arguments.  */
  if ((re_err = re_comp (arg_string ? arg_string : ".")) != NULL)
    {
      error (_("Invalid regexp: %s"), re_err);
    }

  /* If we're debugging a core file, or have attached to a running
     process, then pa64_solib_create_inferior_hook will not have been
     called.

     We need to first determine if we're dealing with a dynamically
     linked executable.  If not, then return without an error or warning.

     We also need to examine __dld_flags to determine if the shared
     library list is valid and to determine if the libraries have been
     privately mapped.  */
  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 load map pointer if we have not done so already.  */
  if (! dld_cache.have_read_dld_descriptor)
    if (! read_dld_descriptor (target, readsyms))
      return;

  /* If the libraries were not mapped private, warn the user.  */
  if ((dld_cache.dld_flags & DT_HP_DEBUG_PRIVATE) == 0)
    warning (_("\
The shared libraries were not privately mapped; setting a\n\
breakpoint in a shared library will not work until you rerun the program."));

  /* For each shaerd library, add it to the shared library list.  */
  for (dll_index = 1; ; dll_index++)
    {
      /* 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)
	return;

      /* 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);

      if (!dll_path)
	error (_("pa64_solib_add, unable to read shared library path."));

      add_to_solist (from_tty, dll_path, readsyms, &dll_desc, 0, target);
    }
}


/* 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 two flag bits in this routine.

     DT_HP_DEBUG_PRIVATE to indicate that shared libraries should be
     mapped private.

     DT_HP_DEBUG_CALLBACK to indicate that we want the dynamic linker
     to call the breakpoint routine for significant events.  */

void
pa64_solib_create_inferior_hook (void)
{
  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."));

  /* Turn on the flags we care about.  */
  dld_cache.dld_flags |= DT_HP_DEBUG_PRIVATE;
  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)
	goto get_out;

      /* 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);
	  goto get_out;
	}

      /* 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 = read_pc () - 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 (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);
    }

get_out:
  /* Wipe out all knowledge of old shared libraries since their
     mapping can change from one exec to another!  */
  while (so_list_head)
    {
      struct so_list *temp;

      temp = so_list_head;
      xfree (so_list_head);
      so_list_head = temp->next;
    }
  clear_symtab_users ();
}

/* This operation removes the "hook" between GDB and the dynamic linker,
   which causes the dld to notify GDB of shared library events.

   After this operation completes, the dld will no longer notify GDB of
   shared library events.  To resume notifications, GDB must call
   pa64_solib_create_inferior_hook.

   This operation does not remove any knowledge of shared libraries
   of which GDB may already have been notified.  */

void
pa64_solib_remove_inferior_hook (int pid)
{
  /* Turn off the DT_HP_DEBUG_CALLBACK bit in the dynamic linker flags.  */
  dld_cache.dld_flags &= ~DT_HP_DEBUG_CALLBACK;
  target_write_memory (dld_cache.dld_flags_addr,
		       (char *)&dld_cache.dld_flags,
		       sizeof (dld_cache.dld_flags));
}

/* This function creates a breakpoint on the dynamic linker hook, which
   is called when e.g., a shl_load or shl_unload call is made.  This
   breakpoint will only trigger when a shl_load call is made.

   If filename is NULL, then loads of any dll will be caught.  Else,
   only loads of the file whose pathname is the string contained by
   filename will be caught.

   Undefined behaviour is guaranteed if this function is called before
   pa64_solib_create_inferior_hook.  */

void
pa64_solib_create_catch_load_hook (int pid, int tempflag, char *filename,
				   char *cond_string)
{
  create_solib_load_event_breakpoint ("", tempflag, filename, cond_string);
}

/* This function creates a breakpoint on the dynamic linker hook, which
   is called when e.g., a shl_load or shl_unload call is made.  This
   breakpoint will only trigger when a shl_unload call is made.

   If filename is NULL, then unloads of any dll will be caught.  Else,
   only unloads of the file whose pathname is the string contained by
   filename will be caught.

   Undefined behaviour is guaranteed if this function is called before
   pa64_solib_create_inferior_hook.  */

void
pa64_solib_create_catch_unload_hook (int pid, int tempflag, char *filename,
				     char *cond_string)
{
  create_solib_unload_event_breakpoint ("", tempflag, filename, cond_string);
}

/* Return nonzero if the dynamic linker has reproted that a library
   has been loaded.  */

int
pa64_solib_have_load_event (int pid)
{
  CORE_ADDR event_kind;

  event_kind = read_register (HPPA_ARG0_REGNUM);
  return (event_kind == DLD_CB_LOAD);
}

/* Return nonzero if the dynamic linker has reproted that a library
   has been unloaded.  */
int
pa64_solib_have_unload_event (int pid)
{
  CORE_ADDR event_kind;

  event_kind = read_register (HPPA_ARG0_REGNUM);
  return (event_kind == DLD_CB_UNLOAD);
}

/* Return a pointer to a string indicating the pathname of the most
   recently loaded library.

   The caller is reposible for copying the string before the inferior is
   restarted.  */

char *
pa64_solib_loaded_library_pathname (int pid)
{
  static char dll_path[MAXPATHLEN];
  CORE_ADDR  dll_path_addr = read_register (HPPA_ARG3_REGNUM);
  read_memory_string (dll_path_addr, dll_path, MAXPATHLEN);
  return dll_path;
}

/* Return a pointer to a string indicating the pathname of the most
   recently unloaded library.

   The caller is reposible for copying the string before the inferior is
   restarted.  */

char *
pa64_solib_unloaded_library_pathname (int pid)
{
  static char dll_path[MAXPATHLEN];
  CORE_ADDR dll_path_addr = read_register (HPPA_ARG3_REGNUM);
  read_memory_string (dll_path_addr, dll_path, MAXPATHLEN);
  return dll_path;
}

/* Return nonzero if PC is an address inside the dynamic linker.  */

int
pa64_solib_in_dynamic_linker (int pid, CORE_ADDR pc)
{
  asection *shlib_info;

  if (symfile_objfile == NULL)
    return 0;

  if (!dld_cache.have_read_dld_descriptor)
    if (!read_dld_descriptor (&current_target, auto_solib_add))
      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.  */

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

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

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

   This function is used in hppa_fix_call_dummy in hppa-tdep.c.  */

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

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

/* Dump information about all the currently loaded shared libraries.  */

static void
pa64_sharedlibrary_info_command (char *ignore, int from_tty)
{
  struct so_list *so_list = so_list_head;

  if (exec_bfd == NULL)
    {
      printf_unfiltered ("No executable file.\n");
      return;
    }

  if (so_list == NULL)
    {
      printf_unfiltered ("No shared libraries loaded at this time.\n");
      return;
    }

  printf_unfiltered ("Shared Object Libraries\n");
  printf_unfiltered ("   %-19s%-19s%-19s%-19s\n",
		     "  text start", "   text end",
		     "  data start", "   data end");
  while (so_list)
    {
      unsigned int flags;

      printf_unfiltered ("%s", so_list->name);
      if (so_list->objfile == NULL)
	printf_unfiltered ("  (symbols not loaded)");
      if (so_list->loaded == 0)
	printf_unfiltered ("  (shared library unloaded)");
      printf_unfiltered ("  %-18s",
	hex_string_custom (so_list->pa64_solib_desc.linkage_ptr, 16));
      printf_unfiltered ("\n");
      printf_unfiltered ("%-18s",
	hex_string_custom (so_list->pa64_solib_desc.text_base, 16));
      printf_unfiltered (" %-18s",
	hex_string_custom ((so_list->pa64_solib_desc.text_base
			    + so_list->pa64_solib_desc.text_size), 16));
      printf_unfiltered (" %-18s",
	hex_string_custom (so_list->pa64_solib_desc.data_base, 16));
      printf_unfiltered (" %-18s\n",
	hex_string_custom ((so_list->pa64_solib_desc.data_base
			    + so_list->pa64_solib_desc.data_size), 16));
      so_list = so_list->next;
    }
}

/* Load up one or more shared libraries as directed by the user.  */

static void
pa64_solib_sharedlibrary_command (char *args, int from_tty)
{
  dont_repeat ();
  pa64_solib_add (args, from_tty, (struct target_ops *) 0, 1);
}

/* Return the name of the shared library containing ADDR or NULL if ADDR
   is not contained in any known shared library.  */

char *
pa64_solib_address (CORE_ADDR addr)
{
  struct so_list *so = so_list_head;

  while (so)
    {
      /* Is this address within this shlib's text range?  If so,
	 return the shlib's name.  */
      if (addr >= so->pa64_solib_desc.text_base
	  && addr < (so->pa64_solib_desc.text_base
		     | so->pa64_solib_desc.text_size))
	return so->name;

      /* Nope, keep looking... */
      so = so->next;
    }

  /* No, we couldn't prove that the address is within a shlib. */
  return NULL;
}

/* We are killing the inferior and restarting the program.  */

void
pa64_solib_restart (void)
{
  struct so_list *sl = so_list_head;

  /* Before the shlib info vanishes, use it to disable any breakpoints
     that may still be active in those shlibs.  */
  disable_breakpoints_in_shlibs (0);

  /* Discard all the shlib descriptors.  */
  while (sl)
    {
      struct so_list *next_sl = sl->next;
      xfree (sl);
      sl = next_sl;
    }
  so_list_head = NULL;

  pa64_solib_total_st_size = (LONGEST) 0;
  pa64_solib_st_size_threshold_exceeded = 0;

  dld_cache.is_valid = 0;
  dld_cache.have_read_dld_descriptor = 0;
  dld_cache.dld_flags_addr = 0;
  dld_cache.load_map = 0;
  dld_cache.load_map_addr = 0;
  dld_cache.dld_desc.data_base = 0;
  dld_cache.dld_flags = 0;
  dld_cache.dyninfo_sect = 0;
}

void
_initialize_pa64_solib (void)
{
  add_com ("sharedlibrary", class_files, pa64_solib_sharedlibrary_command,
	   _("Load shared object library symbols for files matching REGEXP."));
  add_info ("sharedlibrary", pa64_sharedlibrary_info_command,
	    _("Status of loaded shared object libraries."));

  add_setshow_boolean_cmd ("auto-solib-add", class_support,
			   &auto_solib_add, _("\
Set autoloading of shared library symbols."), _("\
Show autoloading of shared library symbols."), _("\
If \"on\", symbols from all shared object libraries will be loaded\n\
automatically when the inferior begins execution, when the dynamic linker\n\
informs gdb that a new library has been loaded, or when attaching to the\n\
inferior.  Otherwise, symbols must be loaded manually, using `sharedlibrary'."),
			   NULL,
			   NULL, /* FIXME: i18n: */
			   &setlist, &showlist);

  add_setshow_zinteger_cmd ("auto-solib-limit", class_support,
			    &auto_solib_limit, _("\
Set threshold (in Mb) for autoloading shared library symbols."), _("\
Show threshold (in Mb) for autoloading shared library symbols."), _("\
When shared library autoloading is enabled, new libraries will be loaded\n\
only until the total size of shared library symbols exceeds this\n\
threshold in megabytes.  Is ignored when using `sharedlibrary'."),
			    NULL,
			    NULL, /* FIXME: i18n: */
			    &setlist, &showlist);

  /* ??rehrauer: On HP-UX, the kernel parameter MAXDSIZ limits how
     much data space a process can use.  We ought to be reading
     MAXDSIZ and setting auto_solib_limit to some large fraction of
     that value.  If not that, we maybe ought to be setting it smaller
     than the default for MAXDSIZ (that being 64Mb, I believe).
     However, [1] this threshold is only crudely approximated rather
     than actually measured, and [2] 50 Mbytes is too small for
     debugging gdb itself.  Thus, the arbitrary 100 figure.  */
  auto_solib_limit = 100;	/* Megabytes */

  pa64_solib_restart ();
}

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

/* 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, then return zero, else
   return nonzero.  */

static int
read_dld_descriptor (struct target_ops *target, int readsyms)
{
  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."));
    }

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

  /* Add dld.sl to the list of known shared libraries so that we can
     do unwind, etc. 

     ?!? This may not be correct.  Consider of dld.sl contains symbols
     which are also referenced/defined by the user program or some user
     shared library.  We need to make absolutely sure that we do not
     pollute the namespace from GDB's point of view.  */
  dll_path = dlgetname (&dld_cache.dld_desc, 
			sizeof(dld_cache.dld_desc), 
			pa64_target_read_memory, 
			0, 
			dld_cache.load_map);
  add_to_solist(0, dll_path, readsyms, &dld_cache.dld_desc, 0, target);
  
  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;
      char *pbuf;

      pbuf = alloca (TARGET_PTR_BIT / HOST_CHAR_BIT);
      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;
}

/* Wrapper for target_read_memory to make dlgetmodinfo happy.  */

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;
}

/* Called from handle_dynlink_load_event and pa64_solib_add to add
   a shared library to so_list_head list and possibly to read in the
   debug information for the library.  

   If load_module_desc_p is NULL, then the load module descriptor must
   be read from the inferior process at the address load_module_desc_addr.  */

static void
add_to_solist (int from_tty, char *dll_path, int readsyms,
	       struct load_module_desc *load_module_desc_p,
	       CORE_ADDR load_module_desc_addr, struct target_ops *target)
{
  struct so_list *new_so, *so_list_tail;
  int pa64_solib_st_size_threshhold_exceeded;
  LONGEST st_size;

  if (symfile_objfile == NULL)
    return;

  so_list_tail = so_list_head;
  /* Find the end of the list of shared objects.  */
  while (so_list_tail && so_list_tail->next)
    {
      if (strcmp (so_list_tail->name, dll_path) == 0)
	return;
      so_list_tail = so_list_tail->next;
    }

  if (so_list_tail && strcmp (so_list_tail->name, dll_path) == 0)
    return;

  /* Add the shared library to the so_list_head list */
  new_so = (struct so_list *) xmalloc (sizeof (struct so_list));
  memset ((char *)new_so, 0, sizeof (struct so_list));
  if (so_list_head == NULL)
    {
      so_list_head = new_so;
      so_list_tail = new_so;
    }
  else
    {
      so_list_tail->next = new_so;
      so_list_tail = new_so;
    }

  /* Initialize the new_so */
  if (load_module_desc_p)
    {
      new_so->pa64_solib_desc = *load_module_desc_p;
    }
  else
    {
      if (target_read_memory (load_module_desc_addr, 
			      (char*) &new_so->pa64_solib_desc,
			      sizeof(struct load_module_desc))
	  != 0)
      {
	error (_("Error while reading in dynamic library %s"), dll_path);
      }
    }
  
  new_so->pa64_solib_desc_addr = load_module_desc_addr;
  new_so->loaded = 1;
  new_so->name = obsavestring (dll_path, strlen(dll_path),
			       &symfile_objfile->objfile_obstack);

  /* If we are not going to load the library, tell the user if we
     haven't already and return.  */

  st_size = pa64_solib_sizeof_symbol_table (dll_path);
  pa64_solib_st_size_threshhold_exceeded =
       !from_tty 
    && readsyms
    && (  (st_size + pa64_solib_total_st_size) 
	> (auto_solib_limit * (LONGEST) (1024 * 1024)));
  if (pa64_solib_st_size_threshhold_exceeded)
    {
      pa64_solib_add_solib_objfile (new_so, dll_path, from_tty, 1);
      return;
    } 

  /* Now read in debug info. */
  pa64_solib_total_st_size += st_size;

  /* This fills in new_so->objfile, among others. */
  pa64_solib_load_symbols (new_so, 
			   dll_path,
			   from_tty, 
			   0,
			   target);
  return;
}


/*
   LOCAL FUNCTION

   bfd_lookup_symbol -- lookup the value for a specific symbol

   SYNOPSIS

   CORE_ADDR bfd_lookup_symbol (bfd *abfd, char *symname)

   DESCRIPTION

   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);
}

