* complaints.c: New file, code moved from utils.c.
[deliverable/binutils-gdb.git] / gdb / dbxread.c
index 7cbdbe13fe3dd191bc798c726ce1e0390760c055..a8595973cd805c9bfeb64e76e7244076343f9ac5 100644 (file)
@@ -41,6 +41,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define L_INCR 1
 #endif
 
+#ifdef GDB_TARGET_IS_HPPA
+/* We don't want to use HP-UX's nlists. */
+#define _NLIST_INCLUDED
+#endif
+
 #include <obstack.h>
 #include <sys/param.h>
 #ifndef        NO_SYS_FILE
@@ -54,35 +59,24 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "target.h"
 #include "gdbcore.h"           /* for bfd stuff */
 #include "libbfd.h"            /* FIXME Secret internal BFD stuff (bfd_read) */
+#ifdef GDB_TARGET_IS_HPPA
+#include "libhppa.h"
+#include "syms.h"
+#else
 #include "libaout.h"           /* FIXME Secret internal BFD stuff for a.out */
+#endif
 #include "symfile.h"
 #include "objfiles.h"
 #include "buildsym.h"
+#include "stabsread.h"
+#include "gdb-stabs.h"
+#include "demangle.h"
+#include "language.h"          /* Needed inside partial-stab.h */
+#include "complaints.h"
 
 #include "aout/aout64.h"
 #include "aout/stab_gnu.h"     /* We always use GNU stabs, not native, now */
 
-/* Information is passed among various dbxread routines for accessing
-   symbol files.  A pointer to this structure is kept in the sym_private
-   field of the objfile struct.  */
-struct dbx_symfile_info {
-  asection *text_sect;         /* Text section accessor */
-  int symcount;                        /* How many symbols are there in the file */
-  char *stringtab;             /* The actual string table */
-  int stringtab_size;          /* Its size */
-  off_t symtab_offset;         /* Offset in file to symbol table */
-  int symbol_size;             /* Bytes in a single symbol */
-};
-
-#define DBX_SYMFILE_INFO(o)    ((struct dbx_symfile_info *)((o)->sym_private))
-#define DBX_TEXT_SECT(o)       (DBX_SYMFILE_INFO(o)->text_sect)
-#define DBX_SYMCOUNT(o)                (DBX_SYMFILE_INFO(o)->symcount)
-#define DBX_STRINGTAB(o)       (DBX_SYMFILE_INFO(o)->stringtab)
-#define DBX_STRINGTAB_SIZE(o)  (DBX_SYMFILE_INFO(o)->stringtab_size)
-#define DBX_SYMTAB_OFFSET(o)   (DBX_SYMFILE_INFO(o)->symtab_offset)
-#define DBX_SYMBOL_SIZE(o)     (DBX_SYMFILE_INFO(o)->symbol_size)
-
 /* Each partial symbol table entry contains a pointer to private data for the
    read_symtab() function to use when expanding a partial symbol table entry
    to a full symbol table entry.
@@ -221,7 +215,8 @@ static struct pending *
 copy_pending PARAMS ((struct pending *, int, struct pending *));
 
 static struct symtab *
-read_ofile_symtab PARAMS ((struct objfile *, int, int, CORE_ADDR, int, int));
+read_ofile_symtab PARAMS ((struct objfile *, int, int, CORE_ADDR, int, 
+                          struct section_offsets *));
 
 static void
 dbx_psymtab_to_symtab PARAMS ((struct partial_symtab *));
@@ -230,7 +225,8 @@ static void
 dbx_psymtab_to_symtab_1 PARAMS ((struct partial_symtab *));
 
 static void
-read_dbx_symtab PARAMS ((CORE_ADDR, struct objfile *, CORE_ADDR, int));
+read_dbx_symtab PARAMS ((struct section_offsets *, struct objfile *,
+                        CORE_ADDR, int));
 
 static void
 free_bincl_list PARAMS ((struct objfile *));
@@ -260,7 +256,7 @@ static void
 dbx_new_init PARAMS ((struct objfile *));
 
 static void
-dbx_symfile_read PARAMS ((struct objfile *, CORE_ADDR, int));
+dbx_symfile_read PARAMS ((struct objfile *, struct section_offsets *, int));
 
 static void
 dbx_symfile_finish PARAMS ((struct objfile *));
@@ -354,7 +350,7 @@ add_old_header_file (name, instance)
        add_this_object_header_file (i);
        return;
       }
-  complain (&repeated_header_complaint, (char *)symnum);
+  complain (&repeated_header_complaint, symnum);
   complain (&repeated_header_name_complaint, name);
 }
 
@@ -394,7 +390,7 @@ add_new_header_file (name, instance)
   header_files[i].length = 10;
   header_files[i].vector
     = (struct type **) xmalloc (10 * sizeof (struct type *));
-  bzero (header_files[i].vector, 10 * sizeof (struct type *));
+  memset (header_files[i].vector, 0, 10 * sizeof (struct type *));
 
   add_this_object_header_file (i);
 }
@@ -447,15 +443,15 @@ record_minimal_symbol (name, address, type, objfile)
    put all the relevant info into a "struct dbx_symfile_info",
    hung off the objfile structure.
 
-   ADDR is the address relative to which the symbols in it are (e.g.
-   the base address of the text segment).
+   SECTION_OFFSETS contains offsets relative to which the symbols in the
+   various sections are (depending where the sections were actually loaded).
    MAINLINE is true if we are reading the main symbol
    table (as opposed to a shared lib or dynamically loaded file).  */
 
 static void
-dbx_symfile_read (objfile, addr, mainline)
+dbx_symfile_read (objfile, section_offsets, mainline)
      struct objfile *objfile;
