* Beginnings of SOM shared library support. Breakpoints and
authorJeff Law <law@redhat.com>
Mon, 7 Nov 1994 07:51:47 +0000 (07:51 +0000)
committerJeff Law <law@redhat.com>
Mon, 7 Nov 1994 07:51:47 +0000 (07:51 +0000)
single frame backtracing within the library only.  Only works when
using the HPUX 9 dynamic linker.  More functionality to be added
soon.

* somsolib.c, somsolib.h: New files.
* Makefile.in (HFILES_NO_SRCDIR): Add somsolib.h
(ALLDEPFILES): Add somsolib.c.
(somsolib.o): Add some dependencies.
* mpw-make.in (HFILES_NO_SRCDIR): Add somsolib.h
(ALLDEPFILES): Add somsolib.c.
(somsolib.o): Add some dependencies.
* somread.c (som_symtab_read): Accept multiple section offsets.
All callers changed.  Adjust all text symbols with the first
section offset.
* symfile.c (find_lowest_section): Enable this function.  Add some
tie-breaking logic when sections have the same vma.
(syms_from_objfile): Use find_lowest_section rather than looking
for ".text" by name.  Relax warning to only warn if the lowest
section is not a code section.
* config/pa/{hppabsd.mh, hppahpux.mh} (NATDEPFILES): Add somsolib.o
* config/pa/{nm-hppab.h, nm-hppah.h}: Include somsolib.h.

gdb/.Sanitize
gdb/ChangeLog
gdb/ChangeLog.mpw
gdb/config/pa/hppabsd.mh
gdb/config/pa/hppahpux.mh
gdb/config/pa/nm-hppab.h
gdb/config/pa/nm-hppah.h
gdb/mpw-make.in
gdb/somread.c
gdb/somsolib.c [new file with mode: 0644]
gdb/somsolib.h [new file with mode: 0644]

index 7f45736..ca52bf7 100644 (file)
@@ -271,6 +271,8 @@ signals.h
 solib.c
 solib.h
 somread.c
+somsolib.c
+somsolib.h
 source.c
 sp64-tdep.c
 sparc-nat.c
index 6604be0..c2e9614 100644 (file)
@@ -1,3 +1,25 @@
+Mon Nov  7 00:27:16 1994  Jeff Law  (law@snake.cs.utah.edu)
+
+       * Beginnings of SOM shared library support.  Breakpoints and
+       single frame backtracing within the library only.  Only works when
+       using the HPUX 9 dynamic linker.  More functionality to be added
+       soon.
+
+       * somsolib.c, somsolib.h: New files.
+       * Makefile.in (HFILES_NO_SRCDIR): Add somsolib.h
+       (ALLDEPFILES): Add somsolib.c.
+       (somsolib.o): Add some dependencies.
+       * somread.c (som_symtab_read): Accept multiple section offsets.
+       All callers changed.  Adjust all text symbols with the first
+       section offset.
+       * symfile.c (find_lowest_section): Enable this function.  Add some
+       tie-breaking logic when sections have the same vma.
+       (syms_from_objfile): Use find_lowest_section rather than looking
+       for ".text" by name.  Relax warning to only warn if the lowest
+       section is not a code section.
+       * config/pa/{hppabsd.mh, hppahpux.mh} (NATDEPFILES): Add somsolib.o
+       * config/pa/{nm-hppab.h, nm-hppah.h}: Include somsolib.h.
+       
 Sun Nov  6 12:54:54 1994  Jeff Law  (law@snake.cs.utah.edu)
 
        * partial-stab.h (N_TEXT): Put back GDB_TARGET_IS_HPPA kludge,
index 4420fe4..e716e26 100644 (file)
@@ -1,3 +1,9 @@
+Mon Nov  7 00:46:22 1994  Jeff Law  (law@snake.cs.utah.edu)
+
+       * mpw-make.in (HFILES_NO_SRCDIR): Add somsolib.h
+       (ALLDEPFILES): Add somsolib.c.
+       (somsolib.o): Add some dependencies.
+
 Mon Sep 12 17:44:58 1994  Stan Shebs  (shebs@andros.cygnus.com)
 
        * mpw-config.in: Use nm-empty.h if host is not target.
index cbb6f8b..161292d 100644 (file)
@@ -6,4 +6,4 @@ HPREAD=hpread.o
 XDEPFILES= 
 XM_FILE= xm-hppab.h
 NAT_FILE= nm-hppab.h
