* Makefile.in (ALLDEPFILES): Add hpread.c.
authorJeff Law <law@redhat.com>
Fri, 19 Aug 1994 16:48:51 +0000 (16:48 +0000)
committerJeff Law <law@redhat.com>
Fri, 19 Aug 1994 16:48:51 +0000 (16:48 +0000)
        (hpread.o): Add dependencies.

        * somread.c: Do not include "aout/aout64.h".  SOM has nothing to
        do with a.out.
        (BYTES_IN_WORD): Delete.
        (som_symfile_read): Call hpread_build_psymtabs to build any
        minimal symbols based on the HP C native debug symbols.
        (som_symfile_finish): Call hpread_symfile_finish.
        (som_symfile_init): Call hpread_symfile_init.
        * config/pa/tm-hppa.h (HPREAD_ADJUST_STACK_ADDRESS): Define.
        * hppa-tdep.c (hpread_adjust_stack_address): New function.

        * config/pa/hppabsd.mh (NATDEPFILES): Add hpread.o
        * config/pa/hppahpux.mh (NATDEPFILES): Likewise.
        * hpread.c: New file.

gdb/.Sanitize
gdb/ChangeLog.hpread [new file with mode: 0644]
gdb/Makefile.in
gdb/config/pa/.Sanitize
gdb/config/pa/hppabsd.mh
gdb/config/pa/hppahpux.mh
gdb/hppa-tdep.c
gdb/hpread.c [new file with mode: 0644]
gdb/somread.c

index 3f446a0dabc4761bf5183f671d742130ef1e9af5..d5ff460030e5561e98b2dd7610be334cacd0c0c1 100644 (file)
@@ -43,6 +43,20 @@ else
        fi
 fi
 
+hpread_files="hpread.c ChangeLog.hpread"
+
+if ( echo $* | grep keep\-hpread > /dev/null ) ; then
+       keep_these_too="${hpread_files} ${keep_these_too}"
+       if [ -n "${verbose}" ] ; then
+               echo Keeping ${hpread_files}
+       fi
+else
+       lose_these_too="${hpread_files} ${lose_these_too}"
+       if [ -n "${verbose}" ] ; then
+               echo Deleting ${hpread_files}
+       fi
+fi
+
 # All files listed between the "Things-to-keep:" line and the
 # "Files-to-sed:" line will be kept.  All other files will be removed.
 # Directories listed in this section will have their own Sanitize
@@ -372,4 +386,30 @@ else
        done
 fi
 
+echo Removing traces of \"hpread\"...
+
+# Don't try to clean directories here, as the 'mv' command will fail.
+# Also, grep fails on NFS mounted directories.
+if ( echo $* | grep keep\-hpread > /dev/null ) ; then
+       for i in * ; do
+               if test ! -d $i && (grep sanitize-hpread $i > /dev/null) ; then
+                       echo Keeping hpread stuff in $i
+               fi
+       done
+else
+       for i in * ; do
+               if test ! -d $i && (grep sanitize-hpread $i > /dev/null) ; then
+                       echo Removing traces of \"hpread\" out of $i...
+                       cp $i new
+                       sed '/start\-sanitize\-hpread/,/end-\sanitize\-hpread/d' < $i > new
+                       if [ -n "${safe}" -a ! -f .Recover/$i ] ; then
+                               echo Caching $i in .Recover...
+                               mv $i .Recover
+                       fi
+                       mv new $i
+               fi
+       done
+fi
+
+
 # End of file.
diff --git a/gdb/ChangeLog.hpread b/gdb/ChangeLog.hpread
new file mode 100644 (file)
index 0000000..375ffd1
--- /dev/null
@@ -0,0 +1,204 @@
+Fri Aug 19 10:36:15 1994  Jeff Law  (law@snake.cs.utah.edu)
+
+       * Makefile.in (ALLDEPFILES): Add hpread.c.
+       (hpread.o): Add dependencies.
+
+       * somread.c: Do not include "aout/aout64.h".  SOM has nothing to
+       do with a.out.
+       (BYTES_IN_WORD): Delete.
+       (som_symfile_read): Call hpread_build_psymtabs to build any
+       minimal symbols based on the HP C native debug symbols.
+       (som_symfile_finish): Call hpread_symfile_finish.
+       (som_symfile_init): Call hpread_symfile_init.
+       * config/pa/tm-hppa.h (HPREAD_ADJUST_STACK_ADDRESS): Define.
+       * hppa-tdep.c (hpread_adjust_stack_address): New function.
+
+       * config/pa/hppabsd.mh (NATDEPFILES): Add hpread.o
+       * config/pa/hppahpux.mh (NATDEPFILES): Likewise.
+       * hpread.c: New file.
+
+Fri Aug 12 19:30:53 1994  Jeff Law  (law@snake.cs.utah.edu)
+
+       * hpread.c: Delete rest of TODO list.  Do not include "libbfd.h",
+       <time.h>, <sys/types.h>, "demangle.h", <sys/file.h>,
+       "expression.h", "language.h", "gdbtypes.h", "demangleh".
+       Move all global variables into the private symbol table structure
+       and add accessor macros.  Update some comments.
+       (hpread_build_psymtabs): Delete dbsubc_addr, we don't need it.
+       (hpread_end_psymtab): New function to end a partial symbol table,
+       all callers changed (no more bogus sharing with dbxread.c).
+
+Mon Aug 08 15:34:13 1994  Jeff Law  (law@snake.cs.utah.edu)
+
+       * hpread.c (hpread_process_one_debug_symbol): Fix block scoping
+       problem (losing localvars on the close-brace instead of after
+       the close brace).
+
+Wed Jul 06 12:39:07 1994  Jeff Law  (law@snake.cs.utah.edu)
+
+       * hpread.c: More cleanups.  Delete lots of trailing whitespace.
+       Remove some items from the TODO list and notes throughout code
+       for things which need fixing.  Add more comments.
+       Document bogus struct symloc sharing with dbxread.c.  Delete more
+       useless variables.  Add more PARAM prototypes.  Fixup more
+       indention problems that have crept in.
+       (SET_NAMESTRING): Accept new namep and objfile arguments so that
+       it doesn't depend on the variable names on the procedures it's
+       used from.  
+       (hpread_symfile_init): Delete incorrect checks for bogus sizes of
+       the debug sections.
+
+Mon Jul 04 19:48:03 1994  Jeff Law  (law@snake.cs.utah.edu)
+
+       * hpread.c (hpread_symfile_init): Make sure to initialize all the
+       private data to zero.  Not having any HP C debug symbols is not an
+       error.  Just return.
+
+Fri Jul 01 19:50:21 1994  Jeff Law  (law@snake.cs.utah.edu)
+
+       * hpread.c: Change contribution notice to the Cygnus/Utah agreed
+       upon notice.  Delete some stuff from the TODO list.  Rework
+       many comments to be clearer.  Major cleanups.  Consistently
+       use "hpread_" prefix.  Delete unnecessary macros, structures
+       variables, fiels, functions and #if 0 code.  Mark code which
+       still needs to be cleaned up.  PARAMize and make most functions
+       static. Fix error checking when reading in the debug section
+       contents.  No more minimal symbol table handling in this code!
+
+Mon Mar 21 10:09:06 1994  Jeff Law  (law@snake.cs.utah.edu)
+
+       * hpread.c (_initialize_hpuxread): Don't call add_symtab_fns if
+       HPREAD is not defined.
+
+Sun Mar 13 17:19:03 1994  Jeff Law  (law@snake.cs.utah.edu)
+
+       * hpread.c (read_hpux_symtab: Correctly determine the namespace
+       and address class of SVAR, DVAR, TYPEDEF, TAGDEF, CONST, and
+       MEMENUM symbols.  Do not include function-scoped variables in
+       the partial symbol table.
+
+Sun Feb  6 15:56:09 1994  Jeff Law  (law@wild.cs.utah.edu)
+
+       * hpread.c (hpux_symfile_init): Use obj_som_* rather than obj_* to
+       access BFD private data.  Search for the "$TEXT$" space rather
+       than ".text".
+       (hppa_sym_fns): Add bfd target flavour to initializer.
+
+Thu Dec 16 09:14:58 1993  Jeff Law  (law@snake.cs.utah.edu)
+
+       * hpread.c (read_hp_function_type): Correctly handle
+       pass-by-value structures > 64bits in size.
+       (process_one_debug_symbol): Likewise.
+
+Tue Nov  2 03:01:01 1993  Jeff Law  (law@snake.cs.utah.edu)
+
+        * hpread.c: Include <time.h> and <sys/types.h>.  Change include
+        of "libhppa.h" to "som.h".
+        (BYTES_IN_WORD): Define.
+        (hppa_sym_fns): "hppa" is 4 characters, not 5.
+       
+Wed Sep 29 17:20:54 1993  Jeff Law  (law@snake.cs.utah.edu)
+
+       * hpread.c (read_hpux_symtab): When a K_END is found for a
+       K_MODULE, clear the have_module and have_name flags.
+
+Sun Aug 22 22:50:32 1993  Jeff Law  (law@snake.cs.utah.edu)
+
+       * hpread.c (get_textlow): Don't go past a K_END when looking for a
+       K_FUNCTION.  Avoids losing on source files with no functions. 
+
+Wed Aug 18 21:42:52 1993  Jeff Law  (law@snake.cs.utah.edu)
+
+       * hpread.c (read_hpux_symtab): Call SET_NAMESTRING for K_MODULE
+       debug symbols.
+
+Mon Aug 16 09:52:33 1993  Jeff Law  (law@snake.cs.utah.edu)
+
+       * hpread.c: Add U Utah contribution notice.  Add TODO list.
+       (hp_type_lookup): Use TYPE_NAME and TYPE_TAG_NAME.
+       (process_one_debug_symbol): Likewise.
+
+Tue Jul 20 14:14:59 1993  Jeff Law  (law@snake.cs.utah.edu)
+
+       * hpread.c (read_hp_array_type): Handle "char foo[]".
+
+Thu Jul  1 15:46:10 1993  Jeff Law  (law@snake.cs.utah.edu)
+
+       * hpread.c: Run through gnu-indent.
+
+Mon Jun 28 19:00:21 1993  Jeff Law  (law@snake.cs.utah.edu)
+
+       * hpread.c: Do not include libhppax.  Instead include libhppa.h
+       and hpux-symtab.h.  Misc indention fixes.
+       (find_unwind_entry): Add PARAM prototype.
+       (read_hpux_symtab): More fixes for names and sizes of structs,
+       unions, enums, typedefs, and tagdefs.
+       (read_hp_enum_type, read_hp_struct_type): Likewise.
+       (read_hp_set_type, read_hp_subrange_type): Likewise.
+       (hp_type_lookup, process_one_debug_symbol): Likewise.
+       (process_one_debug_symbol): Search forward from the K_FUNCTION for
+       the first K_BEGIN when setting the line number associated with a
+       function.  Avoid unnecessary calls to savestring.
+       (hp_alloc_type): Initialize TYPE_CPLUS_SPECIFIC here.  Remove
+       most cases where we set it elsewhere.
+       (hppa_sym_fns): Use "hppa" instead of hppax since hpread.c and
+       paread.c use the same BFD backend now.  All references changed.
+       (hpux_symfile_init): Allocate space to hold the debugging section
+       contents on the symbol obstack.
+
+Wed Jun 23 16:33:36 1993  Jeff Law  (law@snake.cs.utah.edu)
+
+       * hpread.c: Document a few functions, misc cleanups.  Update
+       copyright to reflect the first "release" of this file.
+       (struct hpux_symfile_info): Delete unneeded fields.  Keep pointers
+       to the contents of the debug sections rather than offsets within
+       the file itself.  Corresponding changes to the accessor macros.
+       (sl_symbol_size, slt_symbuf): Delete unneeded global variables.
+       (slt_symbuf_start, slt_symbuf_end, lntt_symbuf): Likewise.
+       (lntt_symbuf_start, lntt_symbuf_end, gntt_symbuf): Likewise.
+       (gntt_symbuf_start, gntt_symbuf_end): Likewise.
+       (fill_slt_symbuf, fill_lntt_symbuf): Delete unneeded functions.
+       (fill_gntt_symbuf): Likewise.
+       (get_lntt, get_gntt, get_slt): Simplify.
+       (hpux_symfile_init): Read and store the contents of the debugging
+       sections.  Do error checking on memory allocation and BFD calls.
+       (read_hpux_symtab): Delete KERNELDEBUG crud.  Ignore debug symbols
+       which are not needed for building partial symbol tables.  Handle
+       K_CONST, K_TYPEDEF, and K_TAGDEF just like K_SVAR and K_DVAR.
+       (read_ofile_symtab): Delete useless processing_gcc_compilation stuff.
+       (read_hp_struct_type): Initialize TYPE_CPLUS_SPECIFIC.
+       (read_hp_set_type, read_hp_array_type): Likewise.
+       (read_hp_subrange_type, hp_type_lookup): Likewise.
+
+Tue Jun 22 11:03:13 1993  Jeff Law  (law@snake.cs.utah.edu)
+
+       * hpread.c: Delete useless #if 1 statements.
+       (hp_type_translate): Use T_LONG, T_UNS_LONG, and T_DOUBLE instead
+       of magic integers.  Fix handling for T_UNS_INT.  Abort if the type
+       passed in is not an "immediate" type.
+       (read_hp_enum_type): Properly compute the size of the type.
+       (read_hp_array_type): Likewise.
+       (hp_type_lookup): Prefix the names of structs, unions and enums
+       with "struct", "union", and "enum" as appropriate.
+
+Mon Jun 21 10:13:42 1993  Jeff Law  (law@snake.cs.utah.edu)
+
+       * hpread.c: Include "demangle.h".
+       (process_one_debug_symbol): Set the SYMBOL_LANGUAGE and
+       SYMBOL_INIT_DEMANGLED_NAME for the current symbol.  Adjust
+       SYMBOL_VALUE for local variables in the stack by the size of the
+       current function's stack (found in unwind descriptor).  Keep
+       better track of the current unwind descriptor. 
+
+Wed Jun 16 14:34:10 1993  Jeff Law  (law@snake.cs.utah.edu)
+
+       * hpread.c (hp_type_translate): Fix promotion bugs from
+       char to short and short to int.
+
+Thu Jun 10 11:27:34 1993  Jeff Law  (law@snake.cs.utah.edu)
+
+       * hpread.c (read_hp_function_type): Adjust SYMBOL_VALUE for
+       arguments in the stack by the size of the current function's stack
+       (found in the unwind descriptor).
+       (process_one_debug_symbol): Likewise.  Keep track of the current
+       function's unwind descriptor.
index cb54b34d2ddc14c20609fb2df9f16cea406012bb..213f2943934701db49908e80e5319da2a4fd3953 100644 (file)
@@ -860,6 +860,11 @@ unexport CHILLFLAGS CHILL_LIB CHILL_FOR_TARGET :
 # These are things from config/*/*.m? fragments.  There is no good reason
 # why they are separate from the lists of files above.
 
+HPREAD_SOURCE=
+# start-sanitize-hpread
+HPREAD_SOURCE=hpread.c
+# end-sanitize-hpread
+
 ALLDEPFILES = 29k-share/udi/udip2soc.c 29k-share/udi/udr.c \
        29k-share/udi/udi2go32.c \
        a29k-pinsn.c a29k-tdep.c a68v-nat.c alpha-nat.c alpha-tdep.c \
@@ -882,7 +887,7 @@ ALLDEPFILES = 29k-share/udi/udip2soc.c 29k-share/udi/udr.c \
        nindy-share/Onindy.c nindy-share/nindy.c \
        nindy-share/ttyflush.c nindy-tdep.c \
        ns32k-pinsn.c ns32km3-nat.c osfsolib.c \
-       somread.c procfs.c pyr-pinsn.c pyr-tdep.c pyr-xdep.c \
+       somread.c $(HPREAD_SOURCE) procfs.c pyr-pinsn.c pyr-tdep.c pyr-xdep.c \
        remote-adapt.c remote-bug.c remote-e7000.c remote-eb.c remote-es.c \
        remote-hms.c remote-mips.c \
        remote-mm.c remote-mon.c remote-nindy.c remote-os9k.c remote-sim.c \
@@ -1240,6 +1245,11 @@ osfsolib.o: osfsolib.c $(command_h) $(defs_h) $(gdbcore_h) $(inferior_h) \
 somread.o: somread.c $(bfd_h) buildsym.h complaints.h $(defs_h) \
        gdb-stabs.h objfiles.h symfile.h $(symtab_h)
 
+# start-sanitize-hpread
+hpread.o: hpread.c $(bfd_h) buildsym.h complaints.h $(defs_h) \
+       gdb-stabs.h objfiles.h symfile.h $(symtab_h)
+# end-sanitize-hpread
+
 parse.o: parse.c $(command_h) $(defs_h) $(expression_h) $(frame_h) \
        $(gdbtypes_h) language.h parser-defs.h $(symtab_h) $(value_h)
 
index 4d80e155143fed2818b4b9cd6f47c0b8434208cb..e63098dc63ceaf290a53787b63b38f8aff339d12 100644 (file)
@@ -41,4 +41,29 @@ Things-to-lose:
 
 Do-last:
 
+echo Removing traces of \"hpread\"...
+
+# Don't try to clean directories here, as the 'mv' command will fail.
+# Also, grep fails on NFS mounted directories.
+if ( echo $* | grep keep\-hpread > /dev/null ) ; then
+       for i in * ; do
+               if test ! -d $i && (grep sanitize-hpread $i > /dev/null) ; then
+                       echo Keeping hpread stuff in $i
+               fi
+       done
+else
+       for i in * ; do
+               if test ! -d $i && (grep sanitize-hpread $i > /dev/null) ; then
+                       echo Removing traces of \"hpread\" out of $i...
+                       cp $i new
+                       sed '/start\-sanitize\-hpread/,/end-\sanitize\-hpread/d' < $i > new
+                       if [ -n "${safe}" -a ! -f .Recover/$i ] ; then
+                               echo Caching $i in .Recover...
+                               mv $i .Recover
+                       fi
+                       mv new $i
+               fi
+       done
+fi
+
 # End of file.
index bf26c41ceeeb093c80741f428cb06cdfee698287..639140e9a145c8a847b465222d312c5571df83c2 100644 (file)
@@ -1,5 +1,9 @@
 # Host: Hewlett-Packard PA-RISC machine, running BSD
+HPREAD=
+# start-sanitize-hpread
+HPREAD=hpread.o
+# end-sanitize-hpread
 XDEPFILES= 
 XM_FILE= xm-hppab.h
 NAT_FILE= nm-hppab.h
-NATDEPFILES= hppab-nat.o coredep.o corelow.o exec.o inftarg.o fork-child.o somread.o infptrace.o
+NATDEPFILES= hppab-nat.o coredep.o corelow.o exec.o inftarg.o fork-child.o somread.o infptrace.o $(HPREAD)
index 5ebb7b52084b43fe77618187b93b8b21c0245293..819167ee7c577422fb54b45097b5cc68b184e8ec 100644 (file)
@@ -1,9 +1,13 @@
 # Host: Hewlett-Packard PA-RISC machine, running HPUX 
+HPREAD=
+# start-sanitize-hpread
+HPREAD=hpread.o
+# end-sanitize-hpread
 TERMCAP = -lcurses
 XDEPFILES= ser-tcp.o
 XM_FILE= xm-hppah.h
 NAT_FILE= nm-hppah.h
-NATDEPFILES= hppah-nat.o coredep.o corelow.o inftarg.o fork-child.o somread.o infptrace.o
 REGEX=regex.o
 REGEX1=regex.o
 HOST_IPC=-DBSD_IPC -DPOSIX_WAIT
+NATDEPFILES= hppah-nat.o coredep.o corelow.o inftarg.o fork-child.o somread.o infptrace.o $(HPREAD)
index 270d54e73fe263106f11712125b90b591b857826..3ff2b10bb71911944c00a055f743c458293fb0d4 100644 (file)
@@ -508,6 +508,27 @@ find_unwind_entry(pc)
   return NULL;
 }
 