-     CORE_ADDR addr;
+     struct section_offsets *section_offsets;
      int mainline;     /* FIXME comments above */
 {
   bfd *sym_bfd;
@@ -470,7 +466,11 @@ dbx_symfile_read (objfile, addr, mainline)
   if (mainline || objfile->global_psymbols.size == 0 || objfile->static_psymbols.size == 0)
     init_psymbol_list (objfile);
 
+#ifdef GDB_TARGET_IS_HPPA
+  symbol_size = obj_dbx_symbol_entry_size (sym_bfd);
+#else
   symbol_size = DBX_SYMBOL_SIZE (objfile);
+#endif
   symbol_table_offset = DBX_SYMTAB_OFFSET (objfile);
 
   pending_blocks = 0;
@@ -482,8 +482,7 @@ dbx_symfile_read (objfile, addr, mainline)
   /* Now that the symbol table data of the executable file are all in core,
      process them and define symbols accordingly.  */
 
-  addr -= bfd_section_vma (sym_bfd, DBX_TEXT_SECT (objfile)); /*offset*/
-  read_dbx_symtab (addr, objfile,
+  read_dbx_symtab (section_offsets, objfile,
                   bfd_section_vma  (sym_bfd, DBX_TEXT_SECT (objfile)),
                   bfd_section_size (sym_bfd, DBX_TEXT_SECT (objfile)));
 
@@ -507,6 +506,7 @@ static void
 dbx_new_init (ignore)
      struct objfile *ignore;
 {
+  stabsread_new_init ();
   buildsym_new_init ();
   init_header_files ();
 }
@@ -539,16 +539,29 @@ dbx_symfile_init (objfile)
     xmmalloc (objfile -> md, sizeof (struct dbx_symfile_info));
 
   /* FIXME POKING INSIDE BFD DATA STRUCTURES */
+#ifdef GDB_TARGET_IS_HPPA
+#define STRING_TABLE_OFFSET  (sym_bfd->origin + obj_dbx_str_filepos (sym_bfd))
+#define SYMBOL_TABLE_OFFSET  (sym_bfd->origin + obj_dbx_sym_filepos (sym_bfd))
+#define HP_STRING_TABLE_OFFSET  (sym_bfd->origin + obj_hp_str_filepos (sym_bfd))
+#define HP_SYMBOL_TABLE_OFFSET  (sym_bfd->origin + obj_hp_sym_filepos (sym_bfd))
+#else
 #define        STRING_TABLE_OFFSET     (sym_bfd->origin + obj_str_filepos (sym_bfd))
 #define        SYMBOL_TABLE_OFFSET     (sym_bfd->origin + obj_sym_filepos (sym_bfd))
+#endif
   /* FIXME POKING INSIDE BFD DATA STRUCTURES */
 
+  DBX_SYMFILE_INFO (objfile)->stab_section_info = NULL;
   DBX_TEXT_SECT (objfile) = bfd_get_section_by_name (sym_bfd, ".text");
   if (!DBX_TEXT_SECT (objfile))
     error ("Can't find .text section in symbol file");
 
-  DBX_SYMBOL_SIZE   (objfile) = obj_symbol_entry_size (sym_bfd);
-  DBX_SYMCOUNT      (objfile) = bfd_get_symcount (sym_bfd);
+#ifdef GDB_TARGET_IS_HPPA
+  HP_SYMCOUNT (objfile) = obj_hp_sym_count (sym_bfd);
+  DBX_SYMCOUNT (objfile) = obj_dbx_sym_count (sym_bfd);
+#else
+  DBX_SYMBOL_SIZE (objfile) = obj_symbol_entry_size (sym_bfd);
+  DBX_SYMCOUNT (objfile) = bfd_get_symcount (sym_bfd);
+#endif
   DBX_SYMTAB_OFFSET (objfile) = SYMBOL_TABLE_OFFSET;
 
   /* Read the string table and stash it away in the psymbol_obstack.  It is
@@ -563,6 +576,10 @@ dbx_symfile_init (objfile)
      however at least check to see if the size is zero or some negative
      value. */
 
+#ifdef GDB_TARGET_IS_HPPA
+  DBX_STRINGTAB_SIZE (objfile) = obj_dbx_stringtab_size (sym_bfd);
+  HP_STRINGTAB_SIZE (objfile) = obj_hp_stringtab_size (sym_bfd);
+#else
   val = bfd_seek (sym_bfd, STRING_TABLE_OFFSET, L_SET);
   if (val < 0)
     perror_with_name (name);
@@ -572,6 +589,8 @@ dbx_symfile_init (objfile)
     perror_with_name (name);
 
   DBX_STRINGTAB_SIZE (objfile) = bfd_h_get_32 (sym_bfd, size_temp);
+#endif
+
   if (DBX_STRINGTAB_SIZE (objfile) <= 0)
     error ("ridiculous string table size (%d bytes).",
           DBX_STRINGTAB_SIZE (objfile));
@@ -579,6 +598,15 @@ dbx_symfile_init (objfile)
   DBX_STRINGTAB (objfile) =
     (char *) obstack_alloc (&objfile -> psymbol_obstack,
                            DBX_STRINGTAB_SIZE (objfile));
+#ifdef GDB_TARGET_IS_HPPA
+  if (HP_STRINGTAB_SIZE (objfile) <= 0)
+    error ("ridiculous string table size (%d bytes).",
+          HP_STRINGTAB_SIZE (objfile));
+
+  HP_STRINGTAB (objfile) =
+    (char *) obstack_alloc (&objfile -> psymbol_obstack,
+                           HP_STRINGTAB_SIZE (objfile));
+#endif
 
   /* Now read in the string table in one big gulp.  */
 
@@ -589,6 +617,18 @@ dbx_symfile_init (objfile)
                  sym_bfd);
   if (val != DBX_STRINGTAB_SIZE (objfile))
     perror_with_name (name);
+#ifdef GDB_TARGET_IS_HPPA
+  val = bfd_seek (sym_bfd, HP_STRING_TABLE_OFFSET, L_SET);
+  if (val < 0)
+    perror_with_name (name);
+  val = bfd_read (HP_STRINGTAB (objfile), HP_STRINGTAB_SIZE (objfile), 1,
+                 sym_bfd);
+  if (val != HP_STRINGTAB_SIZE (objfile))
+    perror_with_name (name);
+#endif
+#ifdef GDB_TARGET_IS_HPPA
+  HP_SYMTAB_OFFSET (objfile) = HP_SYMBOL_TABLE_OFFSET;
+#endif
 }
 
 /* Perform any local cleanups required when we are done with a particular
@@ -642,6 +682,25 @@ fill_symbuf (sym_bfd)
   symbuf_end = nbytes / symbol_size;
   symbuf_idx = 0;
 }
+#ifdef GDB_TARGET_IS_HPPA
+/* same as above for the HP symbol table */
+
+static struct symbol_dictionary_record hp_symbuf[4096];
+static int hp_symbuf_idx;
+static int hp_symbuf_end;
+
+static int
+fill_hp_symbuf (sym_bfd)
+     bfd *sym_bfd;
+{
+  int nbytes = bfd_read ((PTR)hp_symbuf, sizeof (hp_symbuf), 1, sym_bfd);
+  if (nbytes <= 0)
+    error ("error or end of file reading symbol table");
+  hp_symbuf_end = nbytes / sizeof (struct symbol_dictionary_record);
+  hp_symbuf_idx = 0;
+  return 1;
+}
+#endif
 
 #define SWAP_SYMBOL(symp, abfd) \
   { \
@@ -689,8 +748,15 @@ init_psymbol_list (objfile)
   /* Current best guess is that there are approximately a twentieth
      of the total symbols (in a debugging file) are global or static
      oriented symbols */
+#ifdef GDB_TARGET_IS_HPPA
+  objfile -> global_psymbols.size = (DBX_SYMCOUNT (objfile) + 
+                                    HP_SYMCOUNT (objfile)) / 10;
+  objfile -> static_psymbols.size = (DBX_SYMCOUNT (objfile) +
+                                    HP_SYMCOUNT (objfile)) / 10;
+#else
   objfile -> global_psymbols.size = DBX_SYMCOUNT (objfile) / 10;
   objfile -> static_psymbols.size = DBX_SYMCOUNT (objfile) / 10;
+#endif
   objfile -> global_psymbols.next = objfile -> global_psymbols.list = (struct partial_symbol *)
     xmmalloc (objfile -> md, objfile -> global_psymbols.size * sizeof (struct partial_symbol));
   objfile -> static_psymbols.next = objfile -> static_psymbols.list = (struct partial_symbol *)
@@ -765,11 +831,12 @@ free_bincl_list (objfile)
    style data, setup partial_symtab's describing each source file for
    which debugging information is available.
    SYMFILE_NAME is the name of the file we are reading from
-   and ADDR is its relocated address (if incremental) or 0 (if not).  */
+   and SECTION_OFFSETS is the set of offsets for the various sections
+   of the file (a set of zeros if the mainline program).  */
 
 static void
-read_dbx_symtab (addr, objfile, text_addr, text_size)
-     CORE_ADDR addr;
+read_dbx_symtab (section_offsets, objfile, text_addr, text_size)
+     struct section_offsets *section_offsets;
      struct objfile *objfile;
      CORE_ADDR text_addr;
      int text_size;
@@ -781,6 +848,14 @@ read_dbx_symtab (addr, objfile, text_addr, text_size)
   CORE_ADDR last_o_file_start = 0;
   struct cleanup *old_chain;
   bfd *abfd;
+#ifdef GDB_TARGET_IS_HPPA
+  /* HP stuff */
+  struct symbol_dictionary_record *hp_bufp;
+  int hp_symnum;
+  /* A hack: the first text symbol in the debugging library */
+  int dbsubc_addr = 0;
+#endif
+
 
   /* End of the text segment of the executable file.  */
   CORE_ADDR end_of_text_addr;
@@ -802,7 +877,11 @@ read_dbx_symtab (addr, objfile, text_addr, text_size)
   file_string_table_offset = 0;
   next_file_string_table_offset = 0;
 
+#ifdef GDB_TARGET_IS_HPPA
+  stringtab_global = HP_STRINGTAB (objfile);
+#else
   stringtab_global = DBX_STRINGTAB (objfile);
+#endif
   
   pst = (struct partial_symtab *) 0;
 
@@ -823,12 +902,13 @@ read_dbx_symtab (addr, objfile, text_addr, text_size)
   init_bincl_list (20, objfile);
   make_cleanup (free_bincl_list, objfile);
 
-  last_source_file = 0;
+  last_source_file = NULL;
 
 #ifdef END_OF_TEXT_DEFAULT
   end_of_text_addr = END_OF_TEXT_DEFAULT;
 #else
-  end_of_text_addr = text_addr + addr + text_size;     /* Relocate */
+  end_of_text_addr = text_addr + section_offsets->offsets[SECT_OFF_TEXT]
+                              + text_size;     /* Relocate */
 #endif
 
   symfile_bfd = objfile->obfd; /* For next_text_symbol */
@@ -836,6 +916,75 @@ read_dbx_symtab (addr, objfile, text_addr, text_size)
   symbuf_end = symbuf_idx = 0;
   next_symbol_text_func = dbx_next_symbol_text;
 
+#ifdef GDB_TARGET_IS_HPPA
+  /* On pa machines, the global symbols are all in the regular HP-UX
+     symbol table. Read them in first. */
+
+  hp_symbuf_end = hp_symbuf_idx = 0;
+  bfd_seek (abfd, HP_SYMTAB_OFFSET (objfile), L_SET);
+
+  for (hp_symnum = 0; hp_symnum < HP_SYMCOUNT (objfile); hp_symnum++)
+    {
+      int dbx_type;
+
+      QUIT;
+      if (hp_symbuf_idx == hp_symbuf_end)
+        fill_hp_symbuf (abfd);
+      hp_bufp = &hp_symbuf[hp_symbuf_idx++];
+      switch (hp_bufp->symbol_type)
+        {
+        case ST_SYM_EXT:
+        case ST_ARG_EXT:
+          continue;
+        case ST_CODE:
+        case ST_PRI_PROG:
+        case ST_SEC_PROG:
+        case ST_ENTRY:
+        case ST_MILLICODE:
+          dbx_type = N_TEXT;
+          hp_bufp->symbol_value &= ~3; /* clear out permission bits */
+          break;
+        case ST_DATA:
+          dbx_type = N_DATA;
+          break;
+#ifdef KERNELDEBUG
+        case ST_ABSOLUTE:
+          {
+            extern int kernel_debugging;
+            if (!kernel_debugging)
+              continue;
+            dbx_type = N_ABS;
+            break;
+          }
+#endif
+        default:
+          continue;
+        }
+      /* Use the address of dbsubc to finish the last psymtab. */
+      if (hp_bufp->symbol_type == ST_CODE &&
+          HP_STRINGTAB (objfile)[hp_bufp->name.n_strx] == '_' &&
+          !strcmp (HP_STRINGTAB (objfile) + hp_bufp->name.n_strx, "_dbsubc"))
+        dbsubc_addr = hp_bufp->symbol_value;
+      if (hp_bufp->symbol_scope == SS_UNIVERSAL)
+        {
+          if (hp_bufp->name.n_strx > HP_STRINGTAB_SIZE (objfile))
+            error ("Invalid symbol data; bad HP string table offset: %d",
+                   hp_bufp->name.n_strx);
+          /* A hack, but gets the job done. */
+          if (!strcmp (hp_bufp->name.n_strx + HP_STRINGTAB (objfile), 
+                      "$START$"))
+           objfile -> ei.entry_file_lowpc = hp_bufp->symbol_value;
+          if (!strcmp (hp_bufp->name.n_strx + HP_STRINGTAB (objfile), 
+                      "_sr4export"))
+           objfile -> ei.entry_file_highpc = hp_bufp->symbol_value;
+          record_minimal_symbol (hp_bufp->name.n_strx + HP_STRINGTAB (objfile),
+                                hp_bufp->symbol_value, dbx_type | N_EXT, 
+                                objfile);
+        }
+    }
+  bfd_seek (abfd, DBX_SYMTAB_OFFSET (objfile), L_SET);
+#endif
+
   for (symnum = 0; symnum < DBX_SYMCOUNT (objfile); symnum++)
     {
       /* Get the symbol for this run and pull out some info */
@@ -871,7 +1020,7 @@ read_dbx_symtab (addr, objfile, text_addr, text_size)
 #define SET_NAMESTRING()\
   if (((unsigned)bufp->n_strx + file_string_table_offset) >=           \
       DBX_STRINGTAB_SIZE (objfile)) {                                  \
-    complain (&string_table_offset_complaint, (char *) symnum);                \
+    complain (&string_table_offset_complaint, symnum);                 \
     namestring = "foo";                                                        \
   } else                                                               \
     namestring = bufp->n_strx + file_string_table_offset +             \
@@ -880,8 +1029,8 @@ read_dbx_symtab (addr, objfile, text_addr, text_size)
 #define CUR_SYMBOL_TYPE bufp->n_type
 #define CUR_SYMBOL_VALUE bufp->n_value
 #define DBXREAD_ONLY
-#define START_PSYMTAB(ofile,addr,fname,low,symoff,global_syms,static_syms)\
-  start_psymtab(ofile, addr, fname, low, symoff, global_syms, static_syms)
+#define START_PSYMTAB(ofile,secoff,fname,low,symoff,global_syms,static_syms)\
+  start_psymtab(ofile, secoff, fname, low, symoff, global_syms, static_syms)
 #define END_PSYMTAB(pst,ilist,ninc,c_off,c_text,dep_list,n_deps)\
   end_psymtab(pst,ilist,ninc,c_off,c_text,dep_list,n_deps)
 
@@ -889,6 +1038,7 @@ read_dbx_symtab (addr, objfile, text_addr, text_size)
     }
 
   /* If there's stuff to be cleaned up, clean it up.  */
+#ifndef GDB_TARGET_IS_HPPA
   if (DBX_SYMCOUNT (objfile) > 0                       /* We have some syms */
 /*FIXME, does this have a bug at start address 0? */
       && last_o_file_start
@@ -898,12 +1048,19 @@ read_dbx_symtab (addr, objfile, text_addr, text_size)
       objfile -> ei.entry_file_lowpc = last_o_file_start;
       objfile -> ei.entry_file_highpc = bufp->n_value;
     }
+#endif
 
   if (pst)
     {
+#ifdef GDB_TARGET_IS_HPPA
+      end_psymtab (pst, psymtab_include_list, includes_used,
+                  symnum * symbol_size, dbsubc_addr,
+                  dependency_list, dependencies_used);
+#else
       end_psymtab (pst, psymtab_include_list, includes_used,
                   symnum * symbol_size, end_of_text_addr,
                   dependency_list, dependencies_used);
+#endif
     }
 
   free_bincl_list (objfile);
@@ -919,10 +1076,10 @@ read_dbx_symtab (addr, objfile, text_addr, text_size)
 
 
 struct partial_symtab *
-start_psymtab (objfile, addr,
+start_psymtab (objfile, section_offsets,
               filename, textlow, ldsymoff, global_syms, static_syms)
      struct objfile *objfile;
-     CORE_ADDR addr;
+     struct section_offsets *section_offsets;
      char *filename;
      CORE_ADDR textlow;
      int ldsymoff;
@@ -930,7 +1087,7 @@ start_psymtab (objfile, addr,
      struct partial_symbol *static_syms;
 {
   struct partial_symtab *result =
-      start_psymtab_common(objfile, addr,
+      start_psymtab_common(objfile, section_offsets,
                           filename, textlow, global_syms, static_syms);
 
   result->read_symtab_private = (char *)
@@ -942,6 +1099,12 @@ start_psymtab (objfile, addr,
   STRING_OFFSET(result) = string_table_offset;
   FILE_STRING_OFFSET(result) = file_string_table_offset;
 
+  /* If we're handling an ELF file, drag some section-relocation info
+     for this source file out of the ELF symbol table, to compensate for
+     Sun brain death.  This replaces the section_offsets in this psymtab,
+     if successful.  */
+  elfstab_offset_sections (objfile, result);
+
   return result;
 }
 
@@ -1085,7 +1248,7 @@ end_psymtab (pst, include_list, num_includes, capping_symbol_offset,
       struct partial_symtab *subpst =
        allocate_psymtab (include_list[i], objfile);
 
-      subpst->addr = pst->addr;
+      subpst->section_offsets = pst->section_offsets;
       subpst->read_symtab_private =
          (char *) obstack_alloc (&objfile->psymbol_obstack,
                                  sizeof (struct symloc));
@@ -1181,17 +1344,22 @@ dbx_psymtab_to_symtab_1 (pst)
   if (LDSYMLEN(pst))           /* Otherwise it's a dummy */
     {
       /* Init stuff necessary for reading in symbols */
+      stabsread_init ();
       buildsym_init ();
       old_chain = make_cleanup (really_free_pendings, 0);
       file_string_table_offset = FILE_STRING_OFFSET (pst);
+#ifdef GDB_TARGET_IS_HPPA
+      symbol_size = obj_dbx_symbol_entry_size (pst->objfile->obfd);
+#else
       symbol_size = SYMBOL_SIZE (pst);
+#endif
 
       /* Read in this file's symbols */
       bfd_seek (pst->objfile->obfd, SYMBOL_OFFSET (pst), L_SET);
       pst->symtab =
        read_ofile_symtab (pst->objfile, LDSYMOFF(pst), LDSYMLEN(pst),
                           pst->textlow, pst->texthigh - pst->textlow,
-                          pst->addr);
+                          pst->section_offsets);
       sort_symtab_syms (pst->symtab);
 
       do_cleanups (old_chain);
@@ -1254,29 +1422,34 @@ dbx_psymtab_to_symtab (pst)
    SYM_SIZE is the size of the symbol info to read in.
    TEXT_OFFSET is the beginning of the text segment we are reading symbols for
    TEXT_SIZE is the size of the text segment read in.
-   OFFSET is a relocation offset which gets added to each symbol.  */
+   SECTION_OFFSETS are the relocation offsets which get added to each symbol. */
 
 static struct symtab *
 read_ofile_symtab (objfile, sym_offset, sym_size, text_offset, text_size,
-                  offset)
+                  section_offsets)
      struct objfile *objfile;
      int sym_offset;
      int sym_size;
      CORE_ADDR text_offset;
      int text_size;
-     int offset;
+     struct section_offsets *section_offsets;
 {
   register char *namestring;
   register struct internal_nlist *bufp;
   unsigned char type;
   unsigned max_symnum;
   register bfd *abfd;
+  struct symtab *rtn;
 
   current_objfile = objfile;
-  subfile_stack = 0;
+  subfile_stack = NULL;
 
+#ifdef GDB_TARGET_IS_HPPA
+  stringtab_global = HP_STRINGTAB (objfile);
+#else
   stringtab_global = DBX_STRINGTAB (objfile);
-  last_source_file = 0;
+#endif
+  last_source_file = NULL;
 
   abfd = objfile->obfd;
   symfile_bfd = objfile->obfd; /* Implicit param to next_text_symbol */
@@ -1297,10 +1470,27 @@ read_ofile_symtab (objfile, sym_offset, sym_size, text_offset, text_size,
 
       SET_NAMESTRING ();
 
-      processing_gcc_compilation =
-       (bufp->n_type == N_TEXT
-        && (strcmp (namestring, GCC_COMPILED_FLAG_SYMBOL) == 0
-            || strcmp(namestring, GCC2_COMPILED_FLAG_SYMBOL) == 0));
+      processing_gcc_compilation = 0;
+      if (bufp->n_type == N_TEXT)
+       {
+         if (strcmp (namestring, GCC_COMPILED_FLAG_SYMBOL) == 0)
+           processing_gcc_compilation = 1;
+         else if (strcmp (namestring, GCC2_COMPILED_FLAG_SYMBOL) == 0)
+           processing_gcc_compilation = 2;
+       }
+
+      /* Try to select a C++ demangling based on the compilation unit
+        producer. */
+
+      if (processing_gcc_compilation)
+       {
+#if 1    /* Works, but is experimental.  -fnf */
+         if (AUTO_DEMANGLING)
+           {
+             set_demangling_style (GNU_DEMANGLING_STYLE_STRING);
+           }
+#endif
+       }
     }
   else
     {
@@ -1330,30 +1520,35 @@ read_ofile_symtab (objfile, sym_offset, sym_size, text_offset, text_size,
       SWAP_SYMBOL (bufp, abfd);
 
       type = bufp->n_type;
-      if (type == (unsigned char)N_CATCH)
-       {
-         /* N_CATCH is not fixed up by the linker, and unfortunately,
-            there's no other place to put it in the .stab map.  */
-         bufp->n_value += text_offset - offset;
-       }
 
       SET_NAMESTRING ();
 
       if (type & N_STAB) {
          process_one_symbol (type, bufp->n_desc, bufp->n_value,
-                             namestring, offset, objfile);
+                             namestring, section_offsets, objfile);
       }
       /* We skip checking for a new .o or -l file; that should never
          happen in this routine. */
-      else if (type == N_TEXT
-              && (strcmp (namestring, GCC_COMPILED_FLAG_SYMBOL) == 0
-                  || strcmp (namestring, GCC2_COMPILED_FLAG_SYMBOL) == 0))
-       /* I don't think this code will ever be executed, because
-          the GCC_COMPILED_FLAG_SYMBOL usually is right before
-          the N_SO symbol which starts this source file.
-          However, there is no reason not to accept
-          the GCC_COMPILED_FLAG_SYMBOL anywhere.  */
-       processing_gcc_compilation = 1;
+      else if (type == N_TEXT)
+       {
+         /* I don't think this code will ever be executed, because
+            the GCC_COMPILED_FLAG_SYMBOL usually is right before
+            the N_SO symbol which starts this source file.
+            However, there is no reason not to accept
+            the GCC_COMPILED_FLAG_SYMBOL anywhere.  */
+
+         if (strcmp (namestring, GCC_COMPILED_FLAG_SYMBOL) == 0)
+           processing_gcc_compilation = 1;
+         else if (strcmp (namestring, GCC2_COMPILED_FLAG_SYMBOL) == 0)
+           processing_gcc_compilation = 2;
+
+#if 1    /* Works, but is experimental.  -fnf */
+         if (AUTO_DEMANGLING)
+           {
+             set_demangling_style (GNU_DEMANGLING_STYLE_STRING);
+           }
+#endif
+       }
       else if (type & N_EXT || type == (unsigned char)N_TEXT
               || type == (unsigned char)N_NBTEXT
               ) {
@@ -1378,7 +1573,9 @@ read_ofile_symtab (objfile, sym_offset, sym_size, text_offset, text_size,
   if (last_source_start_addr == 0)
     last_source_start_addr = text_offset;
 
-  return end_symtab (text_offset + text_size, 0, 0, objfile);
+  rtn = end_symtab (text_offset + text_size, 0, 0, objfile);
+  end_stabs ();
+  return (rtn);
 }
 \f
 /* This handles a single symbol from the symbol-file, building symbols
@@ -1388,18 +1585,19 @@ read_ofile_symtab (objfile, sym_offset, sym_size, text_offset, text_size,
    DESC is the desc field of the ".stab" entry.
    VALU is the value field of the ".stab" entry.
    NAME is the symbol name, in our address space.
-   OFFSET is the amount by which this object file was relocated 
-         when it was loaded into memory.  All symbols that refer
-         to memory locations need to be offset by this amount.
+   SECTION_OFFSETS is a set of amounts by which the sections of this object
+          file were relocated when it was loaded into memory.
+          All symbols that refer
+         to memory locations need to be offset by these amounts.
    OBJFILE is the object file from which we are reading symbols.
               It is used in end_symtab.  */
 
 void
-process_one_symbol (type, desc, valu, name, offset, objfile)
+process_one_symbol (type, desc, valu, name, section_offsets, objfile)
      int type, desc;
      CORE_ADDR valu;
      char *name;
-     int offset;
+     struct section_offsets *section_offsets;
      struct objfile *objfile;
 {
 #ifndef SUN_FIXED_LBRAC_BUG
@@ -1412,15 +1610,21 @@ process_one_symbol (type, desc, valu, name, offset, objfile)
   /* This remembers the address of the start of a function.  It is used
      because in Solaris 2, N_LBRAC, N_RBRAC, and N_SLINE entries are
      relative to the current function's start address.  On systems
-     other than Solaris 2, this just holds the offset value, and is
-     used to relocate these symbol types rather than OFFSET.  */
+     other than Solaris 2, this just holds the SECT_OFF_TEXT value, and is
+     used to relocate these symbol types rather than SECTION_OFFSETS.  */
   static CORE_ADDR function_start_offset;
   char *colon_pos;
 
+#ifndef        BLOCK_ADDRESS_FUNCTION_RELATIVE
+  /* N_LBRAC, N_RBRAC and N_SLINE entries are not relative to the
+     function start address, so just use the text offset.  */
+  function_start_offset = ANOFFSET (section_offsets, SECT_OFF_TEXT);
+#endif
+
   /* Something is wrong if we see real data before
      seeing a source file name.  */
 
-  if (last_source_file == 0 && type != (unsigned char)N_SO)
+  if (last_source_file == NULL && type != (unsigned char)N_SO)
     {
       /* Currently this ignores N_ENTRY on Gould machines, N_NSYM on machines
         where that code is defined.  */
@@ -1439,13 +1643,14 @@ process_one_symbol (type, desc, valu, name, offset, objfile)
 #if 0
 /* It seems that the Sun ANSI C compiler (acc) replaces N_FUN with N_GSYM and
    N_STSYM with a type code of f or F.  Can't enable this until we get some
-   stuff straightened out with psymtabs. */
+   stuff straightened out with psymtabs.  FIXME. */
 
     case N_GSYM:
     case N_STSYM:
 #endif /* 0 */
 
-      valu += offset;          /* Relocate for dynamic loading */
+      /* Relocate for dynamic loading */
+      valu += ANOFFSET (section_offsets, SECT_OFF_TEXT);
 
       /* Either of these types of symbols indicates the start of
         a new function.  We must process its "name" normally for dbx,
@@ -1472,12 +1677,7 @@ process_one_symbol (type, desc, valu, name, offset, objfile)
         and when using gcc on Solaris 2.0, these addresses are just
         absolute, or relative to the N_SO, depending on
         BLOCK_ADDRESS_ABSOLUTE.  */
-      if (processing_gcc_compilation)  /* FIXME, gcc should prob. conform */
-       function_start_offset = offset;
-      else
-        function_start_offset = valu;  
-#else
-      function_start_offset = offset;  /* Default on ordinary systems */
+      function_start_offset = valu;    
 #endif
 
       within_function = 1;
@@ -1490,17 +1690,12 @@ process_one_symbol (type, desc, valu, name, offset, objfile)
        }
       /* Stack must be empty now.  */
       if (context_stack_depth != 0)
-       complain (&lbrac_unmatched_complaint, (char *) symnum);
+       complain (&lbrac_unmatched_complaint, symnum);
 
       new = push_context (0, valu);
       new->name = define_symbol (valu, name, desc, type, objfile);
       break;
 
-    case N_CATCH:
-      /* Record the address at which this catch takes place.  */
-      define_symbol (valu+offset, name, desc, type, objfile);
-      break;
-
     case N_LBRAC:
       /* This "symbol" just indicates the start of an inner lexical
         context within a function.  */
@@ -1517,7 +1712,7 @@ process_one_symbol (type, desc, valu, name, offset, objfile)
 #ifndef SUN_FIXED_LBRAC_BUG
       if (valu < last_pc_address) {
        /* Patch current LBRAC pc value to match last handy pc value */
-       complain (&lbrac_complaint, 0);
+       complain (&lbrac_complaint);
        valu = last_pc_address;
       }
 #endif
@@ -1539,7 +1734,7 @@ process_one_symbol (type, desc, valu, name, offset, objfile)
 
       new = pop_context();
       if (desc != new->depth)
-       complain (&lbrac_mismatch_complaint, (char *) symnum);
+       complain (&lbrac_mismatch_complaint, symnum);
 
       /* Some compilers put the variable decls inside of an
          LBRAC/RBRAC block.  This macro should be nonzero if this
@@ -1571,7 +1766,7 @@ process_one_symbol (type, desc, valu, name, offset, objfile)
          /* FIXME Muzzle a compiler bug that makes end < start.  */
          if (new->start_addr > valu)
            {
-             complain(&lbrac_rbrac_complaint, 0);
+             complain (&lbrac_rbrac_complaint);
              new->start_addr = valu;
            }
          /* Make a block for the local symbols within.  */
@@ -1590,7 +1785,8 @@ process_one_symbol (type, desc, valu, name, offset, objfile)
     case N_FN:
     case N_FN_SEQ:
       /* This kind of symbol indicates the start of an object file.  */
-      valu += offset;          /* Relocate for dynamic loading */
+      /* Relocate for dynamic loading */
+      valu += ANOFFSET (section_offsets, SECT_OFF_TEXT);
       break;
 
     case N_SO:
@@ -1598,7 +1794,8 @@ process_one_symbol (type, desc, valu, name, offset, objfile)
         for one source file.
         Finish the symbol table of the previous source file
         (if any) and start accumulating a new symbol table.  */
-      valu += offset;          /* Relocate for dynamic loading */
+      /* Relocate for dynamic loading */
+      valu += ANOFFSET (section_offsets, SECT_OFF_TEXT);
 
 #ifndef SUN_FIXED_LBRAC_BUG
       last_pc_address = valu;  /* Save for SunOS bug circumcision */
@@ -1618,19 +1815,15 @@ process_one_symbol (type, desc, valu, name, offset, objfile)
             sanity checks).  If so, that one was actually the directory
             name, and the current one is the real file name.
             Patch things up. */           
-         if (previous_stab_code == N_SO
-             && current_subfile && current_subfile->dirname == NULL
-             && current_subfile->name != NULL
-             && current_subfile->name[strlen(current_subfile->name)-1] == '/')
+         if (previous_stab_code == N_SO)
            {
-             current_subfile->dirname = current_subfile->name;
-             current_subfile->name =
-                 obsavestring (name, strlen (name),
-                               &objfile -> symbol_obstack);
-             break;
+             patch_subfile_names (current_subfile, name);
+             break;            /* Ignore repeated SOs */
            }
-         (void) end_symtab (valu, 0, 0, objfile);
+         end_symtab (valu, 0, 0, objfile);
+         end_stabs ();
        }
+      start_stabs ();
       start_symtab (name, NULL, valu);
       break;
 
@@ -1640,18 +1833,19 @@ process_one_symbol (type, desc, valu, name, offset, objfile)
         a sub-source-file, one whose contents were copied or
         included in the compilation of the main source file
         (whose name was given in the N_SO symbol.)  */
-      valu += offset;          /* Relocate for dynamic loading */
-      start_subfile (name, NULL);
+      /* Relocate for dynamic loading */
+      valu += ANOFFSET (section_offsets, SECT_OFF_TEXT);
+      start_subfile (name, current_subfile->dirname);
       break;
 
     case N_BINCL:
       push_subfile ();
       add_new_header_file (name, valu);
-      start_subfile (name, NULL);
+      start_subfile (name, current_subfile->dirname);
       break;
 
     case N_EINCL:
-      start_subfile (pop_subfile (), NULL);
+      start_subfile (pop_subfile (), current_subfile->dirname);
       break;
 
     case N_EXCL:
@@ -1688,7 +1882,7 @@ process_one_symbol (type, desc, valu, name, offset, objfile)
        int i;
        struct symbol *sym =
          (struct symbol *) xmmalloc (objfile -> md, sizeof (struct symbol));
-       bzero (sym, sizeof *sym);
+       memset (sym, 0, sizeof *sym);
        SYMBOL_NAME (sym) = savestring (name, strlen (name));
        SYMBOL_CLASS (sym) = LOC_BLOCK;
        SYMBOL_NAMESPACE (sym) = (enum namespace)((long)
@@ -1700,19 +1894,63 @@ process_one_symbol (type, desc, valu, name, offset, objfile)
        break;
       }
 
-    /* The following symbol types need to have the offset added to their
-       value; then we process symbol definitions in the name.  */
-    case N_STSYM:              /* Global symbol */
-    case N_LCSYM:              /* Local symbol */
+    /* The following symbol types need to have the appropriate offset added
+       to their value; then we process symbol definitions in the name.  */
+
+    case N_STSYM:              /* Static symbol in data seg */
+    case N_LCSYM:              /* Static symbol in BSS seg */
+    case N_ROSYM:              /* Static symbol in Read-only data seg */
+     /* HORRID HACK DEPT.  However, it's Sun's furgin' fault.  FIXME.
+       Solaris2's stabs-in-coff makes *most* symbols relative
+       but leaves a few absolute.  N_STSYM and friends sit on the fence.
+       .stab "foo:S...",N_STSYM        is absolute (ld relocates it)
+       .stab "foo:V...",N_STSYM        is relative (section base subtracted).
+       This leaves us no choice but to search for the 'S' or 'V'...
+       (or pass the whole section_offsets stuff down ONE MORE function
+       call level, which we really don't want to do).  */
+      {
+       char *p;
+       p = strchr (name, ':');
+       if (p != 0 && p[1] == 'S')
+         {
+           /* FIXME!  We relocate it by the TEXT offset, in case the
+              whole module moved in memory.  But this is wrong, since
+              the sections can side around independently.  */
+           valu += ANOFFSET (section_offsets, SECT_OFF_TEXT);
+           goto define_a_symbol;
+         }
+       /* Since it's not the kludge case, re-dispatch to the right handler. */
+       switch (type) {
+       case N_STSYM:   goto case_N_STSYM;
+       case N_LCSYM:   goto case_N_LCSYM;
+       case N_ROSYM:   goto case_N_ROSYM;
+       default:        abort();
+       }
+      }
+
+    case_N_STSYM:              /* Static symbol in data seg */
     case N_DSLINE:             /* Source line number, data seg */
+      valu += ANOFFSET (section_offsets, SECT_OFF_DATA);
+      goto define_a_symbol;
+
+    case_N_LCSYM:              /* Static symbol in BSS seg */
     case N_BSLINE:             /* Source line number, bss seg */
     /*   N_BROWS:      overlaps with N_BSLINE */
+      valu += ANOFFSET (section_offsets, SECT_OFF_BSS);
+      goto define_a_symbol;
+
+    case_N_ROSYM:              /* Static symbol in Read-only data seg */
+      valu += ANOFFSET (section_offsets, SECT_OFF_RODATA);
+      goto define_a_symbol;
+
     case N_ENTRY:              /* Alternate entry point */
-      valu += offset;          /* Relocate for dynamic loading */
-      /* FALL THROUGH */
+      /* Relocate for dynamic loading */
+      valu += ANOFFSET (section_offsets, SECT_OFF_TEXT);
+      goto define_a_symbol;
 
     /* The following symbol types don't need the address field relocated,
        since it is either unused, or is absolute.  */
+    define_a_symbol:
     case N_GSYM:               /* Global variable */
     case N_NSYMS:              /* Number of symbols (ultrix) */
     case N_NOMAP:              /* No map?  (ultrix) */
@@ -1726,19 +1964,39 @@ process_one_symbol (type, desc, valu, name, offset, objfile)
        define_symbol (valu, name, desc, type, objfile);
       break;
 
+    /* We use N_OPT to carry the gcc2_compiled flag.  Sun uses it
+       for a bunch of other flags, too.  Someday we may parse their
+       flags; for now we ignore theirs and hope they'll ignore ours.  */
+    case N_OPT:                        /* Solaris 2:  Compiler options */
+      if (name)
+       {
+         if (strcmp (name, GCC2_COMPILED_FLAG_SYMBOL) == 0)
+           {
+             processing_gcc_compilation = 2;
+#if 1        /* Works, but is experimental.  -fnf */
+             if (AUTO_DEMANGLING)
+               {
+                 set_demangling_style (GNU_DEMANGLING_STYLE_STRING);
+               }
+#endif
+           }
+       }
+      break;
+
     /* The following symbol types can be ignored.  */
     case N_OBJ:                        /* Solaris 2:  Object file dir and name */
-    case N_OPT:                        /* Solaris 2:  Optimization level? */
     /*   N_UNDF:                  Solaris 2:  file separator mark */
     /*   N_UNDF: -- we will never encounter it, since we only process one
                    file's symbols at once.  */
+    case N_ENDM:               /* Solaris 2:  End of module */
+    case N_MAIN:               /* Name of main routine.  */
       break;
       
     /* The following symbol types we don't know how to process.  Handle
        them in a "default" way, but complain to people who care.  */
     default:
+    case N_CATCH:              /* Exception handler catcher */
     case N_EHDECL:             /* Exception handler name */
-    case N_MAIN:               /* Name of main routine (not used in C) */
     case N_PC:                 /* Global symbol in Pascal */
     case N_M2C:                        /* Modula-2 compilation unit */
     /*   N_MOD2:       overlaps with N_EHDECL */
@@ -1799,25 +2057,25 @@ copy_pending (beg, begi, end)
    adjusted for elf details. */
 
 void
-DEFUN(elfstab_build_psymtabs, (objfile, addr, mainline, 
+elfstab_build_psymtabs (objfile, section_offsets, mainline, 
                               staboffset, stabsize,
-                              stabstroffset, stabstrsize),
-      struct objfile *objfile AND
-      CORE_ADDR addr AND
-      int mainline AND
-      unsigned int staboffset AND
-      unsigned int stabsize AND
-      unsigned int stabstroffset AND
-      unsigned int stabstrsize)
+                              stabstroffset, stabstrsize)
+      struct objfile *objfile;
+      struct section_offsets *section_offsets;
+      int mainline;
+      file_ptr staboffset;
+      unsigned int stabsize;
+      file_ptr stabstroffset;
+      unsigned int stabstrsize;
 {
   int val;
   bfd *sym_bfd = objfile->obfd;
   char *name = bfd_get_filename (sym_bfd);
   struct dbx_symfile_info *info;
 
-  /* Allocate struct to keep track of the symfile */
-  objfile->sym_private = (PTR) xmmalloc (objfile->md, sizeof (*info));
-  info = (struct dbx_symfile_info *)objfile->sym_private;
+  /* There is already a dbx_symfile_info allocated by our caller.
+     It might even contain some info from the ELF symtab to help us.  */
+  info = (struct dbx_symfile_info *) objfile->sym_private;
 
   DBX_TEXT_SECT (objfile) = bfd_get_section_by_name (sym_bfd, ".text");
   if (!DBX_TEXT_SECT (objfile))
@@ -1829,7 +2087,7 @@ DEFUN(elfstab_build_psymtabs, (objfile, addr, mainline,
   DBX_STRINGTAB_SIZE (objfile) = stabstrsize;
   DBX_SYMTAB_OFFSET  (objfile) = staboffset;
   
-  if (stabstrsize < 0)
+  if (stabstrsize < 0) /* FIXME:  stabstrsize is unsigned; never true! */
     error ("ridiculous string table size: %d bytes", stabstrsize);
   DBX_STRINGTAB (objfile) = (char *)
     obstack_alloc (&objfile->psymbol_obstack, stabstrsize+1);
@@ -1843,6 +2101,7 @@ DEFUN(elfstab_build_psymtabs, (objfile, addr, mainline,
   if (val != stabstrsize)
     perror_with_name (name);
 
+  stabsread_new_init ();
   buildsym_new_init ();
   free_header_files ();
   init_header_files ();
@@ -1853,7 +2112,29 @@ DEFUN(elfstab_build_psymtabs, (objfile, addr, mainline,
   /* In an elf file, we've already installed the minimal symbols that came
      from the elf (non-stab) symbol table, so always act like an
      incremental load here. */
-  dbx_symfile_read (objfile, addr, 0);
+  dbx_symfile_read (objfile, section_offsets, 0);
+}
+\f
+/* Parse the user's idea of an offset for dynamic linking, into our idea
+   of how to represent it for fast symbol reading.  */
+
+struct section_offsets *
+dbx_symfile_offsets (objfile, addr)
+     struct objfile *objfile;
+     CORE_ADDR addr;
+{
+  struct section_offsets *section_offsets;
+  int i;
+  section_offsets = (struct section_offsets *)
+    obstack_alloc (&objfile -> psymbol_obstack,
+                  sizeof (struct section_offsets) +
+                         sizeof (section_offsets->offsets) * (SECT_OFF_MAX-1));
+
+  for (i = 0; i < SECT_OFF_MAX; i++)
+    ANOFFSET (section_offsets, i) = addr;
+  
+  return section_offsets;
 }
 \f
 /* Register our willingness to decode symbols for SunOS and a.out and
@@ -1866,6 +2147,7 @@ static struct sym_fns sunos_sym_fns =
   dbx_symfile_init,    /* sym_init: read initial info, setup for sym_read() */
   dbx_symfile_read,    /* sym_read: read a symbol file into symtab */
   dbx_symfile_finish,  /* sym_finish: finished with file, cleanup */
+  dbx_symfile_offsets, /* sym_offsets: parse user's offsets to internal form */
   NULL                 /* next: pointer to next struct sym_fns */
 };
 
@@ -1877,6 +2159,7 @@ static struct sym_fns aout_sym_fns =
   dbx_symfile_init,    /* sym_init: read initial info, setup for sym_read() */
   dbx_symfile_read,    /* sym_read: read a symbol file into symtab */
   dbx_symfile_finish,  /* sym_finish: finished with file, cleanup */
+  dbx_symfile_offsets, /* sym_offsets: parse user's offsets to internal form */
   NULL                 /* next: pointer to next struct sym_fns */
 };
 
@@ -1888,6 +2171,21 @@ static struct sym_fns bout_sym_fns =
   dbx_symfile_init,    /* sym_init: read initial info, setup for sym_read() */
   dbx_symfile_read,    /* sym_read: read a symbol file into symtab */
   dbx_symfile_finish,  /* sym_finish: finished with file, cleanup */
+  dbx_symfile_offsets, /* sym_offsets: parse user's offsets to internal form */
+  NULL                 /* next: pointer to next struct sym_fns */
+};
+
+/* This is probably a mistake.  FIXME.  Why can't the HP's use an ordinary
+   file format name with an -hppa suffix?  */
+static struct sym_fns hppa_sym_fns =
+{
+  "hppa",              /* sym_name: name or name prefix of BFD target type */
+  4,                   /* sym_namelen: number of significant sym_name chars */
+  dbx_new_init,                /* sym_new_init: init anything gbl to entire symtab */
+  dbx_symfile_init,    /* sym_init: read initial info, setup for sym_read() */
+  dbx_symfile_read,    /* sym_read: read a symbol file into symtab */
+  dbx_symfile_finish,  /* sym_finish: finished with file, cleanup */
+  dbx_symfile_offsets, /* sym_offsets: parse user's offsets to internal form */
   NULL                 /* next: pointer to next struct sym_fns */
 };
 
@@ -1897,4 +2195,5 @@ _initialize_dbxread ()
   add_symtab_fns(&sunos_sym_fns);
   add_symtab_fns(&aout_sym_fns);
   add_symtab_fns(&bout_sym_fns);
+  add_symtab_fns(&hppa_sym_fns);
 }
This page took 0.03972 seconds and 4 git commands to generate.