-NATDEPFILES= hppab-nat.o coredep.o corelow.o inftarg.o fork-child.o somread.o infptrace.o $(HPREAD)
+NATDEPFILES= hppab-nat.o coredep.o corelow.o inftarg.o fork-child.o somread.o infptrace.o $(HPREAD) somsolib.o
index 6cfa8ed..dff59ab 100644 (file)
@@ -10,6 +10,6 @@ XM_FILE= xm-hppah.h
 XDEPFILES= ser-tcp.o
 
 NAT_FILE= nm-hppah.h
-NATDEPFILES= hppah-nat.o coredep.o corelow.o inftarg.o fork-child.o somread.o infptrace.o $(HPREAD)
+NATDEPFILES= hppah-nat.o coredep.o corelow.o inftarg.o fork-child.o somread.o infptrace.o $(HPREAD) somsolib.o
 
 HOST_IPC=-DBSD_IPC -DPOSIX_WAIT
index 4581658..421dfd7 100644 (file)
@@ -17,6 +17,8 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
+#include "somsolib.h"
+
 #define U_REGS_OFFSET 0
 
 #define KERNEL_U_ADDR 0
index fdbc17e..f10e504 100644 (file)
@@ -17,6 +17,8 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
+#include "somsolib.h"
+
 #define U_REGS_OFFSET 0
 
 #define KERNEL_U_ADDR 0
index 94a667e..73568ad 100644 (file)
@@ -345,7 +345,8 @@ ALLDEPFILES = "{s}"29k-share:udi:udip2soc.c "{s}"29k-share:udi:udr.c \Option-d
        "{s}"nindy-share:Onindy.c "{s}"nindy-share:nindy.c \Option-d
        "{s}"nindy-share:ttyflush.c "{s}"nindy-tdep.c \Option-d
        "{s}"ns32k-pinsn.c "{s}"ns32km3-nat.c "{s}"osfsolib.c \Option-d
-       "{s}"somread.c "{s}"procfs.c "{s}"pyr-pinsn.c "{s}"pyr-tdep.c "{s}"pyr-xdep.c \Option-d
+       "{s}"somread.c "{s}"somsolib.c \
+       "{s}"procfs.c "{s}"pyr-pinsn.c "{s}"pyr-tdep.c "{s}"pyr-xdep.c \Option-d
        "{s}"remote-adapt.c "{s}"remote-bug.c "{s}"remote-e7000.c "{s}"remote-eb.c "{s}"remote-es.c \Option-d
        "{s}"remote-hms.c "{s}"remote-mips.c \Option-d
        "{s}"remote-mm.c "{s}"remote-mon.c "{s}"remote-nindy.c "{s}"remote-sim.c \Option-d
@@ -606,7 +607,7 @@ HFILES_NO_SRCDIR = "{s}"buildsym.h "{s}"call-cmds.h "{s}"coff-solib.h "{s}"defs.
        "{s}"vx-share:dbgRpcLib.h "{s}"vx-share:ptrace.h "{s}"vx-share:vxTypes.h \Option-d
        "{s}"vx-share:vxWorks.h "{s}"vx-share:wait.h "{s}"vx-share:xdr_ld.h \Option-d
        "{s}"vx-share:xdr_ptrace.h "{s}"vx-share:xdr_rdb.h "{s}"thread.h \Option-d
-       "{s}"dcache.h "{s}"remote-utils.h "{s}"remote-sim.h
+       "{s}"dcache.h "{s}"remote-utils.h "{s}"remote-sim.h "{s}"somsolib.h
 
 # Header files that already have srcdir in them.
 
@@ -1364,6 +1365,8 @@ MAKEOVERRIDES=
 "{o}"somread.c.o \Option-f  "{s}"somread.c {bfd_h} "{s}"buildsym.h "{s}"complaints.h {defs_h} \Option-d
        "{s}"gdb-stabs.h "{s}"objfiles.h "{s}"symfile.h {symtab_h}
 
+"{o}"somsolib.c.o \Option-f  "{s}"somsolib.c {defs_h}
+
 "{o}"parse.c.o \Option-f  "{s}"parse.c {command_h} {defs_h} {expression_h} {frame_h} \Option-d
        {gdbtypes_h} "{s}"language.h "{s}"parser-defs.h {symtab_h} {value_h}
 
index 48ea124..35def22 100644 (file)
@@ -49,7 +49,8 @@ static void
 som_symfile_finish PARAMS ((struct objfile *));
 
 static void
-som_symtab_read PARAMS ((bfd *,  CORE_ADDR, struct objfile *));
+som_symtab_read PARAMS ((bfd *, struct objfile *,
+                        struct section_offsets *));
 
 static struct section_offsets *
 som_symfile_offsets PARAMS ((struct objfile *, CORE_ADDR));