+/* start-sanitize-hpread */
+/* Return the adjustment necessary to make for addresses on the stack
+   as presented by hpread.c.
+
+   This is necessary because of the stack direction on the PA and the
+   bizarre way in which someone (?) decided they wanted to handle
+   frame pointerless code in GDB.  */
+int
+hpread_adjust_stack_address (func_addr)
+     CORE_ADDR func_addr;
+{
+  struct unwind_table_entry *u;
+
+  u = find_unwind_entry (func_addr);
+  if (!u)
+    return 0;
+  else
+    return u->Total_frame_size << 3;
+}
+/* end-sanitize-hpread */
+
 /* Called to determine if PC is in an interrupt handler of some
    kind.  */
 
diff --git a/gdb/hpread.c b/gdb/hpread.c
new file mode 100644 (file)
index 0000000..f3acc7e
--- /dev/null
@@ -0,0 +1,2044 @@
+/* Read hp debug symbols and convert to internal format, for GDB.
+   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 University of Utah
+   and by Cygnus Support.  */
+
+#include "defs.h"
+#include "bfd.h"
+#include <string.h>
+#include "hpux-symtab.h"
+#include "syms.h"
+#include "symtab.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "buildsym.h"
+#include "complaints.h"
+#include "gdb-stabs.h"
+#include "gdbtypes.h"
+
+/* Private information attached to an objfile which we use to find
+   and internalize the HP C debug symbols within that objfile.  */
+
+struct hpread_symfile_info
+{
+  /* The contents of each of the debug sections (there are 4 of them).  */
+  char *gntt;
+  char *lntt;
+  char *slt;
+  char *vt;
+
+  /* We keep the size of the $VT$ section for range checking.  */
+  unsigned int vt_size;
+
+  /* Some routines still need to know the number of symbols in the
+     main debug sections ($LNTT$ and $GNTT$). */
+  unsigned int lntt_symcount;
+  unsigned int gntt_symcount;
+
+  /* To keep track of all the types we've processed.  */
+  struct type **type_vector;
+  int type_vector_length;
+
+  /* Keeps track of the beginning of a range of source lines.  */
+  SLTPOINTER sl_index;
+
+  /* Some state variables we'll need.  */
+  int have_module;
+  int within_function;
+
+   /* Keep track of the current function's address.  We may need to look
+      up something based on this address.  */
+   unsigned int current_function_value;
+
+};
+
+/* Accessor macros to get at the fields.  */
+#define HPUX_SYMFILE_INFO(o) \
+  ((struct hpread_symfile_info *)((o)->sym_private))
+#define GNTT(o)                 (HPUX_SYMFILE_INFO(o)->gntt)
+#define LNTT(o)                 (HPUX_SYMFILE_INFO(o)->lntt)
+#define SLT(o)                  (HPUX_SYMFILE_INFO(o)->slt)
+#define VT(o)                   (HPUX_SYMFILE_INFO(o)->vt)
+#define VT_SIZE(o)              (HPUX_SYMFILE_INFO(o)->vt_size)
+#define LNTT_SYMCOUNT(o)        (HPUX_SYMFILE_INFO(o)->lntt_symcount)
+#define GNTT_SYMCOUNT(o)        (HPUX_SYMFILE_INFO(o)->gntt_symcount)
+#define TYPE_VECTOR(o)          (HPUX_SYMFILE_INFO(o)->type_vector)
+#define TYPE_VECTOR_LENGTH(o)   (HPUX_SYMFILE_INFO(o)->type_vector_length)
+#define SL_INDEX(o)             (HPUX_SYMFILE_INFO(o)->sl_index)
+#define HAVE_MODULE(o)          (HPUX_SYMFILE_INFO(o)->have_module)
+#define WITHIN_FUNCTION(o)      (HPUX_SYMFILE_INFO(o)->within_function)
+#define CURRENT_FUNCTION_VALUE(o) (HPUX_SYMFILE_INFO(o)->current_function_value)
+
+/* Given the native debug symbol SYM, set NAMEP to the name associated
+   with the debug symbol.  Note we may be called with a debug symbol which
+   has no associated name, in that case we return an empty string.
+
+   Also note we "know" that the name for any symbol is always in the
+   same place.  Hence we don't have to conditionalize on the symbol type.  */
+#define SET_NAMESTRING(SYM, NAMEP, OBJFILE) \
+  if (! hpread_has_name ((SYM)->dblock.kind)) \
+    *NAMEP = ""; \
+  else if (((unsigned)(SYM)->dsfile.name) >= VT_SIZE (OBJFILE)) \
+    { \
+      complain (&string_table_offset_complaint, (char *) symnum); \
+      *NAMEP = ""; \
+    } \
+  else \
+    *NAMEP = (SYM)->dsfile.name + VT (OBJFILE)
+
+/* 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.
+
+   For hpuxread this structure contains the offset within the file symbol table
+   of first local symbol for this file, and length (in bytes) of the section
+   of the symbol table devoted to this file's symbols (actually, the section
+   bracketed may contain more than just this file's symbols).
+
+   If ldsymlen is 0, the only reason for this thing's existence is the
+   dependency list.  Nothing else will happen when it is read in.  */
+
+#define LDSYMOFF(p) (((struct symloc *)((p)->read_symtab_private))->ldsymoff)
+#define LDSYMLEN(p) (((struct symloc *)((p)->read_symtab_private))->ldsymlen)
+#define SYMLOC(p) ((struct symloc *)((p)->read_symtab_private))
+
+struct symloc
+{
+  int ldsymoff;
+  int ldsymlen;
+};
+
+/* FIXME: Shouldn't this stuff be in a .h file somewhere?  */
+/* Nonzero means give verbose info on gdb action.  */
+extern int info_verbose;
+
+/* Complaints about the symbols we have encountered.  */
+extern struct complaint string_table_offset_complaint;
+extern struct complaint lbrac_unmatched_complaint;
+extern struct complaint lbrac_mismatch_complaint;
+
+\f
+void hpread_symfile_init  PARAMS ((struct objfile *));
+
+static struct type *hpread_alloc_type
+  PARAMS ((DNTTPOINTER, struct objfile *));
+
+static struct type **hpread_lookup_type
+  PARAMS ((DNTTPOINTER, struct objfile *));
+
+static struct type *hpread_read_enum_type
+  PARAMS ((DNTTPOINTER, union dnttentry *, struct objfile *));
+
+static struct type *hpread_read_set_type
+  PARAMS ((DNTTPOINTER, union dnttentry *, struct objfile *));
+
+static struct type *hpread_read_subrange_type
+  PARAMS ((DNTTPOINTER, union dnttentry *, struct objfile *));
+
+static struct type *hpread_read_struct_type
+  PARAMS ((DNTTPOINTER, union dnttentry *, struct objfile *));
+
+void hpread_build_psymtabs
+  PARAMS ((struct objfile *, struct section_offsets *, int));
+
+void hpread_symfile_finish PARAMS ((struct objfile *));
+
+static struct partial_symtab *hpread_start_psymtab
+  PARAMS ((struct objfile *, struct section_offsets *, char *, CORE_ADDR, int,
+          struct partial_symbol *, struct partial_symbol *));
+
+static struct partial_symtab *hpread_end_psymtab
+  PARAMS ((struct partial_symtab *, char **, int, int, CORE_ADDR,
+          struct partial_symtab **, int));
+
+static struct symtab *hpread_expand_symtab
+  PARAMS ((struct objfile *, int, int, CORE_ADDR, int,
+          struct section_offsets *, char *));
+
+static void hpread_process_one_debug_symbol
+  PARAMS ((union dnttentry *, char *, struct section_offsets *,
+          struct objfile *, CORE_ADDR, int, char *, int));
+
+static SLTPOINTER hpread_record_lines
+  PARAMS ((struct subfile *, SLTPOINTER, SLTPOINTER, struct objfile *));
+
+static struct type *hpread_read_function_type
+  PARAMS ((DNTTPOINTER, union dnttentry *, struct objfile *));
+
+static struct type * hpread_type_lookup
+  PARAMS ((DNTTPOINTER, struct objfile *));
+
+static unsigned long hpread_get_depth
+  PARAMS ((SLTPOINTER, struct objfile *));
+
+static unsigned long hpread_get_line
+  PARAMS ((SLTPOINTER, struct objfile *));
+
+static ADDRESS hpread_get_location
+  PARAMS ((SLTPOINTER, struct objfile *));
+
+static int hpread_type_translate PARAMS ((DNTTPOINTER));
+static unsigned long hpread_get_textlow PARAMS ((int, int, struct objfile *));
+static union dnttentry *hpread_get_gntt PARAMS ((int, struct objfile *));
+static union dnttentry *hpread_get_lntt PARAMS ((int, struct objfile *));
+static union sltentry *hpread_get_slt PARAMS ((int, struct objfile *));
+static void hpread_psymtab_to_symtab PARAMS ((struct partial_symtab *));
+static void hpread_psymtab_to_symtab_1 PARAMS ((struct partial_symtab *));
+static int hpread_has_name PARAMS ((KINDTYPE));
+
+\f
+/* Initialization for reading native HP C debug symbols from OBJFILE.
+
+   It's only purpose in life is to set up the symbol reader's private
+   per-objfile data structures, and read in the raw contents of the debug
+   sections (attaching pointers to the debug info into the private data
+   structures.
+
+   Since BFD doesn't know how to read debug symbols in a format-independent
+   way (and may never do so...), we have to do it ourselves.  Note we may
+   be called on a file without native HP C debugging symbols.
+   FIXME, there should be a cleaner peephole into the BFD environment here.  */
+
+void
+hpread_symfile_init (objfile)
+     struct objfile *objfile;
+{
+  asection *vt_section, *slt_section, *lntt_section, *gntt_section;
+
+  /* Allocate struct to keep track of the symfile */
+  objfile->sym_private = (PTR)
+    xmmalloc (objfile->md, sizeof (struct hpread_symfile_info));
+  memset (objfile->sym_private, 0, sizeof (struct hpread_symfile_info));
+
+  /* We haven't read in any types yet.  */
+  TYPE_VECTOR (objfile) = 0;
+
+  /* Read in data from the $GNTT$ subspace.  */
+  gntt_section = bfd_get_section_by_name (objfile->obfd, "$GNTT$");
+  if (!gntt_section)
+    return;
+
+  GNTT (objfile)
+    = obstack_alloc (&objfile->symbol_obstack,
+                    bfd_section_size (objfile->obfd, gntt_section));
+
+  bfd_get_section_contents (objfile->obfd, gntt_section, GNTT (objfile),
+                           0, bfd_section_size (objfile->obfd, gntt_section));
+
+  GNTT_SYMCOUNT (objfile)
+    = bfd_section_size (objfile->obfd, gntt_section) / DNTTBLOCKSIZE;
+
+  /* Read in data from the $LNTT$ subspace.   Also keep track of the number
+     of LNTT symbols.  */
+  lntt_section = bfd_get_section_by_name (objfile->obfd, "$LNTT$");
+  if (!lntt_section)
+    return;
+
+  LNTT (objfile)
+    = obstack_alloc (&objfile->symbol_obstack,
+                    bfd_section_size (objfile->obfd, lntt_section));
+
+  bfd_get_section_contents (objfile->obfd, lntt_section, LNTT (objfile),
+                           0, bfd_section_size (objfile->obfd, lntt_section));
+
+  LNTT_SYMCOUNT (objfile)
+    = bfd_section_size (objfile->obfd, lntt_section) / DNTTBLOCKSIZE;
+
+  /* Read in data from the $SLT$ subspace.  $SLT$ contains information
+     on source line numbers.  */
+  slt_section = bfd_get_section_by_name (objfile->obfd, "$SLT$");
+  if (!slt_section)
+    return;
+
+  SLT (objfile) =
+    obstack_alloc (&objfile->symbol_obstack,
+                  bfd_section_size (objfile->obfd, slt_section));
+
+  bfd_get_section_contents (objfile->obfd, slt_section, SLT (objfile),
+                           0, bfd_section_size (objfile->obfd, slt_section));
+
+  /* Read in data from the $VT$ subspace.  $VT$ contains things like
+     names and constants.  Keep track of the number of symbols in the VT.  */
+  vt_section = bfd_get_section_by_name (objfile->obfd, "$VT$");
+  if (!vt_section)
+    return;
+
+  VT_SIZE (objfile) = bfd_section_size (objfile->obfd, vt_section);
+
+  VT (objfile) =
+    (char *) obstack_alloc (&objfile->symbol_obstack,
+                           VT_SIZE (objfile));
+
+  bfd_get_section_contents (objfile->obfd, vt_section, VT (objfile),
+                           0, VT_SIZE (objfile));
+}
+
+/* Scan and build partial symbols for a symbol file.
+
+   The minimal symbol table (either SOM or HP a.out) has already been
+   read in; all we need to do is setup partial symbols based on the
+   native debugging information.
+
+   We assume hpread_symfile_init has been called to initialize the
+   symbol reader's private data structures.
+
+   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).  */
+
+void
+hpread_build_psymtabs (objfile, section_offsets, mainline)
+     struct objfile *objfile;
+     struct section_offsets *section_offsets;
+     int mainline;
+{
+  char *namestring;
+  int past_first_source_file = 0;
+  struct cleanup *old_chain;
+
+  int hp_symnum, symcount, i;
+
+  union dnttentry *dn_bufp;
+  unsigned long valu;
+  char *p;
+  int texthigh = 0;
+  int have_name = 0;
+
+  /* Current partial symtab */
+  struct partial_symtab *pst;
+
+  /* List of current psymtab's include files */
+  char **psymtab_include_list;
+  int includes_allocated;
+  int includes_used;
+
+  /* Index within current psymtab dependency list */
+  struct partial_symtab **dependency_list;
+  int dependencies_used, dependencies_allocated;
+
+  /* Just in case the stabs reader left turds lying around.  */
+  pending_blocks = 0;
+  make_cleanup (really_free_pendings, 0);
+
+  pst = (struct partial_symtab *) 0;
+
+  /* We shouldn't use alloca, instead use malloc/free.  Doing so avoids
+     a number of problems with cross compilation and creating useless holes
+     in the stack when we have to allocate new entries.  FIXME.  */
+
+  includes_allocated = 30;
+  includes_used = 0;
+  psymtab_include_list = (char **) alloca (includes_allocated *
+                                          sizeof (char *));
+
+  dependencies_allocated = 30;
+  dependencies_used = 0;
+  dependency_list =
+    (struct partial_symtab **) alloca (dependencies_allocated *
+                                      sizeof (struct partial_symtab *));
+
+  old_chain = make_cleanup (free_objfile, objfile);
+
+  last_source_file = 0;
+
+  /* Make two passes, one ofr the GNTT symbols, the other for the
+     LNTT symbols.  */
+  for (i = 0; i < 1; i++)
+    {
+      int within_function = 0;
+
+      if (i)
+       symcount = GNTT_SYMCOUNT (objfile);
+      else
+       symcount = LNTT_SYMCOUNT (objfile);
+
+      for (hp_symnum = 0; hp_symnum < symcount; hp_symnum++)
+       {
+         QUIT;
+         if (i)
+           dn_bufp = hpread_get_gntt (hp_symnum, objfile);
+         else
+           dn_bufp = hpread_get_lntt (hp_symnum, objfile);
+
+         if (dn_bufp->dblock.extension)
+           continue;
+
+         /* Only handle things which are necessary for minimal symbols.
+            everything else is ignored.  */
+         switch (dn_bufp->dblock.kind)
+           {
+           case K_SRCFILE:
+             {
+               /* A source file of some kind.  Note this may simply
+                  be an included file.  */
+               SET_NAMESTRING (dn_bufp, &namestring, objfile);
+
+               /* Check if this is the source file we are already working
+                  with.  */
+               if (pst && !strcmp (namestring, pst->filename))
+                 continue;
+
+               /* Check if this is an include file, if so check if we have
+                  already seen it.  Add it to the include list */
+               p = strrchr (namestring, '.');
+               if (!strcmp (p, ".h"))
+                 {
+                   int j, found;
+
+                   found = 0;
+                   for (j = 0; j < includes_used; j++)
+                     if (!strcmp (namestring, psymtab_include_list[j]))
+                       {
+                         found = 1;
+                         break;
+                       }
+                   if (found)
+                     continue;
+
+                   /* Add it to the list of includes seen so far and
+                      allocate more include space if necessary.  */
+                   psymtab_include_list[includes_used++] = namestring;
+                   if (includes_used >= includes_allocated)
+                     {
+                       char **orig = psymtab_include_list;
+
+                       psymtab_include_list = (char **)
+                         alloca ((includes_allocated *= 2) *
+                                 sizeof (char *));
+                       memcpy ((PTR) psymtab_include_list, (PTR) orig,
+                               includes_used * sizeof (char *));
+                     }
+                   continue;
+                 }
+
+
+               if (HAVE_MODULE (objfile))
+                 {
+                   if (!have_name)
+                     {
+                       pst->filename =
+                         (char *) obstack_alloc (&pst->objfile->psymbol_obstack, strlen (namestring) + 1);
+                       strcpy (pst->filename, namestring);
+                       have_name = 1;
+                       continue;
+                     }
+                   continue;
+                 }
+
+               /* This is a bonafide new source file.
+                  End the current partial symtab and start a new one.  */
+
+               if (pst && past_first_source_file)
+                 {
+                   texthigh += ANOFFSET (section_offsets, SECT_OFF_TEXT);
+                   hpread_end_psymtab (pst, psymtab_include_list,
+                                       includes_used,
+                                       hp_symnum * DNTTBLOCKSIZE, texthigh,
+                                       dependency_list, dependencies_used);
+                   pst = (struct partial_symtab *) 0;
+                   includes_used = 0;
+                   dependencies_used = 0;
+                 }
+               else
+                 past_first_source_file = 1;
+
+               valu = hpread_get_textlow (i, hp_symnum, objfile);
+               valu += ANOFFSET (section_offsets, SECT_OFF_TEXT);
+               pst = hpread_start_psymtab (objfile, section_offsets,
+                                           namestring, valu,
+                                           hp_symnum * DNTTBLOCKSIZE,
+                                           objfile->global_psymbols.next,
+                                           objfile->static_psymbols.next);
+               texthigh = valu;
+               continue;
+             }
+
+           case K_MODULE:
+             /* A source file.  It's still unclear to me what the
+                real difference between a K_SRCFILE and K_MODULE
+                is supposed to be.  */
+             SET_NAMESTRING (dn_bufp, &namestring, objfile);
+             valu = hpread_get_textlow (i, hp_symnum, objfile);
+             valu += ANOFFSET (section_offsets, SECT_OFF_TEXT);
+             pst = hpread_start_psymtab (objfile, section_offsets,
+                                         namestring, valu,
+                                         hp_symnum * DNTTBLOCKSIZE,
+                                         objfile->global_psymbols.next,
+                                         objfile->static_psymbols.next);
+             texthigh = valu;
+             HAVE_MODULE (objfile) = 1;
+             have_name = 0;
+             continue;
+           case K_FUNCTION:
+           case K_ENTRY:
+             /* The beginning of a function.  K_ENTRY may also denote
+                a secondary entry point.  */
+             valu = dn_bufp->dfunc.lowaddr +
+               ANOFFSET (section_offsets, SECT_OFF_TEXT);
+             if (dn_bufp->dfunc.hiaddr > texthigh)
+               texthigh = dn_bufp->dfunc.hiaddr;
+             SET_NAMESTRING (dn_bufp, &namestring, objfile);
+             ADD_PSYMBOL_TO_LIST (namestring, strlen (namestring),
+                                  VAR_NAMESPACE, LOC_BLOCK,
+                                  objfile->static_psymbols, valu,
+                                  language_unknown, objfile);
+             within_function = 1;
+             continue;
+           case K_BEGIN:
+           case K_END:
+             /* Scope block begin/end.  We only care about function
+                and file blocks right now.  */
+             if (dn_bufp->dend.endkind == K_MODULE)
+               {
+                 texthigh += ANOFFSET (section_offsets, SECT_OFF_TEXT);
+                 hpread_end_psymtab (pst, psymtab_include_list, includes_used,
+                                     hp_symnum * DNTTBLOCKSIZE, texthigh,
+                                     dependency_list, dependencies_used);
+                 pst = (struct partial_symtab *) 0;
+                 includes_used = 0;
+                 dependencies_used = 0;
+                 HAVE_MODULE (objfile) = 0;
+                 have_name = 0;
+               }
+             if (dn_bufp->dend.endkind == K_FUNCTION)
+               within_function = 0;
+             continue;
+           case K_SVAR:
+           case K_DVAR:
+           case K_TYPEDEF:
+           case K_TAGDEF:
+             {
+               /* Variables, typedefs an the like.  */
+               enum address_class storage;
+               enum namespace namespace;
+
+               /* Don't add locals to the partial symbol table.  */
+               if (within_function
+                   && (dn_bufp->dblock.kind == K_SVAR
+                       || dn_bufp->dblock.kind == K_DVAR))
+                 continue;
+
+               /* TAGDEFs go into the structure namespace.  */
+               if (dn_bufp->dblock.kind == K_TAGDEF)
+                 namespace = STRUCT_NAMESPACE;
+               else
+                 namespace = VAR_NAMESPACE;
+
+               /* What kind of "storage" does this use?  */
+               if (dn_bufp->dblock.kind == K_SVAR)
+                 storage = LOC_STATIC;
+               else if (dn_bufp->dblock.kind == K_DVAR
+                        && dn_bufp->ddvar.regvar)
+                 storage = LOC_REGISTER;
+               else if (dn_bufp->dblock.kind == K_DVAR)
+                 storage = LOC_LOCAL;
+               else
+                 storage = LOC_UNDEF;
+
+               SET_NAMESTRING (dn_bufp, &namestring, objfile);
+               if (!pst)
+                 {
+                   pst = hpread_start_psymtab (objfile, section_offsets,
+                                               "globals", 0,
+                                               hp_symnum * DNTTBLOCKSIZE,
+                                               objfile->global_psymbols.next,
+                                               objfile->static_psymbols.next);
+                 }
+               if (dn_bufp->dsvar.public)
+                 {
+                   ADD_PSYMBOL_TO_LIST (namestring, strlen (namestring),
+                                        namespace, storage,
+                                        objfile->global_psymbols,
+                                        dn_bufp->dsvar.location,
+                                        language_unknown, objfile);
+                 }
+               else
+                 {
+                   ADD_PSYMBOL_TO_LIST (namestring, strlen (namestring),
+                                        namespace, storage,
+                                        objfile->static_psymbols,
+                                        dn_bufp->dsvar.location,
+                                        language_unknown, objfile);
+                 }
+               continue;
+             }
+           case K_MEMENUM:
+           case K_CONST:
+             /* Constants and members of enumerated types.  */
+             SET_NAMESTRING (dn_bufp, &namestring, objfile);
+             if (!pst)
+               {
+                 pst = hpread_start_psymtab (objfile, section_offsets,
+                                             "globals", 0,
+                                             hp_symnum * DNTTBLOCKSIZE,
+                                             objfile->global_psymbols.next,
+                                             objfile->static_psymbols.next);
+               }
+             ADD_PSYMBOL_TO_LIST (namestring, strlen (namestring),
+                                  VAR_NAMESPACE, LOC_CONST,
+                                  objfile->static_psymbols, 0,
+                                  language_unknown, objfile);
+             continue;
+           default:
+             continue;
+           }
+       }
+    }
+
+  /* End any pending partial symbol table.  */
+  if (pst)
+    {
+      hpread_end_psymtab (pst, psymtab_include_list, includes_used,
+                         hp_symnum * DNTTBLOCKSIZE, 0,
+                         dependency_list, dependencies_used);
+    }
+
+  discard_cleanups (old_chain);
+}
+
+/* Perform any local cleanups required when we are done with a particular
+   objfile.  I.E, we are in the process of discarding all symbol information
+   for an objfile, freeing up all memory held for it, and unlinking the
+   objfile struct from the global list of known objfiles. */
+
+void
+hpread_symfile_finish (objfile)
+     struct objfile *objfile;
+{
+  if (objfile->sym_private != NULL)
+    {
+      mfree (objfile->md, objfile->sym_private);
+    }
+}
+\f
+
+/* The remaining functions are all for internal use only.  */
+
+/* Various small functions to get entries in the debug symbol sections.  */
+
+static union dnttentry *
+hpread_get_lntt (index, objfile)
+     int index;
+     struct objfile *objfile;
+{
+  return (union dnttentry *)&(LNTT (objfile)[index * DNTTBLOCKSIZE]);
+}
+
+static union dnttentry *
+hpread_get_gntt (index, objfile)
+     int index;
+     struct objfile *objfile;
+{
+  return (union dnttentry *)&(GNTT (objfile)[index * DNTTBLOCKSIZE]);
+}
+
+static union sltentry *
+hpread_get_slt (index, objfile)
+     int index;
+     struct objfile *objfile;
+{
+  return (union sltentry *)&(SLT (objfile)[index * SLTBLOCKSIZE]);
+}
+
+/* Get the low address associated with some symbol (typically the start
+   of a particular source file or module).  Since that information is not
+   stored as part of the K_MODULE or K_SRCFILE symbol we must infer it from
+   the existance of K_FUNCTION symbols.  */
+
+static unsigned long
+hpread_get_textlow (global, index, objfile)
+     int global;
+     int index;
+     struct objfile *objfile;
+{
+  union dnttentry *dn_bufp;
+  struct minimal_symbol *msymbol;
+
+  /* Look for a K_FUNCTION symbol.  */
+  do
+    {
+      if (global)
+       dn_bufp = hpread_get_gntt (index++, objfile);
+      else
+       dn_bufp = hpread_get_lntt (index++, objfile);
+    } while (dn_bufp->dblock.kind != K_FUNCTION
+            && dn_bufp->dblock.kind != K_END);
+
+  /* Avoid going past a K_END when looking for a K_FUNCTION.  This
+     might happen when a sourcefile has no functions.  */
+  if (dn_bufp->dblock.kind == K_END)
+    return 0;
+
+  /* The minimal symbols are typically more accurate for some reason.  */
+  msymbol = lookup_minimal_symbol (dn_bufp->dfunc.name + VT (objfile),
+                                  objfile);
+  if (msymbol)
+    return SYMBOL_VALUE_ADDRESS (msymbol);
+  else
+    return dn_bufp->dfunc.lowaddr;
+}
+
+/* Get the nesting depth for the source line identified by INDEX.  */
+
+static unsigned long
+hpread_get_depth (index, objfile)
+     SLTPOINTER index;
+     struct objfile *objfile;
+{
+  union sltentry *sl_bufp;
+
+  sl_bufp = hpread_get_slt (index, objfile);
+  return sl_bufp->sspec.backptr.dnttp.index;
+}
+
+/* Get the source line number the the line identified by INDEX.  */
+
+static unsigned long
+hpread_get_line (index, objfile)
+     SLTPOINTER index;
+     struct objfile *objfile;
+{
+  union sltentry *sl_bufp;
+
+  sl_bufp = hpread_get_slt (index, objfile);
+  return sl_bufp->snorm.line;
+}
+
+static ADDRESS
+hpread_get_location (index, objfile)
+     SLTPOINTER index;
+     struct objfile *objfile;
+{
+  union sltentry *sl_bufp;
+  int i;
+
+  /* code location of special sltentrys is determined from context */
+  sl_bufp = hpread_get_slt (index, objfile);
+
+  if (sl_bufp->snorm.sltdesc == SLT_END)
+    {
+      /* find previous normal sltentry and get address */
+      for (i = 0; ((sl_bufp->snorm.sltdesc != SLT_NORMAL) &&
+                  (sl_bufp->snorm.sltdesc != SLT_EXIT)); i++)
+       sl_bufp = hpread_get_slt (index - i, objfile);
+      return sl_bufp->snorm.address;
+    }
+
+  /* find next normal sltentry and get address */
+  for (i = 0; ((sl_bufp->snorm.sltdesc != SLT_NORMAL) &&
+              (sl_bufp->snorm.sltdesc != SLT_EXIT)); i++)
+    sl_bufp = hpread_get_slt (index + i, objfile);
+  return sl_bufp->snorm.address;
+}
+\f
+
+/* Return 1 if an HP debug symbol of type KIND has a name associated with
+   it, else return 0.  */
+
+static int
+hpread_has_name (kind)
+     KINDTYPE kind;
+{
+  switch (kind)
+    {
+    case K_SRCFILE:
+    case K_MODULE:
+    case K_FUNCTION:
+    case K_ENTRY:
+    case K_IMPORT:
+    case K_LABEL:
+    case K_FPARAM:
+    case K_SVAR:
+    case K_DVAR:
+    case K_CONST:
+    case K_TYPEDEF:
+    case K_TAGDEF:
+    case K_MEMENUM:
+    case K_FIELD:
+    case K_SA:
+      return 1;
+
+    case K_BEGIN:
+    case K_END:
+    case K_WITH:
+    case K_COMMON:
+    case K_POINTER:
+    case K_ENUM:
+    case K_SET:
+    case K_SUBRANGE:
+    case K_ARRAY:
+    case K_STRUCT:
+    case K_UNION:
+    case K_VARIANT:
+    case K_FILE:
+    case K_FUNCTYPE:
+    case K_COBSTRUCT:
+    case K_XREF:
+    case K_MACRO:
+    default:
+      return 0;
+    }
+}
+
+/* Allocate and partially fill a partial symtab.  It will be
+   completely filled at the end of the symbol list.
+
+   SYMFILE_NAME is the name of the symbol-file we are reading from, and ADDR
+   is the address relative to which its symbols are (incremental) or 0
+   (normal). */
+
+static struct partial_symtab *
+hpread_start_psymtab (objfile, section_offsets,
+                 filename, textlow, ldsymoff, global_syms, static_syms)
+     struct objfile *objfile;
+     struct section_offsets *section_offsets;
+     char *filename;
+     CORE_ADDR textlow;
+     int ldsymoff;
+     struct partial_symbol *global_syms;
+     struct partial_symbol *static_syms;
+{
+  struct partial_symtab *result =
+  start_psymtab_common (objfile, section_offsets,
+                       filename, textlow, global_syms, static_syms);
+
+  result->read_symtab_private = (char *)
+    obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc));
+  LDSYMOFF (result) = ldsymoff;
+  result->read_symtab = hpread_psymtab_to_symtab;
+
+  return result;
+}
+\f
+
+/* Close off the current usage of PST.  
+   Returns PST or NULL if the partial symtab was empty and thrown away.
+
+   FIXME:  List variables and peculiarities of same.  */
+
+static struct partial_symtab *
+hpread_end_psymtab (pst, include_list, num_includes, capping_symbol_offset,
+            capping_text, dependency_list, number_dependencies)
+     struct partial_symtab *pst;
+     char **include_list;
+     int num_includes;
+     int capping_symbol_offset;
+     CORE_ADDR capping_text;
+     struct partial_symtab **dependency_list;
+     int number_dependencies;
+{
+  int i;
+  struct objfile *objfile = pst -> objfile;
+
+  if (capping_symbol_offset != -1)
+      LDSYMLEN(pst) = capping_symbol_offset - LDSYMOFF(pst);
+  pst->texthigh = capping_text;
+
+  pst->n_global_syms =
+    objfile->global_psymbols.next - (objfile->global_psymbols.list + pst->globals_offset);
+  pst->n_static_syms =
+    objfile->static_psymbols.next - (objfile->static_psymbols.list + pst->statics_offset);
+
+  pst->number_of_dependencies = number_dependencies;
+  if (number_dependencies)
+    {
+      pst->dependencies = (struct partial_symtab **)
+       obstack_alloc (&objfile->psymbol_obstack,
+                      number_dependencies * sizeof (struct partial_symtab *));
+      memcpy (pst->dependencies, dependency_list,
+            number_dependencies * sizeof (struct partial_symtab *));
+    }
+  else
+    pst->dependencies = 0;
+
+  for (i = 0; i < num_includes; i++)
+    {
+      struct partial_symtab *subpst =
+       allocate_psymtab (include_list[i], objfile);
+
+      subpst->section_offsets = pst->section_offsets;
+      subpst->read_symtab_private =
+         (char *) obstack_alloc (&objfile->psymbol_obstack,
+                                 sizeof (struct symloc));
+      LDSYMOFF(subpst) =
+       LDSYMLEN(subpst) =
+         subpst->textlow =
+           subpst->texthigh = 0;
+
+      /* We could save slight bits of space by only making one of these,
+        shared by the entire set of include files.  FIXME-someday.  */
+      subpst->dependencies = (struct partial_symtab **)
+       obstack_alloc (&objfile->psymbol_obstack,
+                      sizeof (struct partial_symtab *));
+      subpst->dependencies[0] = pst;
+      subpst->number_of_dependencies = 1;
+
+      subpst->globals_offset =
+       subpst->n_global_syms =
+         subpst->statics_offset =
+           subpst->n_static_syms = 0;
+
+      subpst->readin = 0;
+      subpst->symtab = 0;
+      subpst->read_symtab = pst->read_symtab;
+    }
+
+  sort_pst_symbols (pst);
+
+  /* If there is already a psymtab or symtab for a file of this name, remove it.
+     (If there is a symtab, more drastic things also happen.)
+     This happens in VxWorks.  */
+  free_named_symtabs (pst->filename);
+
+  if (num_includes == 0
+      && number_dependencies == 0
+      && pst->n_global_syms == 0
+      && pst->n_static_syms == 0)
+    {
+      /* Throw away this psymtab, it's empty.  We can't deallocate it, since
+        it is on the obstack, but we can forget to chain it on the list.  */
+      /* Empty psymtabs happen as a result of header files which don't have
+        any symbols in them.  There can be a lot of them.  But this check
+        is wrong, in that a psymtab with N_SLINE entries but nothing else
+        is not empty, but we don't realize that.  Fixing that without slowing
+        things down might be tricky.  */
+      struct partial_symtab *prev_pst;
+
+      /* First, snip it out of the psymtab chain */
+
+      if (pst->objfile->psymtabs == pst)
+       pst->objfile->psymtabs = pst->next;
+      else
+       for (prev_pst = pst->objfile->psymtabs; prev_pst; prev_pst = pst->next)
+         if (prev_pst->next == pst)
+           prev_pst->next = pst->next;
+
+      /* Next, put it on a free list for recycling */
+
+      pst->next = pst->objfile->free_psymtabs;
+      pst->objfile->free_psymtabs = pst;
+
+      /* Indicate that psymtab was thrown away.  */
+      pst = (struct partial_symtab *)NULL;
+    }
+  return pst;
+}
+\f
+/* Do the dirty work of reading in the full symbol from a partial symbol
+   table.  */
+
+static void
+hpread_psymtab_to_symtab_1 (pst)
+     struct partial_symtab *pst;
+{
+  struct cleanup *old_chain;
+  int i;
+
+  /* Get out quick if passed junk.  */
+  if (!pst)
+    return;
+
+  /* Complain if we've already read in this symbol table.  */
+  if (pst->readin)
+    {
+      fprintf (stderr, "Psymtab for %s already read in.  Shouldn't happen.\n",
+              pst->filename);
+      return;
+    }
+
+  /* Read in all partial symtabs on which this one is dependent */
+  for (i = 0; i < pst->number_of_dependencies; i++)
+    if (!pst->dependencies[i]->readin)
+      {
+       /* Inform about additional files that need to be read in.  */
+       if (info_verbose)
+         {
+           fputs_filtered (" ", stdout);
+           wrap_here ("");
+           fputs_filtered ("and ", stdout);
+           wrap_here ("");
+           printf_filtered ("%s...", pst->dependencies[i]->filename);
+           wrap_here ("");     /* Flush output */
+           fflush (stdout);
+         }
+       hpread_psymtab_to_symtab_1 (pst->dependencies[i]);
+      }
+
+  /* If it's real...  */
+  if (LDSYMLEN (pst))
+    {
+      /* Init stuff necessary for reading in symbols */
+      buildsym_init ();
+      old_chain = make_cleanup (really_free_pendings, 0);
+
+      pst->symtab =
+       hpread_expand_symtab (pst->objfile, LDSYMOFF (pst), LDSYMLEN (pst),
+                             pst->textlow, pst->texthigh - pst->textlow,
+                             pst->section_offsets, pst->filename);
+      sort_symtab_syms (pst->symtab);
+
+      do_cleanups (old_chain);
+    }
+
+  pst->readin = 1;
+}
+
+/* Read in all of the symbols for a given psymtab for real.
+   Be verbose about it if the user wants that.  */
+
+static void
+hpread_psymtab_to_symtab (pst)
+     struct partial_symtab *pst;
+{
+  /* Get out quick if given junk.  */
+  if (!pst)
+    return;
+
+  /* Sanity check.  */
+  if (pst->readin)
+    {
+      fprintf (stderr, "Psymtab for %s already read in.  Shouldn't happen.\n",
+              pst->filename);
+      return;
+    }
+
+  if (LDSYMLEN (pst) || pst->number_of_dependencies)
+    {
+      /* Print the message now, before reading the string table,
+         to avoid disconcerting pauses.  */
+      if (info_verbose)
+       {
+         printf_filtered ("Reading in symbols for %s...", pst->filename);
+         fflush (stdout);
+       }
+
+      hpread_psymtab_to_symtab_1 (pst);
+
+      /* Match with global symbols.  This only needs to be done once,
+         after all of the symtabs and dependencies have been read in.   */
+      scan_file_globals (pst->objfile);
+
+      /* Finish up the debug error message.  */
+      if (info_verbose)
+       printf_filtered ("done.\n");
+    }
+}
+/* Read in a defined section of a specific object file's symbols.
+
+   DESC is the file descriptor for the file, positioned at the
+   beginning of the symtab
+   SYM_OFFSET is the offset within the file of
+   the beginning of the symbols we want to read
+   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.
+   SECTION_OFFSETS are the relocation offsets which get added to each symbol. */
+
+static struct symtab *
+hpread_expand_symtab (objfile, sym_offset, sym_size, text_offset, text_size,
+                     section_offsets, filename)
+     struct objfile *objfile;
+     int sym_offset;
+     int sym_size;
+     CORE_ADDR text_offset;
+     int text_size;
+     struct section_offsets *section_offsets;
+     char *filename;
+{
+  char *namestring;
+  union dnttentry *dn_bufp;
+  unsigned max_symnum;
+
+  int sym_index = sym_offset / DNTTBLOCKSIZE;
+
+  current_objfile = objfile;
+  subfile_stack = 0;
+
+  last_source_file = 0;
+
+  dn_bufp = hpread_get_lntt (sym_index, objfile);
+  if (!((dn_bufp->dblock.kind == (unsigned char) K_SRCFILE) ||
+       (dn_bufp->dblock.kind == (unsigned char) K_MODULE)))
+    start_symtab ("globals", NULL, 0);
+
+  max_symnum = sym_size / DNTTBLOCKSIZE;
+
+  /* Read in and process each debug symbol within the specified range.  */
+  for (symnum = 0;
+       symnum < max_symnum;
+       symnum++)
+    {
+      QUIT;                    /* Allow this to be interruptable */
+      dn_bufp = hpread_get_lntt (sym_index + symnum, objfile);
+
+      if (dn_bufp->dblock.extension)
+       continue;
+
+      /* Yow!  We call SET_NAMESTRING on things without names!  */
+      SET_NAMESTRING (dn_bufp, &namestring, objfile);
+
+      hpread_process_one_debug_symbol (dn_bufp, namestring, section_offsets,
+                                      objfile, text_offset, text_size,
+                                      filename, symnum + sym_index);
+    }
+
+  current_objfile = NULL;
+
+  return end_symtab (text_offset + text_size, 0, 0, objfile, 0);
+}
+\f
+
+/* Convert basic types from HP debug format into GDB internal format.  */
+
+static int
+hpread_type_translate (typep)
+     DNTTPOINTER typep;
+{
+  if (!typep.dntti.immediate)
+    abort ();
+
+  switch (typep.dntti.type)
+    {
+    case T_BOOLEAN:
+    case T_BOOLEAN_S300_COMPAT:
+    case T_BOOLEAN_VAX_COMPAT:
+      return FT_BOOLEAN;
+      /* Ugh.  No way to distinguish between signed and unsigned chars.  */
+    case T_CHAR:
+    case T_WIDE_CHAR:
+      return FT_CHAR;
+    case T_INT:
+      if (typep.dntti.bitlength <= 8)
+       return FT_CHAR;
+      if (typep.dntti.bitlength <= 16)
+       return FT_SHORT;
+      if (typep.dntti.bitlength <= 32)
+       return FT_INTEGER;
+      return FT_LONG_LONG;
+    case T_LONG:
+      return FT_LONG;
+    case T_UNS_LONG:
+      return FT_UNSIGNED_LONG;
+    case T_UNS_INT:
+      if (typep.dntti.bitlength <= 8)
+       return FT_UNSIGNED_CHAR;
+      if (typep.dntti.bitlength <= 16)
+       return FT_UNSIGNED_SHORT;
+      if (typep.dntti.bitlength <= 32)
+       return FT_UNSIGNED_INTEGER;
+      return FT_UNSIGNED_LONG_LONG;
+    case T_REAL:
+    case T_REAL_3000:
+    case T_DOUBLE:
+      if (typep.dntti.bitlength == 64)
+       return FT_DBL_PREC_FLOAT;
+      if (typep.dntti.bitlength == 128)
+       return FT_EXT_PREC_FLOAT;
+      return FT_FLOAT;
+    case T_COMPLEX:
+    case T_COMPLEXS3000:
+      if (typep.dntti.bitlength == 128)
+       return FT_DBL_PREC_COMPLEX;
+      if (typep.dntti.bitlength == 192)
+       return FT_EXT_PREC_COMPLEX;
+      return FT_COMPLEX;
+    case T_STRING200:
+    case T_LONGSTRING200:
+    case T_FTN_STRING_SPEC:
+    case T_MOD_STRING_SPEC:
+    case T_MOD_STRING_3000:
+    case T_FTN_STRING_S300_COMPAT:
+    case T_FTN_STRING_VAX_COMPAT:
+      return FT_STRING;
+    default:
+      abort ();
+    }
+}
+
+/* Return the type associated with the index found in HP_TYPE.  */
+
+static struct type **
+hpread_lookup_type (hp_type, objfile)
+     DNTTPOINTER hp_type;
+     struct objfile *objfile;
+{
+  unsigned old_len;
+  int index = hp_type.dnttp.index;
+
+  if (hp_type.dntti.immediate)
+    return NULL;
+
+  if (index < LNTT_SYMCOUNT (objfile))
+    {
+      if (index >= TYPE_VECTOR_LENGTH (objfile))
+       {
+         old_len = TYPE_VECTOR_LENGTH (objfile);
+         if (old_len == 0)
+           {
+             TYPE_VECTOR_LENGTH (objfile) = 100;
+             TYPE_VECTOR (objfile) = (struct type **)
+               malloc (TYPE_VECTOR_LENGTH (objfile) * sizeof (struct type *));
+           }
+         while (index >= TYPE_VECTOR_LENGTH (objfile))
+           TYPE_VECTOR_LENGTH (objfile) *= 2;
+         TYPE_VECTOR (objfile) = (struct type **)
+           xrealloc ((char *) TYPE_VECTOR (objfile),
+                     (TYPE_VECTOR_LENGTH (objfile) * sizeof (struct type *)));
+         memset (&TYPE_VECTOR (objfile)[old_len], 0,
+                 (TYPE_VECTOR_LENGTH (objfile) - old_len) *
+                 sizeof (struct type *));
+       }
+      return &TYPE_VECTOR (objfile)[index];
+    }
+  else
+    return NULL;
+}
+
+/* Possibly allocate a GDB internal type so we can internalize HP_TYPE.
+   Note we'll just return the address of a GDB internal type if we already
+   have it lying around.  */
+
+static struct type *
+hpread_alloc_type (hp_type, objfile)
+     DNTTPOINTER hp_type;
+     struct objfile *objfile;
+{
+  struct type **type_addr;
+
+  type_addr = hpread_lookup_type (hp_type, objfile);
+  if (*type_addr == 0)
+    *type_addr = alloc_type (objfile);
+
+  TYPE_CPLUS_SPECIFIC (*type_addr)
+    = (struct cplus_struct_type *) &cplus_struct_default;
+  return *type_addr;
+}
+
+/* Read a native enumerated type and return it in GDB internal form.  */
+
+static struct type *
+hpread_read_enum_type (hp_type, dn_bufp, objfile)
+     DNTTPOINTER hp_type;
+     union dnttentry *dn_bufp;
+     struct objfile *objfile;
+{
+  struct type *type;
+  struct pending **symlist, *osyms, *syms;
+  int o_nsyms, nsyms = 0;
+  DNTTPOINTER mem;
+  union dnttentry *memp;
+  char *name;
+  long n;
+  struct symbol *sym;
+
+  type = hpread_alloc_type (hp_type, objfile);
+  TYPE_LENGTH (type) = 4;
+
+  symlist = &file_symbols;
+  osyms = *symlist;
+  o_nsyms = osyms ? osyms->nsyms : 0;
+
+  /* Get a name for each member and add it to our list of members.  */
+  mem = dn_bufp->denum.firstmem;
+  while (mem.dnttp.extension && mem.word != DNTTNIL)
+    {
+      memp = hpread_get_lntt (mem.dnttp.index, objfile);
+
+      name = VT (objfile) + memp->dmember.name;
+      sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+                                            sizeof (struct symbol));
+      memset (sym, 0, sizeof (struct symbol));
+      SYMBOL_NAME (sym) = name;
+      SYMBOL_CLASS (sym) = LOC_CONST;
+      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+      SYMBOL_VALUE (sym) = memp->dmember.value;
+      add_symbol_to_list (sym, symlist);
+      nsyms++;
+      mem = memp->dmember.nextmem;
+    }
+
+  /* Now that we know more about the enum, fill in more info.  */
+  TYPE_CODE (type) = TYPE_CODE_ENUM;
+  TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB;
+  TYPE_NFIELDS (type) = nsyms;
+  TYPE_FIELDS (type) = (struct field *)
+    obstack_alloc (&objfile->type_obstack, sizeof (struct field) * nsyms);
+
+  /* Find the symbols for the members and put them into the type.
+     The symbols can be found in the symlist that we put them on
+     to cause them to be defined.  osyms contains the old value
+     of that symlist; everything up to there was defined by us.
+
+     Note that we preserve the order of the enum constants, so
+     that in something like "enum {FOO, LAST_THING=FOO}" we print
+     FOO, not LAST_THING.  */
+  for (syms = *symlist, n = 0; syms; syms = syms->next)
+    {
+      int j = 0;
+      if (syms == osyms)
+       j = o_nsyms;
+      for (; j < syms->nsyms; j++, n++)
+       {
+         struct symbol *xsym = syms->symbol[j];
+         SYMBOL_TYPE (xsym) = type;
+         TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
+         TYPE_FIELD_VALUE (type, n) = 0;
+         TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym);
+         TYPE_FIELD_BITSIZE (type, n) = 0;
+       }
+      if (syms == osyms)
+       break;
+    }
+
+  return type;
+}
+
+/* Read and internalize a native function debug symbol.  */
+
+static struct type *
+hpread_read_function_type (hp_type, dn_bufp, objfile)
+     DNTTPOINTER hp_type;
+     union dnttentry *dn_bufp;
+     struct objfile *objfile;
+{
+  struct type *type, *type1;
+  struct pending **symlist, *osyms, *syms;
+  int o_nsyms, nsyms = 0;
+  DNTTPOINTER param;
+  union dnttentry *paramp;
+  char *name;
+  long n;
+  struct symbol *sym;
+
+  param = dn_bufp->dfunc.firstparam;
+
+  /* See if we've already read in this type.  */
+  type = hpread_alloc_type (hp_type, objfile);
+  if (TYPE_CODE (type) == TYPE_CODE_FUNC)
+    return type;
+
+  /* Nope, so read it in and store it away.  */
+  type1 = lookup_function_type (hpread_type_lookup (dn_bufp->dfunc.retval,
+                                                   objfile));
+  memcpy ((char *) type, (char *) type1, sizeof (struct type));
+
+  symlist = &local_symbols;
+  osyms = *symlist;
+  o_nsyms = osyms ? osyms->nsyms : 0;
+
+  /* Now examine each parameter noting its type, location, and a
+     wealth of other information.  */
+  while (param.word && param.word != DNTTNIL)
+    {
+      paramp = hpread_get_lntt (param.dnttp.index, objfile);
+      nsyms++;
+      param = paramp->dfparam.nextparam;
+
+      /* Get the name.  */
+      name = VT (objfile) + paramp->dfparam.name;
+      sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+                                            sizeof (struct symbol));
+      (void) memset (sym, 0, sizeof (struct symbol));
+      SYMBOL_NAME (sym) = name;
+
+      /* Figure out where it lives.  */
+      if (paramp->dfparam.regparam)
+       SYMBOL_CLASS (sym) = LOC_REGPARM;
+      else if (paramp->dfparam.indirect)
+       SYMBOL_CLASS (sym) = LOC_REF_ARG;
+      else
+       SYMBOL_CLASS (sym) = LOC_ARG;
+      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+      if (paramp->dfparam.copyparam)
+       {
+         SYMBOL_VALUE (sym) = paramp->dfparam.location ;
+#ifdef HPREAD_ADJUST_STACK_ADDRESS
+         SYMBOL_VALUE (sym)
+           += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile));
+#endif
+         /* This is likely a pass-by-invisible reference parameter,
+            Hack on the symbol class to make GDB happy.  */
+         SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
+       }
+      else
+       SYMBOL_VALUE (sym) = paramp->dfparam.location;
+
+      /* Get its type.  */
+      SYMBOL_TYPE (sym) = hpread_type_lookup (paramp->dfparam.type, objfile);
+
+      /* Add it to the list.  */
+      add_symbol_to_list (sym, symlist);
+    }
+
+  /* Note how many parameters we found.  */
+  TYPE_NFIELDS (type) = nsyms;
+  TYPE_FIELDS (type) = (struct field *)
+    obstack_alloc (&objfile->type_obstack,
+                  sizeof (struct field) * nsyms);
+
+  /* Find the symbols for the values and put them into the type.
+     The symbols can be found in the symlist that we put them on
+     to cause them to be defined.  osyms contains the old value
+     of that symlist; everything up to there was defined by us.  */
+  /* Note that we preserve the order of the parameters, so
+     that in something like "enum {FOO, LAST_THING=FOO}" we print
+     FOO, not LAST_THING.  */
+  for (syms = *symlist, n = 0; syms; syms = syms->next)
+    {
+      int j = 0;
+      if (syms == osyms)
+       j = o_nsyms;
+      for (; j < syms->nsyms; j++, n++)
+       {
+         struct symbol *xsym = syms->symbol[j];
+         TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
+         TYPE_FIELD_TYPE (type, n) = SYMBOL_TYPE (xsym);
+         TYPE_FIELD_BITPOS (type, n) = n;
+         TYPE_FIELD_BITSIZE (type, n) = 0;
+       }
+      if (syms == osyms)
+       break;
+    }
+  return type;
+}
+
+/* Read in and internalize a structure definition.  */
+
+static struct type *
+hpread_read_struct_type (hp_type, dn_bufp, objfile)
+     DNTTPOINTER hp_type;
+     union dnttentry *dn_bufp;
+     struct objfile *objfile;
+{
+  struct nextfield
+    {
+      struct nextfield *next;
+      struct field field;
+    };
+
+  struct type *type;
+  struct nextfield *list = 0;
+  struct nextfield *new;
+  int n, nfields = 0;
+  DNTTPOINTER field;
+  union dnttentry *fieldp;
+
+  /* Is it something we've already dealt with?  */
+  type = hpread_alloc_type (hp_type, objfile);
+  if ((TYPE_CODE (type) == TYPE_CODE_STRUCT) ||
+      (TYPE_CODE (type) == TYPE_CODE_UNION))
+      return type;
+
+  /* Get the basic type correct.  */
+  if (dn_bufp->dblock.kind == K_STRUCT)
+    {
+      TYPE_CODE (type) = TYPE_CODE_STRUCT;
+      TYPE_LENGTH (type) = dn_bufp->dstruct.bitlength / 8;
+    }
+  else if (dn_bufp->dblock.kind == K_UNION)
+    {
+      TYPE_CODE (type) = TYPE_CODE_UNION;
+      TYPE_LENGTH (type) = dn_bufp->dunion.bitlength / 8;
+    }
+  else
+    return type;
+
+
+  TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB;
+
+  /* Read in and internalize all the fields.  */
+  field = dn_bufp->dstruct.firstfield;
+  while (field.word != DNTTNIL && field.dnttp.extension)
+    {
+      fieldp = hpread_get_lntt (field.dnttp.index, objfile);
+
+      /* Get space to record the next field's data.  */
+      new = (struct nextfield *) alloca (sizeof (struct nextfield));
+      new->next = list;
+      list = new;
+
+      list->field.name = VT (objfile) + fieldp->dfield.name;
+      list->field.bitpos = fieldp->dfield.bitoffset;
+      if (fieldp->dfield.bitlength % 8)
+       list->field.bitsize = fieldp->dfield.bitlength;
+      else
+       list->field.bitsize = 0;
+      nfields++;
+      field = fieldp->dfield.nextfield;
+      list->field.type = hpread_type_lookup (fieldp->dfield.type, objfile);
+    }
+
+  TYPE_NFIELDS (type) = nfields;
+  TYPE_FIELDS (type) = (struct field *)
+    obstack_alloc (&objfile->type_obstack, sizeof (struct field) * nfields);
+
+  /* Copy the saved-up fields into the field vector.  */
+  for (n = nfields; list; list = list->next)
+    {
+      n -= 1;
+      TYPE_FIELD (type, n) = list->field;
+    }
+  return type;
+}
+
+/* Read in and internalize a set debug symbol.  */
+
+static struct type *
+hpread_read_set_type (hp_type, dn_bufp, objfile)
+     DNTTPOINTER hp_type;
+     union dnttentry *dn_bufp;
+     struct objfile *objfile;
+{
+  struct type *type;
+
+  /* See if it's something we've already deal with.  */
+  type = hpread_alloc_type (hp_type, objfile);
+  if (TYPE_CODE (type) == TYPE_CODE_SET)
+    return type;
+
+  /* Nope.  Fill in the appropriate fields.  */
+  TYPE_CODE (type) = TYPE_CODE_SET;
+  TYPE_LENGTH (type) = dn_bufp->dset.bitlength / 8;
+  TYPE_NFIELDS (type) = 0;
+  TYPE_TARGET_TYPE (type) = hpread_type_lookup (dn_bufp->dset.subtype,
+                                               objfile);
+  return type;
+}
+
+/* Read in and internalize an array debug symbol.  */
+
+static struct type *
+hpread_read_array_type (hp_type, dn_bufp, objfile)
+     DNTTPOINTER hp_type;
+     union dnttentry *dn_bufp;
+     struct objfile *objfile;
+{
+  struct type *type;
+  union dnttentry save;
+  save = *dn_bufp;
+
+  /* Why no check here?  Because it kept us from properly determining
+     the size of the array!  */
+  type = hpread_alloc_type (hp_type, objfile);
+
+  TYPE_CODE (type) = TYPE_CODE_ARRAY;
+
+  /* values are not normalized.  */
+  if (!((dn_bufp->darray.arrayisbytes && dn_bufp->darray.elemisbytes)
+       || (!dn_bufp->darray.arrayisbytes && !dn_bufp->darray.elemisbytes)))
+    abort ();
+  else if (dn_bufp->darray.arraylength == 0x7fffffff)
+    {
+      /* The HP debug format represents char foo[]; as an array with
+        length 0x7fffffff.  Internally GDB wants to represent this
+        as a pointer.  Ugh.  */
+     TYPE_CODE (type) = TYPE_CODE_PTR;
+     TYPE_LENGTH (type) = 4;
+    }
+  else
+    TYPE_LENGTH (type) = dn_bufp->darray.arraylength / 8;
+
+  TYPE_NFIELDS (type) = 1;
+  TYPE_TARGET_TYPE (type) = hpread_type_lookup (dn_bufp->darray.elemtype,
+                                               objfile);
+  dn_bufp = &save;
+  TYPE_FIELDS (type) = (struct field *)
+    obstack_alloc (&objfile->type_obstack, sizeof (struct field));
+  TYPE_FIELD_TYPE (type, 0) = hpread_type_lookup (dn_bufp->darray.indextype,
+                                                 objfile);
+  return type;
+}
+
+/* Read in and internalize a subrange debug symbol.  */
+static struct type *
+hpread_read_subrange_type (hp_type, dn_bufp, objfile)
+     DNTTPOINTER hp_type;
+     union dnttentry *dn_bufp;
+     struct objfile *objfile;
+{
+  struct type *type;
+
+  /* Is it something we've already dealt with.  */
+  type = hpread_alloc_type (hp_type, objfile);
+  if (TYPE_CODE (type) == TYPE_CODE_RANGE)
+    return type;
+
+  /* Nope, internalize it.  */
+  TYPE_CODE (type) = TYPE_CODE_RANGE;
+  TYPE_LENGTH (type) = dn_bufp->dsubr.bitlength / 8;
+  TYPE_NFIELDS (type) = 2;
+  TYPE_FIELDS (type) = (struct field *) obstack_alloc
+    (&objfile->type_obstack, 2 * sizeof (struct field));
+
+  if (dn_bufp->dsubr.dyn_low)
+    TYPE_FIELD_BITPOS (type, 0) = 0;
+  else
+    TYPE_FIELD_BITPOS (type, 0) = dn_bufp->dsubr.lowbound;
+
+  if (dn_bufp->dsubr.dyn_high)
+    TYPE_FIELD_BITPOS (type, 1) = -1;
+  else
+    TYPE_FIELD_BITPOS (type, 1) = dn_bufp->dsubr.highbound;
+  TYPE_TARGET_TYPE (type) = hpread_type_lookup (dn_bufp->dsubr.subtype,
+                                               objfile);
+  return type;
+}
+
+static struct type *
+hpread_type_lookup (hp_type, objfile)
+     DNTTPOINTER hp_type;
+     struct objfile *objfile;
+{
+  union dnttentry *dn_bufp;
+
+  /* First see if it's a simple builtin type.  */
+  if (hp_type.dntti.immediate)
+    return lookup_fundamental_type (objfile, hpread_type_translate (hp_type));
+
+  /* Not a builtin type.  We'll have to read it in.  */
+  if (hp_type.dnttp.index < LNTT_SYMCOUNT (objfile))
+    dn_bufp = hpread_get_lntt (hp_type.dnttp.index, objfile);
+  else
+    return lookup_fundamental_type (objfile, FT_VOID);
+
+  switch (dn_bufp->dblock.kind)
+    {
+    case K_SRCFILE:
+    case K_MODULE:
+    case K_FUNCTION:
+    case K_ENTRY:
+    case K_BEGIN:
+    case K_END:
+    case K_IMPORT:
+    case K_LABEL:
+    case K_WITH:
+    case K_COMMON:
+    case K_FPARAM:
+    case K_SVAR:
+    case K_DVAR:
+    case K_CONST:
+      /* Opps.  Something went very wrong.  */
+      return lookup_fundamental_type (objfile, FT_VOID);
+
+    case K_TYPEDEF:
+      {
+       struct type *structtype = hpread_type_lookup (dn_bufp->dtype.type,
+                                                     objfile);
+       char *suffix;
+       suffix = VT (objfile) + dn_bufp->dtype.name;
+
+       TYPE_CPLUS_SPECIFIC (structtype)
+         = (struct cplus_struct_type *) &cplus_struct_default;
+       TYPE_NAME (structtype) = suffix;
+       return structtype;
+      }
+
+    case K_TAGDEF:
+      {
+       /* Just a little different from above.  We have to tack on
+          an identifier of some kind (struct, union, enum, etc).  */
+       struct type *structtype = hpread_type_lookup (dn_bufp->dtype.type,
+                                                     objfile);
+       char *prefix, *suffix;
+       suffix = VT (objfile) + dn_bufp->dtype.name;
+
+       /* Lookup the next type in the list.  It should be a structure,
+          union, or enum type.  We will need to attach that to our name.  */
+       if (dn_bufp->dtype.type.dnttp.index < LNTT_SYMCOUNT (objfile))
+         dn_bufp = hpread_get_lntt (dn_bufp->dtype.type.dnttp.index, objfile);
+       else
+         abort ();
+
+       if (dn_bufp->dblock.kind == K_STRUCT)
+         prefix = "struct ";
+       else if (dn_bufp->dblock.kind == K_UNION)
+         prefix = "union ";
+       else
+         prefix = "enum ";
+
+       /* Build the correct name.  */
+       structtype->name
+         = (char *) obstack_alloc (&objfile->type_obstack,
+                                   strlen (prefix) + strlen (suffix) + 1);
+       TYPE_NAME (structtype) = strcpy (TYPE_NAME (structtype), prefix);
+       TYPE_NAME (structtype) = strcat (TYPE_NAME (structtype), suffix);
+       TYPE_TAG_NAME (structtype) = suffix;
+
+       TYPE_CPLUS_SPECIFIC (structtype)
+         = (struct cplus_struct_type *) &cplus_struct_default;
+
+       return structtype;
+      }
+    case K_POINTER:
+      return lookup_pointer_type (hpread_type_lookup (dn_bufp->dptr.pointsto,
+                                                     objfile));
+    case K_ENUM:
+      return hpread_read_enum_type (hp_type, dn_bufp, objfile);
+    case K_MEMENUM:
+      return lookup_fundamental_type (objfile, FT_VOID);
+    case K_SET:
+      return hpread_read_set_type (hp_type, dn_bufp, objfile);
+    case K_SUBRANGE:
+      return hpread_read_subrange_type (hp_type, dn_bufp, objfile);
+    case K_ARRAY:
+      return hpread_read_array_type (hp_type, dn_bufp, objfile);
+    case K_STRUCT:
+    case K_UNION:
+      return hpread_read_struct_type (hp_type, dn_bufp, objfile);
+    case K_FIELD:
+      return hpread_type_lookup (dn_bufp->dfield.type, objfile);
+    case K_VARIANT:
+    case K_FILE:
+      return lookup_fundamental_type (objfile, FT_VOID);
+    case K_FUNCTYPE:
+      return lookup_function_type (hpread_type_lookup (dn_bufp->dfunctype.retval,
+                                                      objfile));
+    case K_COBSTRUCT:
+    case K_XREF:
+    case K_SA:
+    case K_MACRO:
+    default:
+      return lookup_fundamental_type (objfile, FT_VOID);
+    }
+}
+
+static SLTPOINTER
+hpread_record_lines (subfile, s_idx, e_idx, objfile)
+     struct subfile *subfile;
+     SLTPOINTER s_idx, e_idx;
+     struct objfile *objfile;
+{
+  union sltentry *sl_bufp;
+
+  while (s_idx <= e_idx)
+    {
+      sl_bufp = hpread_get_slt (s_idx, objfile);
+      /* Only record "normal" entries in the SLT.  */
+      if (sl_bufp->snorm.sltdesc == SLT_NORMAL
+         || sl_bufp->snorm.sltdesc == SLT_EXIT)
+       record_line (subfile, sl_bufp->snorm.line, sl_bufp->snorm.address);
+      s_idx++;
+    }
+  return e_idx;
+}
+
+/* Internalize one native debug symbol.  */
+
+static void
+hpread_process_one_debug_symbol (dn_bufp, name, section_offsets, objfile,
+                                text_offset, text_size, filename, index)
+     union dnttentry *dn_bufp;
+     char *name;
+     struct section_offsets *section_offsets;
+     struct objfile *objfile;
+     CORE_ADDR text_offset;
+     int text_size;
+     char *filename;
+     int index;
+{
+  unsigned long desc;
+  int type;
+  CORE_ADDR valu;
+  int offset = ANOFFSET (section_offsets, SECT_OFF_TEXT);
+  union dnttentry *dn_temp;
+  DNTTPOINTER hp_type;
+  struct symbol *sym;
+  struct context_stack *new;
+  char *p;
+
+  /* Allocate one GDB debug symbol and fill in some default values.  */
+  sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+                                        sizeof (struct symbol));
+  memset (sym, 0, sizeof (struct symbol));
+  SYMBOL_NAME (sym) = name;
+  SYMBOL_LANGUAGE (sym) = language_auto;
+  SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+  SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+  SYMBOL_LINE (sym) = 0;
+  SYMBOL_VALUE (sym) = 0;
+  SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+
+  hp_type.dnttp.extension = 1;
+  hp_type.dnttp.immediate = 0;
+  hp_type.dnttp.global = 0;
+  hp_type.dnttp.index = index;
+
+  type = dn_bufp->dblock.kind;
+
+  switch (type)
+    {
+    case K_SRCFILE:
+      /* This type of symbol indicates from which source file or include file
+         the following data comes. If there are no modules it also may
+         indicate the start of a new source file, in which case we must
+         finish the symbol table of the previous source file
+         (if any) and start accumulating a new symbol table.  */
+
+      valu = text_offset + offset;     /* Relocate for dynamic loading */
+      p = strrchr (name, '.');
+      if (!strcmp (p, ".h") || HAVE_MODULE (objfile)
+         || (last_source_file && !strcmp (name, last_source_file)))
+       {
+         SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+                                                   SL_INDEX (objfile),
+                                                   dn_bufp->dsfile.address,
+                                                   objfile);
+         start_subfile (name, NULL);
+         break;
+       }
+
+      if (last_source_file)
+       {
+         SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+                                                   SL_INDEX (objfile),
+                                                   dn_bufp->dsfile.address,
+                                                   objfile);
+         end_symtab (valu + text_size, 0, 0, objfile, 0);
+       }
+
+      SL_INDEX (objfile) = dn_bufp->dsfile.address;
+      start_symtab (name, NULL, valu);
+      break;
+
+    case K_MODULE:
+      /* This kind of symbol indicates the start of a module or C source
+         file */
+      valu = text_offset + offset;     /* Relocate for dynamic loading */
+      SL_INDEX (objfile) = dn_bufp->dmodule.address;
+      start_symtab (filename, NULL, valu);
+      break;
+
+    case K_FUNCTION:
+    case K_ENTRY:
+      /* A function or secondary entry point.  */
+      valu = dn_bufp->dfunc.lowaddr + offset;
+      SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+                                               SL_INDEX (objfile),
+                                               dn_bufp->dfunc.address,
+                                               objfile);
+      
+      WITHIN_FUNCTION (objfile) = 1;
+      CURRENT_FUNCTION_VALUE (objfile) = valu;
+
+      /* Stack must be empty now.  */
+      if (context_stack_depth != 0)
+       complain (&lbrac_unmatched_complaint, (char *) symnum);
+      new = push_context (0, valu);
+
+      SYMBOL_CLASS (sym) = LOC_BLOCK;
+      SYMBOL_TYPE (sym) = hpread_read_function_type (hp_type, dn_bufp, objfile);
+      if (dn_bufp->dfunc.public)
+       add_symbol_to_list (sym, &global_symbols);
+      else
+       add_symbol_to_list (sym, &file_symbols);
+      new->name = sym;
+
+      /* Search forward to the next scope beginning.  */
+      while (dn_bufp->dblock.kind != K_BEGIN)
+       {
+         dn_bufp = hpread_get_lntt (++index, objfile);
+         if (dn_bufp->dblock.extension)
+           continue;
+       }
+      SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+                                               SL_INDEX (objfile),
+                                               dn_bufp->dbegin.address,
+                                               objfile);
+      SYMBOL_LINE (sym) = hpread_get_line (dn_bufp->dbegin.address, objfile);
+      record_line (current_subfile, SYMBOL_LINE (sym), valu);
+      break;
+
+    case K_BEGIN:
+      /* Begin a new scope.  */
+      SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+                                               SL_INDEX (objfile),
+                                               dn_bufp->dbegin.address,
+                                               objfile);
+      valu = hpread_get_location (dn_bufp->dbegin.address, objfile);
+      valu += offset;          /* Relocate for dynamic loading */
+      desc = hpread_get_depth (dn_bufp->dbegin.address, objfile);
+      new = push_context (desc, valu);
+      break;
+
+    case K_END:
+      /* End a scope.  */
+      SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+                                               SL_INDEX (objfile),
+                                               dn_bufp->dend.address + 1,
+                                               objfile);
+      switch (dn_bufp->dend.endkind)
+       {
+       case K_MODULE:
+         /* Ending a module ends the symbol table for that module.  */
+         valu = text_offset + text_size + offset;
+         (void) end_symtab (valu, 0, 0, objfile, 0);
+         break;
+
+       case K_FUNCTION:
+         /* Ending a function, well, ends the function's scope.  */
+         dn_temp = hpread_get_lntt (dn_bufp->dend.beginscope.dnttp.index,
+                                    objfile);
+         valu = dn_temp->dfunc.hiaddr + offset;
+         new = pop_context ();
+         /* Make a block for the local symbols within.  */
+         finish_block (new->name, &local_symbols, new->old_blocks,
+                       new->start_addr, valu, objfile);
+         WITHIN_FUNCTION (objfile) = 0;
+         break;
+       case K_BEGIN:
+         /* Just ending a local scope.  */
+         valu = hpread_get_location (dn_bufp->dend.address, objfile);
+         /* Why in the hell is this needed?  */
+         valu += offset + 9;   /* Relocate for dynamic loading */
+         new = pop_context ();
+         desc = dn_bufp->dend.beginscope.dnttp.index;
+         if (desc != new->depth)
+           complain (&lbrac_mismatch_complaint, (char *) symnum);
+         /* Make a block for the local symbols within.  */
+         finish_block (new->name, &local_symbols, new->old_blocks,
+                       new->start_addr, valu, objfile);
+         local_symbols = new->locals;
+         break;
+       }
+      break;
+    case K_LABEL:
+      SYMBOL_NAMESPACE (sym) = LABEL_NAMESPACE;
+      break;
+    case K_FPARAM:
+      /* Function parameters.  */
+      if (dn_bufp->dfparam.regparam)
+       SYMBOL_CLASS (sym) = LOC_REGISTER;
+      else
+       SYMBOL_CLASS (sym) = LOC_LOCAL;
+      if (dn_bufp->dfparam.copyparam)
+       {
+         SYMBOL_VALUE (sym) = dn_bufp->dfparam.location;
+#ifdef HPREAD_ADJUST_STACK_ADDRESS
+         SYMBOL_VALUE (sym)
+           += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile));
+#endif
+       }
+      else
+       SYMBOL_VALUE (sym) = dn_bufp->dfparam.location;
+      SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dfparam.type, objfile);
+      add_symbol_to_list (sym, &local_symbols);
+      break;
+    case K_SVAR:
+      /* Static variables.  */
+      SYMBOL_CLASS (sym) = LOC_STATIC;
+      SYMBOL_VALUE_ADDRESS (sym) = dn_bufp->dsvar.location;
+      SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dsvar.type, objfile);
+      if (dn_bufp->dsvar.public)
+       add_symbol_to_list (sym, &global_symbols);
+      else if (WITHIN_FUNCTION (objfile))
+       add_symbol_to_list (sym, &local_symbols);
+      else
+       add_symbol_to_list (sym, &file_symbols);
+      break;
+    case K_DVAR:
+      /* Dynamic variables.  */
+      if (dn_bufp->ddvar.regvar)
+       SYMBOL_CLASS (sym) = LOC_REGISTER;
+      else
+       SYMBOL_CLASS (sym) = LOC_LOCAL;
+      SYMBOL_VALUE (sym) = dn_bufp->ddvar.location;
+#ifdef HPREAD_ADJUST_STACK_ADDRESS
+      SYMBOL_VALUE (sym)
+       += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile));
+#endif
+      SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->ddvar.type, objfile);
+      if (dn_bufp->ddvar.public)
+       add_symbol_to_list (sym, &global_symbols);
+      else if (WITHIN_FUNCTION (objfile))
+       add_symbol_to_list (sym, &local_symbols);
+      else
+       add_symbol_to_list (sym, &file_symbols);
+      break;
+    case K_CONST:
+      /* A constant (pascal?).  */
+      SYMBOL_CLASS (sym) = LOC_CONST;
+      SYMBOL_VALUE (sym) = dn_bufp->dconst.location;
+      SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dconst.type, objfile);
+      if (dn_bufp->dconst.public)
+       add_symbol_to_list (sym, &global_symbols);
+      else if (WITHIN_FUNCTION (objfile))
+       add_symbol_to_list (sym, &local_symbols);
+      else
+       add_symbol_to_list (sym, &file_symbols);
+      break;
+    case K_TYPEDEF:
+      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+      SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dtype.type, objfile);
+      if (dn_bufp->dtype.public)
+       add_symbol_to_list (sym, &global_symbols);
+      else if (WITHIN_FUNCTION (objfile))
+       add_symbol_to_list (sym, &local_symbols);
+      else
+       add_symbol_to_list (sym, &file_symbols);
+      break;
+    case K_TAGDEF:
+      SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
+      SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dtype.type, objfile);
+      TYPE_NAME (sym->type) = SYMBOL_NAME (sym);
+      TYPE_TAG_NAME (sym->type) = SYMBOL_NAME (sym);
+      if (dn_bufp->dtype.public)
+       add_symbol_to_list (sym, &global_symbols);
+      else if (WITHIN_FUNCTION (objfile))
+       add_symbol_to_list (sym, &local_symbols);
+      else
+       add_symbol_to_list (sym, &file_symbols);
+      break;
+    case K_POINTER:
+      SYMBOL_TYPE (sym) = lookup_pointer_type (hpread_type_lookup
+                                              (dn_bufp->dptr.pointsto,
+                                               objfile));
+      add_symbol_to_list (sym, &file_symbols);
+      break;
+    case K_ENUM:
+      SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
+      SYMBOL_TYPE (sym) = hpread_read_enum_type (hp_type, dn_bufp, objfile);
+      add_symbol_to_list (sym, &file_symbols);
+      break;
+    case K_MEMENUM:
+      break;
+    case K_SET:
+      SYMBOL_TYPE (sym) = hpread_read_set_type (hp_type, dn_bufp, objfile);
+      add_symbol_to_list (sym, &file_symbols);
+      break;
+    case K_SUBRANGE:
+      SYMBOL_TYPE (sym) = hpread_read_subrange_type (hp_type, dn_bufp,
+                                                    objfile);
+      add_symbol_to_list (sym, &file_symbols);
+      break;
+    case K_ARRAY:
+      SYMBOL_TYPE (sym) = hpread_read_array_type (hp_type, dn_bufp, objfile);
+      add_symbol_to_list (sym, &file_symbols);
+      break;
+    case K_STRUCT:
+    case K_UNION:
+      SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
+      SYMBOL_TYPE (sym) = hpread_read_struct_type (hp_type, dn_bufp, objfile);
+      add_symbol_to_list (sym, &file_symbols);
+      break;
+    default:
+      break;
+    }
+}
index d99101910dd94944e7734481b546fb24a60392ba..2dd2291cde69dea00c57869982b7b5c5b9a8e3bf 100644 (file)
@@ -34,13 +34,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "demangle.h"
 #include <sys/file.h>
 
