/* Handle SOM shared libraries.

   Copyright (C) 2004-2015 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 "symtab.h"
#include "bfd.h"
#include "symfile.h"
#include "objfiles.h"
#include "gdbcore.h"
#include "target.h"
#include "inferior.h"

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

#undef SOLIB_SOM_DBG 

/* These ought to be defined in some public interface, but aren't.  They
   define the meaning of the various bits in the distinguished __dld_flags
   variable that is declared in every debuggable a.out on HP-UX, and that
   is shared between the debugger and the dynamic linker.  */

#define DLD_FLAGS_MAPPRIVATE    0x1
#define DLD_FLAGS_HOOKVALID     0x2
#define DLD_FLAGS_LISTVALID     0x4
#define DLD_FLAGS_BOR_ENABLE    0x8

struct lm_info
  {
    /* Version of this structure (it is expected to change again in
       hpux10).  */
    unsigned char struct_version;

    /* Binding mode for this library.  */
    unsigned char bind_mode;

    /* Version of this library.  */
    short library_version;

    /* Start of text address,
       link-time text location (length of text area),
       end of text address.  */
    CORE_ADDR text_addr;
    CORE_ADDR text_link_addr;
    CORE_ADDR text_end;

    /* Start of data, start of bss and end of data.  */
    CORE_ADDR data_start;
    CORE_ADDR bss_start;
    CORE_ADDR data_end;

    /* Value of linkage pointer (%r19).  */
    CORE_ADDR got_value;

    /* Address in target of offset from thread-local register of
       start of this thread's data.  I.e., the first thread-local
       variable in this shared library starts at *(tsd_start_addr)
       from that area pointed to by cr27 (mpsfu_hi).
      
       We do the indirection as soon as we read it, so from then
       on it's the offset itself.  */
    CORE_ADDR tsd_start_addr;

    /* Address of the link map entry in the loader.  */
    CORE_ADDR lm_addr;
  };

/* These addresses should be filled in by som_solib_create_inferior_hook.
   They are also used elsewhere in this module.  */

typedef struct
  {
    CORE_ADDR address;
    struct unwind_table_entry *unwind;
  }
addr_and_unwind_t;

/* When adding fields, be sure to clear them in _initialize_som_solib.  */
static struct
  {
    int is_valid;
    addr_and_unwind_t hook;
    addr_and_unwind_t hook_stub;
    addr_and_unwind_t load;
    addr_and_unwind_t load_stub;
    addr_and_unwind_t unload;
    addr_and_unwind_t unload2;
    addr_and_unwind_t unload_stub;
  }
dld_cache;

static void
som_relocate_section_addresses (struct so_list *so,
				struct target_section *sec)
{
  flagword aflag = bfd_get_section_flags(so->abfd, sec->the_bfd_section);

  if (aflag & SEC_CODE)
    {
      sec->addr    += so->lm_info->text_addr - so->lm_info->text_link_addr; 
      sec->endaddr += so->lm_info->text_addr - so->lm_info->text_link_addr;
    }
  else if (aflag & SEC_DATA)
    {
      sec->addr    += so->lm_info->data_start; 
      sec->endaddr += so->lm_info->data_start;
    }
  else
    {
      /* Nothing.  */
    }
}


/* Variable storing HP-UX major release number.

   On non-native system, simply assume that the major release number
   is 11.  On native systems, hppa-hpux-nat.c initialization code
   sets this number to the real one on startup.
   
   We cannot compute this value here, because we need to make a native
   call to "uname".  We are are not allowed to do that from here, as
   this file is used for both native and cross debugging.  */

#define DEFAULT_HPUX_MAJOR_RELEASE 11
int hpux_major_release = DEFAULT_HPUX_MAJOR_RELEASE;

static int
get_hpux_major_release (void)
{
  return hpux_major_release;
}

/* DL header flag defines.  */
#define SHLIB_TEXT_PRIVATE_ENABLE 0x4000

/* The DL header is documented in <shl.h>.  We are only interested
   in the flags field to determine whether the executable wants shared
   libraries mapped private.  */