@@ -78,8 +79,8 @@ LOCAL FUNCTION
 
 SYNOPSIS
 
-       void som_symtab_read (bfd *abfd, CORE_ADDR addr,
-                             struct objfile *objfile)
+       void som_symtab_read (bfd *abfd, struct objfile *objfile,
+                             struct section_offsets *section_offsets)
 
 DESCRIPTION
 
@@ -90,10 +91,10 @@ DESCRIPTION
 */
 
 static void
-som_symtab_read (abfd, addr, objfile)
+som_symtab_read (abfd, objfile, section_offsets)
      bfd *abfd;
-     CORE_ADDR addr;
      struct objfile *objfile;
+     struct section_offsets *section_offsets;
 {
   unsigned int number_of_symbols;
   int val, dynamic;
@@ -102,6 +103,11 @@ som_symtab_read (abfd, addr, objfile)
   struct symbol_dictionary_record *buf, *bufp, *endbufp;
   char *symname;
   CONST int symsize = sizeof (struct symbol_dictionary_record);
+  CORE_ADDR text_offset;
+
+
+  /* FIXME.  Data stuff needs dynamic relocation too!  */
+  text_offset = ANOFFSET (section_offsets, 0);
 
   number_of_symbols = bfd_get_symcount (abfd);
 
@@ -152,6 +158,7 @@ som_symtab_read (abfd, addr, objfile)
            case ST_MILLICODE:
              symname = bufp->name.n_strx + stringtab;
              ms_type = mst_text;
+             bufp->symbol_value += text_offset;
 #ifdef SMASH_TEXT_ADDRESS
              SMASH_TEXT_ADDRESS (bufp->symbol_value);
 #endif
@@ -166,6 +173,7 @@ som_symtab_read (abfd, addr, objfile)
                ms_type = mst_solib_trampoline;
              else
                ms_type = mst_text;
+             bufp->symbol_value += text_offset;
 #ifdef SMASH_TEXT_ADDRESS
              SMASH_TEXT_ADDRESS (bufp->symbol_value);
 #endif
@@ -174,6 +182,7 @@ som_symtab_read (abfd, addr, objfile)
            case ST_STUB:
              symname = bufp->name.n_strx + stringtab;
              ms_type = mst_solib_trampoline;
+             bufp->symbol_value += text_offset;
 #ifdef SMASH_TEXT_ADDRESS
              SMASH_TEXT_ADDRESS (bufp->symbol_value);
 #endif
@@ -202,6 +211,7 @@ som_symtab_read (abfd, addr, objfile)
            case ST_CODE:
              symname = bufp->name.n_strx + stringtab;
              ms_type = mst_file_text;
+             bufp->symbol_value += text_offset;
 #ifdef SMASH_TEXT_ADDRESS
              SMASH_TEXT_ADDRESS (bufp->symbol_value);
 #endif
@@ -227,6 +237,7 @@ som_symtab_read (abfd, addr, objfile)
            case ST_MILLICODE:
              symname = bufp->name.n_strx + stringtab;
              ms_type = mst_file_text;
+             bufp->symbol_value += text_offset;
 #ifdef SMASH_TEXT_ADDRESS
              SMASH_TEXT_ADDRESS (bufp->symbol_value);
 #endif
@@ -241,6 +252,7 @@ som_symtab_read (abfd, addr, objfile)
                ms_type = mst_solib_trampoline;
              else
                ms_type = mst_file_text;
+             bufp->symbol_value += text_offset;
 #ifdef SMASH_TEXT_ADDRESS
              SMASH_TEXT_ADDRESS (bufp->symbol_value);
 #endif
@@ -249,6 +261,7 @@ som_symtab_read (abfd, addr, objfile)
            case ST_STUB:
              symname = bufp->name.n_strx + stringtab;
              ms_type = mst_solib_trampoline;
+             bufp->symbol_value += text_offset;
 #ifdef SMASH_TEXT_ADDRESS
              SMASH_TEXT_ADDRESS (bufp->symbol_value);
 #endif
@@ -316,18 +329,13 @@ som_symfile_read (objfile, section_offsets, mainline)
 {
   bfd *abfd = objfile->obfd;
   struct cleanup *back_to;
-  CORE_ADDR offset;
 
   init_minimal_symbol_collection ();
   back_to = make_cleanup (discard_minimal_symbols, 0);
 
-  /* FIXME, should take a section_offsets param, not just an offset.  */
-
-  offset = ANOFFSET (section_offsets, 0);
-
   /* Process the normal SOM symbol table first. */
 
-  som_symtab_read (abfd, offset, objfile);
+  som_symtab_read (abfd, objfile, section_offsets);
 
   /* Now read information from the stabs debug sections.  */
   stabsect_build_psymtabs (objfile, section_offsets, mainline,
diff --git a/gdb/somsolib.c b/gdb/somsolib.c
new file mode 100644 (file)
index 0000000..67d12ab
--- /dev/null
@@ -0,0 +1,319 @@
+/* Handle HP SOM shared libraries for GDB, the GNU Debugger.
+   Copyright 1993 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Written by the Center for Software Science at the Univerity of Utah
+and by Cygnus Support.  */
+
+
+#include "defs.h"
+
+#include "frame.h"
+#include "bfd.h"
+#include "som.h"
+#include "libhppa.h"
+#include "gdbcore.h"
+#include "symtab.h"
+#include "breakpoint.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "inferior.h"
+
+/* We don't currently use this structure, but it isn't documented anywhere,
+   and we'll likely need it in som_solib_add as more shared library support
+   is added.  */
+
+struct som_solib_mapped_entry
+{
+  /* The name of the library.  */
+  char *name;
+
+  /* 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, 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;
+
+  /* Next entry.  */
+  struct som_solib_mapped_entry *next;
+
+  /* There are other fields, but I don't have information as to what is
+     contained in them.  */
+};
+
+/* Add symbols from shared libraries into the symtab list.  */
+
+void
+som_solib_add (arg_string, from_tty, target)
+     char *arg_string;
+     int from_tty;
+     struct target_ops *target;
+{      
+  struct minimal_symbol *msymbol;
+  CORE_ADDR addr;
+  int status;
+  char buf[4];
+
+  msymbol = lookup_minimal_symbol ("__dld_list", (struct objfile *) NULL);
+  if (!msymbol)
+    {
+      /* 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.  */
+      msymbol = lookup_minimal_symbol ("__dld_flags", (struct objfile *)NULL);
+      if (!msymbol)
+       {
+         error ("Unable to find dynamic library list.\n");
+         return;
+       }
+      addr = SYMBOL_VALUE_ADDRESS (msymbol) - 8;
+    }
+  else
+    addr = SYMBOL_VALUE_ADDRESS (msymbol);
+
+  status = target_read_memory (addr, buf, 4);
+  if (status != 0)
+    {
+      error ("Unable to find dynamic library list.\n");
+      return;
+    }
+
+  addr = extract_unsigned_integer (buf, 4);
+
+  /* If addr is zero, then we're using an old dynamic loader which
+     doesn't maintain __dld_list.  We'll have to use a completely
+     different approach to get shared library information.  */
+  if (addr == 0)
+    goto old_dld;
+
+  /* Using the information in __dld_list is the preferred method
+     to get at shared library information.  It doesn't depend on
+     any functions in /usr/lib/end.o and has a chance of working
+     with hpux10 when it is released.  */
+  status = target_read_memory (addr, buf, 4);
+  if (status != 0)
+    {
+      error ("Unable to find dynamic library list.\n");
+      return;
+    }
+
+  /* addr now holds the address of the first entry in the dynamic
+     library list.  */
+  addr = extract_unsigned_integer (buf, 4);
+
+  /* Now that we have a pointer to the dynamic library list, walk
+     through it and add the symbols for each library.
+
+     Skip the first entry since it's our executable.  */
+  status = target_read_memory (addr + 36, buf, 4);
+  if (status != 0)
+    {
+      error ("Error while reading dynamic library list.\n");
+      return;
+    }
+  addr = extract_unsigned_integer (buf, 4);
+
+  while (1)
+    {
+      CORE_ADDR name_addr, text_addr;
+      unsigned int name_len;
+      char *name;
+      if (addr == 0)
+       break;
+
+      /* Get a pointer to the name of this library.  */
+      status = target_read_memory (addr, buf, 4);
+      if (status != 0)
+       {
+         error ("Error while reading dynamic library list.\n");
+         return;
+       }
+      name_addr = extract_unsigned_integer (buf, 4);
+      name_len = 0;
+      while (1)
+       {
+         target_read_memory (name_addr + name_len, buf, 1);
+         if (status != 0)
+           {
+             error ("Error while reading dynamic library list.\n");
+             return;
+           }
+         name_len++;
+         if (*buf == '\0')
+           break;
+       }
+      name = alloca (name_len);
+      status = target_read_memory (name_addr, name, name_len);
+      if (status != 0)
+       {
+         error ("Error while reading dynamic library list.\n");
+         return;
+       }
+      name = obsavestring (name, name_len - 1,
+                          &symfile_objfile->symbol_obstack);
+
+      status = target_read_memory (addr + 8, buf, 4);
+      if (status != 0)
+       {
+         error ("Error while reading dynamic library list.\n");
+         return;
+       }
+      text_addr = extract_unsigned_integer (buf, 4);
+
+      /* OK, we've got everything we need.  Tell GDB about it.  */
+      symbol_file_add (name, from_tty, text_addr, 0, 0, 0);
+
+      /* Get address of the next record.  */
+      status = target_read_memory (addr + 36, buf, 4);
+      if (status != 0)
+       {
+         error ("Error while reading dynamic library list.\n");
+         return;
+       }
+      addr = extract_unsigned_integer (buf, 4);
+    }
+
+  /* Getting new symbols may change our opinion about what is
+     frameless.  */
+  reinit_frame_cache ();
+  return;
+
+old_dld:
+  error ("Debugging dynamic executables loaded via the hpux8 dld.sl is not supported.\n");
+  return;
+}
+
+/* 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.  */
+   
+void 
+som_solib_create_inferior_hook()
+{
+  struct minimal_symbol *msymbol;
+  asection *shlib_info;
+  unsigned int dld_flags, status;
+  char shadow_contents[BREAKPOINT_MAX], buf[4];
+  CORE_ADDR anaddr;
+
+  /* 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;
+
+  /* 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", (struct objfile *) NULL);
+  if (msymbol == NULL)
+    {
+      error ("Unable to find __dld_flags symbol in object file.\n");
+      return;
+    }
+
+  anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
+  /* Read the current contents.  */
+  status = target_read_memory (anaddr, buf, 4);
+  if (status != 0)
+    {
+      error ("Unable to read __dld_flags\n");
+      return;
+    }
+  dld_flags = extract_unsigned_integer (buf, 4);
+
+  /* Turn on the flags we care about.  */
+  dld_flags |= 0x5;
+  store_unsigned_integer (buf, 4, dld_flags);
+  status = target_write_memory (anaddr, buf, 4);
+  if (status != 0)
+    {
+      error ("Unable to write __dld_flags\n");
+      return;
+    }
+
+  /* Now find the address of _start and set a breakpoint there.  */
+  msymbol = lookup_minimal_symbol ("_start", symfile_objfile);
+  if (msymbol == NULL)
+    {
+      error ("Unable to find _start symbol in object file.\n");
+      return;
+    }
+
+  anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
+  if (target_insert_breakpoint (anaddr, shadow_contents))
+    {
+      error ("Unable to set breakpoint at _start.\n");
+      return;
+    }
+
+  /* Start the process again and wait for it to hit our breakpoint.  */
+  clear_proceed_status ();
+  stop_soon_quietly = 1;
+  stop_signal = TARGET_SIGNAL_0;
+  do
+    {
+      target_resume (-1, 0, stop_signal);
+      wait_for_inferior ();
+    }
+  while (stop_signal != TARGET_SIGNAL_TRAP);
+  stop_soon_quietly = 0;
+
+  /* All the libraries should be mapped in now.  Remove our breakpoint and
+     read in the symbol tables from the shared libraries.  */
+  if (target_remove_breakpoint (anaddr, shadow_contents))
+    {
+      error ("Unable to remove breakpoint at _start.\n");
+      return;
+    }
+
+  som_solib_add ((char *) 0, 0, (struct target_ops *) 0);
+}
diff --git a/gdb/somsolib.h b/gdb/somsolib.h
new file mode 100644 (file)
index 0000000..f6b0115
--- /dev/null
@@ -0,0 +1,43 @@
+/* HP SOM Shared library declarations for GDB, the GNU Debugger.
+   Copyright (C) 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Written by the Center for Software Science at the Univerity of Utah
+and by Cygnus Support.  */
+
+#ifdef __STDC__                /* Forward decl's for prototypes */
+struct target_ops;
+#endif
+
+/* Called to add symbols from a shared library to gdb's symbol table. */
+
+#define SOLIB_ADD(filename, from_tty, targ) \
+    som_solib_add (filename, from_tty, targ)
+
+extern void
+som_solib_add PARAMS ((char *, int, struct target_ops *));
+
+/* Function to be called when the inferior starts up, to discover the names
+   of shared libraries that are dynamically linked, the base addresses to
+   which they are linked, and sufficient information to read in their symbols
+   at a later time. */
+
+#define SOLIB_CREATE_INFERIOR_HOOK(PID)        som_solib_create_inferior_hook()
+
+extern void
+som_solib_create_inferior_hook PARAMS((void));