-/* Size of n_value and n_strx fields in a stab symbol.  */
-#define BYTES_IN_WORD 4
-
-#if 0
-#include "aout/aout64.h"
-#endif
-
 /* Various things we might complain about... */
 
 static void
@@ -336,10 +329,15 @@ som_symfile_read (objfile, section_offsets, mainline)
 
   som_symtab_read (abfd, offset, objfile);
 
-  /* Now read information from the debugging sections.  */
+  /* Now read information from the stabs debug sections.  */
   stabsect_build_psymtabs (objfile, section_offsets, mainline,
                           "$GDB_SYMBOLS$", "$GDB_STRINGS$", "$TEXT$");
 
+/* start-sanitize-hpread */
+  /* Now read the native debug information.  */
+  hpread_build_psymtabs (objfile, section_offsets, mainline);
+/* end-sanitize-hpread */
+
   /* Install any minimal symbols that have been collected as the current
      minimal symbols for this objfile.  */
   install_minimal_symbols (objfile);
@@ -374,15 +372,21 @@ som_symfile_finish (objfile)
     {
       mfree (objfile -> md, objfile -> sym_stab_info);
     }
+/* start-sanitize-hpread */
+  hpread_symfile_finish (objfile);
+/* end-sanitize-hpread */
 }
 
 /* SOM specific initialization routine for reading symbols.
 
    Nothing SOM specific left to do anymore.  */
 static void
-som_symfile_init (ignore)
-     struct objfile *ignore;
+som_symfile_init (objfile)
+     struct objfile *objfile;
 {
+/* start-sanitize-hpread */
+  hpread_symfile_init (objfile);
+/* end-sanitize-hpread */
 }
 
 /* SOM specific parsing routine for section offsets.