struct {
    short junk[37];
    short flags;
} dl_header;

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

   __dld_flags is the location of the magic flags; as of this implementation
   there are 3 flags of interest:

   bit 0 when set indicates that private copies of the libraries are needed
   bit 1 when set indicates that the callback hook routine is valid
   bit 2 when set indicates that the dynamic linker should maintain the
   __dld_list structure when loading/unloading libraries.

   Note that shared libraries are not mapped in at this time, so we have
   run the inferior until the libraries are mapped in.  Typically this
   means running until the "_start" is called.  */

static void
som_solib_create_inferior_hook (int from_tty)
{
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
  struct bound_minimal_symbol msymbol;
  unsigned int dld_flags, status, have_endo;
  asection *shlib_info;
  gdb_byte buf[4];
  CORE_ADDR anaddr;

  if (symfile_objfile == NULL)
    return;

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

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

  /* Read the DL header.  */
  bfd_get_section_contents (symfile_objfile->obfd, shlib_info,
			    (char *) &dl_header, 0, sizeof (dl_header));

  have_endo = 0;
  /* Slam the pid of the process into __d_pid.

     We used to warn when this failed, but that warning is only useful
     on very old HP systems (hpux9 and older).  The warnings are an
     annoyance to users of modern systems and foul up the testsuite as
     well.  As a result, the warnings have been disabled.  */
  msymbol = lookup_minimal_symbol ("__d_pid", NULL, symfile_objfile);
  if (msymbol.minsym == NULL)
    goto keep_going;

  anaddr = BMSYMBOL_VALUE_ADDRESS (msymbol);
  store_unsigned_integer (buf, 4, byte_order, ptid_get_pid (inferior_ptid));
  status = target_write_memory (anaddr, buf, 4);
  if (status != 0)
    {
      warning (_("\
Unable to write __d_pid.\n\
Suggest linking with /opt/langtools/lib/end.o.\n\
GDB will be unable to track shl_load/shl_unload calls"));
      goto keep_going;
    }

  /* Get the value of _DLD_HOOK (an export stub) and put it in __dld_hook;
     This will force the dynamic linker to call __d_trap when significant
     events occur.

     Note that the above is the pre-HP-UX 9.0 behaviour.  At 9.0 and above,
     the dld provides an export stub named "__d_trap" as well as the
     function named "__d_trap" itself, but doesn't provide "_DLD_HOOK".
     We'll look first for the old flavor and then the new.  */

  msymbol = lookup_minimal_symbol ("_DLD_HOOK", NULL, symfile_objfile);
  if (msymbol.minsym == NULL)
    msymbol = lookup_minimal_symbol ("__d_trap", NULL, symfile_objfile);
  if (msymbol.minsym == NULL)
    {
      warning (_("\
Unable to find _DLD_HOOK symbol in object file.\n\
Suggest linking with /opt/langtools/lib/end.o.\n\
GDB will be unable to track shl_load/shl_unload calls"));
      goto keep_going;
    }
  anaddr = BMSYMBOL_VALUE_ADDRESS (msymbol);
  dld_cache.hook.address = anaddr;

  /* Grrr, this might not be an export symbol!  We have to find the
     export stub.  */
  msymbol
    = hppa_lookup_stub_minimal_symbol (MSYMBOL_LINKAGE_NAME (msymbol.minsym),
				       EXPORT);
  if (msymbol.minsym != NULL)
    {
      anaddr = MSYMBOL_VALUE (msymbol.minsym);
      dld_cache.hook_stub.address = anaddr;
    }
  store_unsigned_integer (buf, 4, byte_order, anaddr);

  msymbol = lookup_minimal_symbol ("__dld_hook", NULL, symfile_objfile);
  if (msymbol.minsym == NULL)
    {
      warning (_("\
Unable to find __dld_hook symbol in object file.\n\
Suggest linking with /opt/langtools/lib/end.o.\n\
GDB will be unable to track shl_load/shl_unload calls"));
      goto keep_going;
    }
  anaddr = BMSYMBOL_VALUE_ADDRESS (msymbol);
  status = target_write_memory (anaddr, buf, 4);

  /* Now set a shlib_event breakpoint at __d_trap so we can track
     significant shared library events.  */
  msymbol = lookup_minimal_symbol ("__d_trap", NULL, symfile_objfile);
  if (msymbol.minsym == NULL)
    {
      warning (_("\
Unable to find __dld_d_trap symbol in object file.\n\
Suggest linking with /opt/langtools/lib/end.o.\n\
GDB will be unable to track shl_load/shl_unload calls"));
      goto keep_going;
    }
  create_solib_event_breakpoint (target_gdbarch (),
				 BMSYMBOL_VALUE_ADDRESS (msymbol));

  /* We have all the support usually found in end.o, so we can track
     shl_load and shl_unload calls.  */
  have_endo = 1;

keep_going:

  /* Get the address of __dld_flags, if no such symbol exists, then we can
     not debug the shared code.  */
  msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
  if (msymbol.minsym == NULL)
    {
      error (_("Unable to find __dld_flags symbol in object file."));
    }

  anaddr = BMSYMBOL_VALUE_ADDRESS (msymbol);

  /* Read the current contents.  */
  status = target_read_memory (anaddr, buf, 4);
  if (status != 0)
    error (_("Unable to read __dld_flags."));
  dld_flags = extract_unsigned_integer (buf, 4, byte_order);

  /* If the libraries were not mapped private on HP-UX 11 and later, warn
     the user.  On HP-UX 10 and earlier, there is no easy way to specify
     that shared libraries should be privately mapped.  So, we just force
     private mapping.  */
  if (get_hpux_major_release () >= 11
      && (dl_header.flags & SHLIB_TEXT_PRIVATE_ENABLE) == 0
      && (dld_flags & DLD_FLAGS_MAPPRIVATE) == 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.  */
  if (get_hpux_major_release () < 11)
    dld_flags |= DLD_FLAGS_MAPPRIVATE;
  if (have_endo)
    dld_flags |= DLD_FLAGS_HOOKVALID;
  store_unsigned_integer (buf, 4, byte_order, dld_flags);
  status = target_write_memory (anaddr, buf, 4);
  if (status != 0)
    error (_("Unable to write __dld_flags."));

  /* Now find the address of _start and set a breakpoint there.
     We still need this code for two reasons:

     * Not all sites have /opt/langtools/lib/end.o, so it's not always
     possible to track the dynamic linker's events.

     * At this time no events are triggered for shared libraries
     loaded at startup time (what a crock).  */

  msymbol = lookup_minimal_symbol ("_start", NULL, symfile_objfile);
  if (msymbol.minsym == NULL)
    error (_("Unable to find _start symbol in object file."));

  anaddr = BMSYMBOL_VALUE_ADDRESS (msymbol);

  /* Make the breakpoint at "_start" a shared library event breakpoint.  */
  create_solib_event_breakpoint (target_gdbarch (), anaddr);

  clear_symtab_users (0);
}

static void
som_special_symbol_handling (void)
{
}

static void
som_solib_desire_dynamic_linker_symbols (void)
{
  struct objfile *objfile;
  struct unwind_table_entry *u;
  struct bound_minimal_symbol dld_msymbol;

  /* Do we already know the value of these symbols?  If so, then
     we've no work to do.

     (If you add clauses to this test, be sure to likewise update the
     test within the loop.)  */

  if (dld_cache.is_valid)
    return;

  ALL_OBJFILES (objfile)
  {
    dld_msymbol = lookup_minimal_symbol ("shl_load", NULL, objfile);
    if (dld_msymbol.minsym != NULL)
      {
	dld_cache.load.address = MSYMBOL_VALUE (dld_msymbol.minsym);
	dld_cache.load.unwind = find_unwind_entry (dld_cache.load.address);
      }

    dld_msymbol = lookup_minimal_symbol_solib_trampoline ("shl_load",
							  objfile);
    if (dld_msymbol.minsym != NULL)
      {
	if (MSYMBOL_TYPE (dld_msymbol.minsym) == mst_solib_trampoline)
	  {
	    u = find_unwind_entry (MSYMBOL_VALUE (dld_msymbol.minsym));
	    if ((u != NULL) && (u->stub_unwind.stub_type == EXPORT))
	      {
		dld_cache.load_stub.address
		  = MSYMBOL_VALUE (dld_msymbol.minsym);
		dld_cache.load_stub.unwind = u;
	      }
	  }
      }

    dld_msymbol = lookup_minimal_symbol ("shl_unload", NULL, objfile);
    if (dld_msymbol.minsym != NULL)
      {
	dld_cache.unload.address = MSYMBOL_VALUE (dld_msymbol.minsym);
	dld_cache.unload.unwind = find_unwind_entry (dld_cache.unload.address);

	/* ??rehrauer: I'm not sure exactly what this is, but it appears
	   that on some HPUX 10.x versions, there's two unwind regions to
	   cover the body of "shl_unload", the second being 4 bytes past
	   the end of the first.  This is a large hack to handle that
	   case, but since I don't seem to have any legitimate way to
	   look for this thing via the symbol table...  */

	if (dld_cache.unload.unwind != NULL)
	  {
	    u = find_unwind_entry (dld_cache.unload.unwind->region_end + 4);
	    if (u != NULL)
	      {
		dld_cache.unload2.address = u->region_start;
		dld_cache.unload2.unwind = u;
	      }
	  }
      }

    dld_msymbol = lookup_minimal_symbol_solib_trampoline ("shl_unload",
							  objfile);
    if (dld_msymbol.minsym != NULL)
      {
	if (MSYMBOL_TYPE (dld_msymbol.minsym) == mst_solib_trampoline)
	  {
	    u = find_unwind_entry (MSYMBOL_VALUE (dld_msymbol.minsym));
	    if ((u != NULL) && (u->stub_unwind.stub_type == EXPORT))
	      {
		dld_cache.unload_stub.address
		  = MSYMBOL_VALUE (dld_msymbol.minsym);
		dld_cache.unload_stub.unwind = u;
	      }
	  }
      }

    /* Did we find everything we were looking for?  If so, stop.  */
    if ((dld_cache.load.address != 0)
	&& (dld_cache.load_stub.address != 0)
	&& (dld_cache.unload.address != 0)
	&& (dld_cache.unload_stub.address != 0))
      {
	dld_cache.is_valid = 1;
	break;
      }
  }

  dld_cache.hook.unwind = find_unwind_entry (dld_cache.hook.address);
  dld_cache.hook_stub.unwind = find_unwind_entry (dld_cache.hook_stub.address);

  /* We're prepared not to find some of these symbols, which is why
     this function is a "desire" operation, and not a "require".  */
}

static int
som_in_dynsym_resolve_code (CORE_ADDR pc)
{
  struct unwind_table_entry *u_pc;

  /* Are we in the dld itself?

     ??rehrauer: Large hack -- We'll assume that any address in a
     shared text region is the dld's text.  This would obviously
     fall down if the user attached to a process, whose shlibs
     weren't mapped to a (writeable) private region.  However, in
     that case the debugger probably isn't able to set the fundamental
     breakpoint in the dld callback anyways, so this hack should be
     safe.  */

  if ((pc & (CORE_ADDR) 0xc0000000) == (CORE_ADDR) 0xc0000000)
    return 1;

  /* Cache the address of some symbols that are part of the dynamic
     linker, if not already known.  */

  som_solib_desire_dynamic_linker_symbols ();

  /* Are we in the dld callback?  Or its export stub?  */
  u_pc = find_unwind_entry (pc);
  if (u_pc == NULL)
    return 0;

  if ((u_pc == dld_cache.hook.unwind) || (u_pc == dld_cache.hook_stub.unwind))
    return 1;

  /* Or the interface of the dld (i.e., "shl_load" or friends)?  */
  if ((u_pc == dld_cache.load.unwind)
      || (u_pc == dld_cache.unload.unwind)
      || (u_pc == dld_cache.unload2.unwind)
      || (u_pc == dld_cache.load_stub.unwind)
      || (u_pc == dld_cache.unload_stub.unwind))
    return 1;

  /* Apparently this address isn't part of the dld's text.  */
  return 0;
}

static void
som_clear_solib (void)
{
}

struct dld_list {
  char name[4];
  char info[4];
  char text_addr[4];
  char text_link_addr[4];
  char text_end[4];
  char data_start[4];
  char bss_start[4];
  char data_end[4];
  char got_value[4];
  char next[4];
  char tsd_start_addr_ptr[4];
};

static CORE_ADDR
link_map_start (void)
{
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
  struct bound_minimal_symbol sym;
  CORE_ADDR addr;
  gdb_byte buf[4];
  unsigned int dld_flags;

  sym = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
  if (!sym.minsym)
    error (_("Unable to find __dld_flags symbol in object file."));
  addr = BMSYMBOL_VALUE_ADDRESS (sym);
  read_memory (addr, buf, 4);
  dld_flags = extract_unsigned_integer (buf, 4, byte_order);
  if ((dld_flags & DLD_FLAGS_LISTVALID) == 0)
    error (_("__dld_list is not valid according to __dld_flags."));

  sym = lookup_minimal_symbol ("__dld_list", NULL, NULL);
  if (!sym.minsym)
    {
      /* Older crt0.o files (hpux8) don't have __dld_list as a symbol,
         but the data is still available if you know where to look.  */
      sym = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
      if (!sym.minsym)
	{
	  error (_("Unable to find dynamic library list."));
	  return 0;
	}
      addr = BMSYMBOL_VALUE_ADDRESS (sym) - 8;
    }
  else
    addr = BMSYMBOL_VALUE_ADDRESS (sym);

  read_memory (addr, buf, 4);
  addr = extract_unsigned_integer (buf, 4, byte_order);
  if (addr == 0)
    return 0;

  read_memory (addr, buf, 4);
  return extract_unsigned_integer (buf, 4, byte_order);
}

/* Does this so's name match the main binary?  */
static int
match_main (const char *name)
{
  return strcmp (name, objfile_name (symfile_objfile)) == 0;
}

static struct so_list *
som_current_sos (void)
{
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
  CORE_ADDR lm;
  struct so_list *head = 0;
  struct so_list **link_ptr = &head;

  for (lm = link_map_start (); lm; )
    {
      char *namebuf;
      CORE_ADDR addr;
      struct so_list *new;
      struct cleanup *old_chain;
      int errcode;
      struct dld_list dbuf;
      gdb_byte tsdbuf[4];

      new = (struct so_list *) xmalloc (sizeof (struct so_list));
      old_chain = make_cleanup (xfree, new);

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

      read_memory (lm, (gdb_byte *)&dbuf, sizeof (struct dld_list));

      addr = extract_unsigned_integer ((gdb_byte *)&dbuf.name,
				       sizeof (dbuf.name), byte_order);
      target_read_string (addr, &namebuf, SO_NAME_MAX_PATH_SIZE - 1, &errcode);
      if (errcode != 0)
	warning (_("Can't read pathname for load map: %s."),
		 safe_strerror (errcode));
      else
	{
	  strncpy (new->so_name, namebuf, SO_NAME_MAX_PATH_SIZE - 1);
	  new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
	  xfree (namebuf);
	  strcpy (new->so_original_name, new->so_name);
	}

	if (new->so_name[0] && !match_main (new->so_name))
	  {
	    struct lm_info *lmi = new->lm_info;
	    unsigned int tmp;

	    lmi->lm_addr = lm;

#define EXTRACT(_fld) \
  extract_unsigned_integer ((gdb_byte *)&dbuf._fld, \
			    sizeof (dbuf._fld), byte_order);

	    lmi->text_addr = EXTRACT (text_addr);
	    tmp = EXTRACT (info);
	    lmi->library_version = (tmp >> 16) & 0xffff;
	    lmi->bind_mode = (tmp >> 8) & 0xff;
	    lmi->struct_version = tmp & 0xff;
	    lmi->text_link_addr = EXTRACT (text_link_addr);
	    lmi->text_end = EXTRACT (text_end);
	    lmi->data_start = EXTRACT (data_start);
	    lmi->bss_start = EXTRACT (bss_start);
	    lmi->data_end = EXTRACT (data_end);
	    lmi->got_value = EXTRACT (got_value);
	    tmp = EXTRACT (tsd_start_addr_ptr);
	    read_memory (tmp, tsdbuf, 4);
	    lmi->tsd_start_addr
	      = extract_unsigned_integer (tsdbuf, 4, byte_order);

#ifdef SOLIB_SOM_DBG
	    printf ("\n+ library \"%s\" is described at %s\n", new->so_name,
	    	    paddress (target_gdbarch (), lm));
	    printf ("  'version' is %d\n", new->lm_info->struct_version);
	    printf ("  'bind_mode' is %d\n", new->lm_info->bind_mode);
	    printf ("  'library_version' is %d\n", 
	    	    new->lm_info->library_version);
	    printf ("  'text_addr' is %s\n",
	    	    paddress (target_gdbarch (), new->lm_info->text_addr));
	    printf ("  'text_link_addr' is %s\n",
	    	    paddress (target_gdbarch (), new->lm_info->text_link_addr));
	    printf ("  'text_end' is %s\n",
	    	    paddress (target_gdbarch (), new->lm_info->text_end));
	    printf ("  'data_start' is %s\n",
	    	    paddress (target_gdbarch (), new->lm_info->data_start));
	    printf ("  'bss_start' is %s\n",
	    	    paddress (target_gdbarch (), new->lm_info->bss_start));
	    printf ("  'data_end' is %s\n",
	    	    paddress (target_gdbarch (), new->lm_info->data_end));
	    printf ("  'got_value' is %s\n",
	    	    paddress (target_gdbarch (), new->lm_info->got_value));
	    printf ("  'tsd_start_addr' is %s\n",
	    	    paddress (target_gdbarch (), new->lm_info->tsd_start_addr));
#endif

	    new->addr_low = lmi->text_addr;
	    new->addr_high = lmi->text_end;

	    /* Link the new object onto the list.  */
	    new->next = NULL;
	    *link_ptr = new;
	    link_ptr = &new->next;
	  }
 	else
	  {
	    free_so (new);
	  }

      lm = EXTRACT (next);
      discard_cleanups (old_chain);
#undef EXTRACT
    }

  /* TODO: The original somsolib code has logic to detect and eliminate 
     duplicate entries.  Do we need that?  */

  return head;
}

static int
som_open_symbol_file_object (void *from_ttyp)
{
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
  CORE_ADDR lm, l_name;
  char *filename;
  int errcode;
  int from_tty = *(int *)from_ttyp;
  gdb_byte buf[4];
  struct cleanup *cleanup;

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

  /* First link map member should be the executable.  */
  if ((lm = link_map_start ()) == 0)
    return 0;	/* failed somehow...  */

  /* Read address of name from target memory to GDB.  */
  read_memory (lm + offsetof (struct dld_list, name), buf, 4);

  /* Convert the address to host format.  Assume that the address is
     unsigned.  */
  l_name = extract_unsigned_integer (buf, 4, byte_order);

  if (l_name == 0)
    return 0;		/* No filename.  */

  /* Now fetch the filename from target memory.  */
  target_read_string (l_name, &filename, SO_NAME_MAX_PATH_SIZE - 1, &errcode);

  if (errcode)
    {
      warning (_("failed to read exec filename from attached file: %s"),
	       safe_strerror (errcode));
      return 0;
    }

  cleanup = make_cleanup (xfree, filename);
  /* Have a pathname: read the symbol file.  */
  symbol_file_add_main (filename, from_tty);

  do_cleanups (cleanup);
  return 1;
}

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

static CORE_ADDR
som_solib_thread_start_addr (struct so_list *so)
{
  return so->lm_info->tsd_start_addr;
}

/* 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
som_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->text_addr <= addr
	  && so_list->lm_info->text_end > addr)
	{
	  got_value = so_list->lm_info->got_value;
	  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 initialize_hp_cxx_exception_support in 
   hppa-hpux-tdep.c.  */

static CORE_ADDR
som_solib_get_solib_by_pc (CORE_ADDR addr)
{
  struct so_list *so_list = master_so_list ();

  while (so_list)
    {
      if (so_list->lm_info->text_addr <= addr
	  && so_list->lm_info->text_end > addr)
	{
	  break;
	}
      so_list = so_list->next;
    }
  if (so_list)
    return so_list->lm_info->lm_addr;
  else
    return 0;
}


static struct target_so_ops som_so_ops;

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

void
_initialize_som_solib (void)
{
  som_so_ops.relocate_section_addresses = som_relocate_section_addresses;
  som_so_ops.free_so = som_free_so;
  som_so_ops.clear_solib = som_clear_solib;
  som_so_ops.solib_create_inferior_hook = som_solib_create_inferior_hook;
  som_so_ops.special_symbol_handling = som_special_symbol_handling;
  som_so_ops.current_sos = som_current_sos;
  som_so_ops.open_symbol_file_object = som_open_symbol_file_object;
  som_so_ops.in_dynsym_resolve_code = som_in_dynsym_resolve_code;
  som_so_ops.bfd_open = solib_bfd_open;
}

void
som_solib_select (struct gdbarch *gdbarch)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  set_solib_ops (gdbarch, &som_so_ops);
  tdep->solib_thread_start_addr = som_solib_thread_start_addr;
  tdep->solib_get_got_by_pc = som_solib_get_got_by_pc;
  tdep->solib_get_solib_by_pc = som_solib_get_solib_by_pc;
}

