--- /dev/null
+/* 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;
+ }
+}