/* The rest of these functions are not part of the solib interface; they 
   are used by somread.c or hppa-hpux-tdep.c.  */

int
som_solib_section_offsets (struct objfile *objfile,
			   struct section_offsets *offsets)
{
  struct so_list *so_list = master_so_list ();

  while (so_list)
    {
      /* Oh what a pain!  We need the offsets before so_list->objfile
         is valid.  The BFDs will never match.  Make a best guess.  */
      if (strstr (objfile_name (objfile), so_list->so_name))
	{
	  asection *private_section;
	  struct obj_section *sect;

	  /* The text offset is easy.  */
	  offsets->offsets[SECT_OFF_TEXT (objfile)]
	    = (so_list->lm_info->text_addr
	       - so_list->lm_info->text_link_addr);

	  /* We should look at presumed_dp in the SOM header, but
	     that's not easily available.  This should be OK though.  */
	  private_section = bfd_get_section_by_name (objfile->obfd,
						     "$PRIVATE$");
	  if (!private_section)
	    {
	      warning (_("Unable to find $PRIVATE$ in shared library!"));
	      offsets->offsets[SECT_OFF_DATA (objfile)] = 0;
	      offsets->offsets[SECT_OFF_BSS (objfile)] = 0;
	      return 1;
	    }
	  if (objfile->sect_index_data != -1)
	    {
	      offsets->offsets[SECT_OFF_DATA (objfile)]
		= (so_list->lm_info->data_start - private_section->vma);
	      if (objfile->sect_index_bss != -1)
		offsets->offsets[SECT_OFF_BSS (objfile)]
		  = ANOFFSET (offsets, SECT_OFF_DATA (objfile));
	    }

	  ALL_OBJFILE_OSECTIONS (objfile, sect)
	    {
	      flagword flags = bfd_get_section_flags (objfile->obfd,
						      sect->the_bfd_section);

	      if ((flags & SEC_CODE) != 0)
		offsets->offsets[sect->the_bfd_section->index]
		  = offsets->offsets[SECT_OFF_TEXT (objfile)];
	      else
		offsets->offsets[sect->the_bfd_section->index]
		  = offsets->offsets[SECT_OFF_DATA (objfile)];
	    }

	  return 1;
	}
      so_list = so_list->next;
    }
  return 0;
}
