/* Read hp debug symbols and convert to internal format, for GDB.
   Copyright 1993, 1996 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., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.

   Written by the Center for Software Science at the University of Utah
   and by Cygnus Support.  */

#include "defs.h"
#include "bfd.h"
#include "gdb_string.h"
#include "hp-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"
#include "demangle.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 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 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)

/* We put a pointer to this structure in the read_symtab_private field
   of the psymtab.  */

struct symloc
  {
    /* The offset within the file symbol table of first local symbol for
       this file.  */

    int ldsymoff;

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

    int ldsymlen;
  };

#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))

/* 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;


void hpread_symfile_init PARAMS ((struct objfile *));

static struct type *
  hpread_read_array_type PARAMS ((dnttpointer, union dnttentry *, 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 *, int));

void hpread_symfile_finish PARAMS ((struct objfile *));

static struct partial_symtab *hpread_start_psymtab
  PARAMS ((struct objfile *, 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 *, CORE_ADDR));

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 CORE_ADDR 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 ((enum dntt_entry_type));


/* 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)
    / sizeof (struct dntt_type_block);

  /* 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)
    / sizeof (struct dntt_type_block);

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

   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, mainline)
     struct objfile *objfile;
     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.  */
  free_pending_blocks ();
  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 DNTT_TYPE_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 (pst)
		  {
		    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)
		  {
		    hpread_end_psymtab (pst, psymtab_include_list,
					includes_used,
					(hp_symnum
					 * sizeof (struct dntt_type_block)),
					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 (objfile->section_offsets, SECT_OFF_TEXT);
		pst = hpread_start_psymtab (objfile,
					    namestring, valu,
					    (hp_symnum
					 * sizeof (struct dntt_type_block)),
					    objfile->global_psymbols.next,
					    objfile->static_psymbols.next);
		texthigh = valu;
		have_name = 1;
		continue;
	      }

	    case DNTT_TYPE_MODULE:
	      /* A source file.  It's still unclear to me what the
	         real difference between a DNTT_TYPE_SRCFILE and DNTT_TYPE_MODULE
	         is supposed to be.  */
	      SET_NAMESTRING (dn_bufp, &namestring, objfile);
	      valu = hpread_get_textlow (i, hp_symnum, objfile);
	      valu += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT);
	      if (!pst)
		{
		  pst = hpread_start_psymtab (objfile,
					      namestring, valu,
					      (hp_symnum
					 * sizeof (struct dntt_type_block)),
					      objfile->global_psymbols.next,
					      objfile->static_psymbols.next);
		  texthigh = valu;
		  have_name = 0;
		}
	      continue;
	    case DNTT_TYPE_FUNCTION:
	    case DNTT_TYPE_ENTRY:
	      /* The beginning of a function.  DNTT_TYPE_ENTRY may also denote
	         a secondary entry point.  */
	      valu = dn_bufp->dfunc.hiaddr + ANOFFSET (objfile->section_offsets,
						       SECT_OFF_TEXT);
	      if (valu > texthigh)
		texthigh = valu;
	      valu = dn_bufp->dfunc.lowaddr +
		ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT);
	      SET_NAMESTRING (dn_bufp, &namestring, objfile);
	      add_psymbol_to_list (namestring, strlen (namestring),
				   VAR_NAMESPACE, LOC_BLOCK,
				   &objfile->static_psymbols, valu,
				   0, language_unknown, objfile);
	      within_function = 1;
	      continue;
	    case DNTT_TYPE_BEGIN:
	    case DNTT_TYPE_END:
	      /* Scope block begin/end.  We only care about function
	         and file blocks right now.  */
	      if (dn_bufp->dend.endkind == DNTT_TYPE_MODULE)
		{
		  hpread_end_psymtab (pst, psymtab_include_list, includes_used,
				      (hp_symnum
				       * sizeof (struct dntt_type_block)),
				      texthigh,
				      dependency_list, dependencies_used);
		  pst = (struct partial_symtab *) 0;
		  includes_used = 0;
		  dependencies_used = 0;
		  have_name = 0;
		}
	      if (dn_bufp->dend.endkind == DNTT_TYPE_FUNCTION)
		within_function = 0;
	      continue;
	    case DNTT_TYPE_SVAR:
	    case DNTT_TYPE_DVAR:
	    case DNTT_TYPE_TYPEDEF:
	    case DNTT_TYPE_TAGDEF:
	      {
		/* Variables, typedefs an the like.  */
		enum address_class storage;
		namespace_enum namespace;

		/* Don't add locals to the partial symbol table.  */
		if (within_function
		    && (dn_bufp->dblock.kind == DNTT_TYPE_SVAR
			|| dn_bufp->dblock.kind == DNTT_TYPE_DVAR))
		  continue;

		/* TAGDEFs go into the structure namespace.  */
		if (dn_bufp->dblock.kind == DNTT_TYPE_TAGDEF)
		  namespace = STRUCT_NAMESPACE;
		else
		  namespace = VAR_NAMESPACE;

		/* What kind of "storage" does this use?  */
		if (dn_bufp->dblock.kind == DNTT_TYPE_SVAR)
		  storage = LOC_STATIC;
		else if (dn_bufp->dblock.kind == DNTT_TYPE_DVAR
			 && dn_bufp->ddvar.regvar)
		  storage = LOC_REGISTER;
		else if (dn_bufp->dblock.kind == DNTT_TYPE_DVAR)
		  storage = LOC_LOCAL;
		else
		  storage = LOC_UNDEF;

		SET_NAMESTRING (dn_bufp, &namestring, objfile);
		if (!pst)
		  {
		    pst = hpread_start_psymtab (objfile,
						"globals", 0,
						(hp_symnum
					 * sizeof (struct dntt_type_block)),
					      objfile->global_psymbols.next,
					     objfile->static_psymbols.next);
		  }
		if (dn_bufp->dsvar.global)
		  {
		    add_psymbol_to_list (namestring, strlen (namestring),
					 namespace, storage,
					 &objfile->global_psymbols,
					 dn_bufp->dsvar.location,
					 0, language_unknown, objfile);
		  }
		else
		  {
		    add_psymbol_to_list (namestring, strlen (namestring),
					 namespace, storage,
					 &objfile->static_psymbols,
					 dn_bufp->dsvar.location,
					 0, language_unknown, objfile);
		  }
		continue;
	      }
	    case DNTT_TYPE_MEMENUM:
	    case DNTT_TYPE_CONST:
	      /* Constants and members of enumerated types.  */
	      SET_NAMESTRING (dn_bufp, &namestring, objfile);
	      if (!pst)
		{
		  pst = hpread_start_psymtab (objfile,
					      "globals", 0,
					      (hp_symnum
					 * sizeof (struct dntt_type_block)),
					      objfile->global_psymbols.next,
					      objfile->static_psymbols.next);
		}
	      add_psymbol_to_list (namestring, strlen (namestring),
				   VAR_NAMESPACE, LOC_CONST,
				   &objfile->static_psymbols, 0,
				   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 * sizeof (struct dntt_type_block),
			  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);
    }
}


/* 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 * sizeof (struct dntt_type_block))]);
}

static union dnttentry *
hpread_get_gntt (index, objfile)
     int index;
     struct objfile *objfile;
{
  return (union dnttentry *)
    &(GNTT (objfile)[(index * sizeof (struct dntt_type_block))]);
}

static union sltentry *
hpread_get_slt (index, objfile)
     int index;
     struct objfile *objfile;
{
  return (union sltentry *) &(SLT (objfile)[index * sizeof (union sltentry)]);
}

/* 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 DNTT_TYPE_MODULE or DNTT_TYPE_SRCFILE symbol we must infer it from
   the existance of DNTT_TYPE_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 DNTT_TYPE_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 != DNTT_TYPE_FUNCTION
	 && dn_bufp->dblock.kind != DNTT_TYPE_END);

  /* Avoid going past a DNTT_TYPE_END when looking for a DNTT_TYPE_FUNCTION.  This
     might happen when a sourcefile has no functions.  */
  if (dn_bufp->dblock.kind == DNTT_TYPE_END)
    return 0;

  /* The minimal symbols are typically more accurate for some reason.  */
  msymbol = lookup_minimal_symbol (dn_bufp->dfunc.name + VT (objfile), NULL,
				   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 CORE_ADDR
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;
}


/* 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)
     enum dntt_entry_type kind;
{
  switch (kind)
    {
    case DNTT_TYPE_SRCFILE:
    case DNTT_TYPE_MODULE:
    case DNTT_TYPE_FUNCTION:
    case DNTT_TYPE_ENTRY:
    case DNTT_TYPE_IMPORT:
    case DNTT_TYPE_LABEL:
    case DNTT_TYPE_FPARAM:
    case DNTT_TYPE_SVAR:
    case DNTT_TYPE_DVAR:
    case DNTT_TYPE_CONST:
    case DNTT_TYPE_TYPEDEF:
    case DNTT_TYPE_TAGDEF:
    case DNTT_TYPE_MEMENUM:
    case DNTT_TYPE_FIELD:
    case DNTT_TYPE_SA:
      return 1;

    case DNTT_TYPE_BEGIN:
    case DNTT_TYPE_END:
    case DNTT_TYPE_WITH:
    case DNTT_TYPE_COMMON:
    case DNTT_TYPE_POINTER:
    case DNTT_TYPE_ENUM:
    case DNTT_TYPE_SET:
    case DNTT_TYPE_SUBRANGE:
    case DNTT_TYPE_ARRAY:
    case DNTT_TYPE_STRUCT:
    case DNTT_TYPE_UNION:
    case DNTT_TYPE_VARIANT:
    case DNTT_TYPE_FILE:
    case DNTT_TYPE_FUNCTYPE:
    case DNTT_TYPE_COBSTRUCT:
    case DNTT_TYPE_XREF:
    case DNTT_TYPE_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, filename, textlow, ldsymoff, global_syms,
		      static_syms)
     struct objfile *objfile;
     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;
}


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

      discard_psymtab (pst);

      /* Indicate that psymtab was thrown away.  */
      pst = (struct partial_symtab *) NULL;
    }
  return pst;
}

/* 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 (" ", gdb_stdout);
	    wrap_here ("");
	    fputs_filtered ("and ", gdb_stdout);
	    wrap_here ("");
	    printf_filtered ("%s...", pst->dependencies[i]->filename);
	    wrap_here ("");	/* Flush output */
	    gdb_flush (gdb_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);
	  gdb_flush (gdb_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 / sizeof (struct dntt_type_block);

  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) DNTT_TYPE_SRCFILE) ||
	(dn_bufp->dblock.kind == (unsigned char) DNTT_TYPE_MODULE)))
    {
      start_symtab ("globals", NULL, 0);
      record_debugformat ("HP");
    }

  max_symnum = sym_size / sizeof (struct dntt_type_block);

  /* 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, objfile, 0);
}


/* 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 HP_TYPE_BOOLEAN:
    case HP_TYPE_BOOLEAN_S300_COMPAT:
    case HP_TYPE_BOOLEAN_VAX_COMPAT:
      return FT_BOOLEAN;
      /* Ugh.  No way to distinguish between signed and unsigned chars.  */
    case HP_TYPE_CHAR:
    case HP_TYPE_WIDE_CHAR:
      return FT_CHAR;
    case HP_TYPE_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 HP_TYPE_LONG:
      return FT_LONG;
    case HP_TYPE_UNSIGNED_LONG:
      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_LONG;
      return FT_UNSIGNED_LONG_LONG;
    case HP_TYPE_UNSIGNED_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 HP_TYPE_REAL:
    case HP_TYPE_REAL_3000:
    case HP_TYPE_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 HP_TYPE_COMPLEX:
    case HP_TYPE_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 HP_TYPE_STRING200:
    case HP_TYPE_LONGSTRING200:
    case HP_TYPE_FTN_STRING_SPEC:
    case HP_TYPE_MOD_STRING_SPEC:
    case HP_TYPE_MOD_STRING_3000:
    case HP_TYPE_FTN_STRING_S300_COMPAT:
    case HP_TYPE_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 **)
		xmmalloc (objfile->md,
		     TYPE_VECTOR_LENGTH (objfile) * sizeof (struct type *));
	    }
	  while (index >= TYPE_VECTOR_LENGTH (objfile))
	    TYPE_VECTOR_LENGTH (objfile) *= 2;
	  TYPE_VECTOR (objfile) = (struct type **)
	    xmrealloc (objfile->md,
		       (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) = obsavestring (name, strlen (name),
					&objfile->symbol_obstack);
      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_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) = obsavestring (name, strlen (name),
					&objfile->symbol_obstack);

      /* 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 == DNTT_TYPE_STRUCT)
    {
      TYPE_CODE (type) = TYPE_CODE_STRUCT;
      TYPE_LENGTH (type) = dn_bufp->dstruct.bitlength / 8;
    }
  else if (dn_bufp->dblock.kind == DNTT_TYPE_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;
      FIELD_BITPOS (list->field) = fieldp->dfield.bitoffset;
      if (fieldp->dfield.bitlength % 8)
	FIELD_BITSIZE (list->field) = fieldp->dfield.bitlength;
      else
	FIELD_BITSIZE (list->field) = 0;
      nfields++;
      field = fieldp->dfield.nextfield;
      FIELD_TYPE (list->field) = 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 an array of length zero.  */
      TYPE_LENGTH (type) = 0;
    }
  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 DNTT_TYPE_SRCFILE:
    case DNTT_TYPE_MODULE:
    case DNTT_TYPE_FUNCTION:
    case DNTT_TYPE_ENTRY:
    case DNTT_TYPE_BEGIN:
    case DNTT_TYPE_END:
    case DNTT_TYPE_IMPORT:
    case DNTT_TYPE_LABEL:
    case DNTT_TYPE_WITH:
    case DNTT_TYPE_COMMON:
    case DNTT_TYPE_FPARAM:
    case DNTT_TYPE_SVAR:
    case DNTT_TYPE_DVAR:
    case DNTT_TYPE_CONST:
      /* Opps.  Something went very wrong.  */
      return lookup_fundamental_type (objfile, FT_VOID);

    case DNTT_TYPE_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 DNTT_TYPE_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 == DNTT_TYPE_STRUCT)
	  prefix = "struct ";
	else if (dn_bufp->dblock.kind == DNTT_TYPE_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 DNTT_TYPE_POINTER:
      return lookup_pointer_type (hpread_type_lookup (dn_bufp->dptr.pointsto,
						      objfile));
    case DNTT_TYPE_ENUM:
      return hpread_read_enum_type (hp_type, dn_bufp, objfile);
    case DNTT_TYPE_MEMENUM:
      return lookup_fundamental_type (objfile, FT_VOID);
    case DNTT_TYPE_SET:
      return hpread_read_set_type (hp_type, dn_bufp, objfile);
    case DNTT_TYPE_SUBRANGE:
      return hpread_read_subrange_type (hp_type, dn_bufp, objfile);
    case DNTT_TYPE_ARRAY:
      return hpread_read_array_type (hp_type, dn_bufp, objfile);
    case DNTT_TYPE_STRUCT:
    case DNTT_TYPE_UNION:
      return hpread_read_struct_type (hp_type, dn_bufp, objfile);
    case DNTT_TYPE_FIELD:
      return hpread_type_lookup (dn_bufp->dfield.type, objfile);
    case DNTT_TYPE_VARIANT:
    case DNTT_TYPE_FILE:
      return lookup_fundamental_type (objfile, FT_VOID);
    case DNTT_TYPE_FUNCTYPE:
      return lookup_function_type (hpread_type_lookup (dn_bufp->dfunctype.retval,
						       objfile));
    case DNTT_TYPE_COBSTRUCT:
    case DNTT_TYPE_XREF:
    case DNTT_TYPE_SA:
    case DNTT_TYPE_MACRO:
    default:
      return lookup_fundamental_type (objfile, FT_VOID);
    }
}

static sltpointer
hpread_record_lines (subfile, s_idx, e_idx, objfile, offset)
     struct subfile *subfile;
     sltpointer s_idx, e_idx;
     struct objfile *objfile;
     CORE_ADDR offset;
{
  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 + offset);
      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;

  /* 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) = obsavestring (name, strlen (name), &objfile->symbol_obstack);
  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 DNTT_TYPE_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;
      if (!last_source_file)
	{
	  start_symtab (name, NULL, valu);
	  record_debugformat ("HP");
	  SL_INDEX (objfile) = dn_bufp->dsfile.address;
	}
      else
	{
	  SL_INDEX (objfile) = hpread_record_lines (current_subfile,
						    SL_INDEX (objfile),
						    dn_bufp->dsfile.address,
						    objfile, offset);
	}
      start_subfile (name, NULL);
      break;

    case DNTT_TYPE_MODULE:
      /* No need to do anything with these DNTT_TYPE_MODULE symbols anymore.  */
      break;

    case DNTT_TYPE_FUNCTION:
    case DNTT_TYPE_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, offset);

      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.global)
	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 != DNTT_TYPE_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, offset);
      SYMBOL_LINE (sym) = hpread_get_line (dn_bufp->dbegin.address, objfile);
      record_line (current_subfile, SYMBOL_LINE (sym), valu);
      break;

    case DNTT_TYPE_BEGIN:
      /* Begin a new scope.  */
      SL_INDEX (objfile) = hpread_record_lines (current_subfile,
						SL_INDEX (objfile),
						dn_bufp->dbegin.address,
						objfile, offset);
      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 DNTT_TYPE_END:
      /* End a scope.  */
      SL_INDEX (objfile) = hpread_record_lines (current_subfile,
						SL_INDEX (objfile),
						dn_bufp->dend.address + 1,
						objfile, offset);
      switch (dn_bufp->dend.endkind)
	{
	case DNTT_TYPE_MODULE:
	  /* Ending a module ends the symbol table for that module.  */
	  valu = text_offset + text_size + offset;
	  (void) end_symtab (valu, objfile, 0);
	  break;

	case DNTT_TYPE_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 DNTT_TYPE_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 DNTT_TYPE_LABEL:
      SYMBOL_NAMESPACE (sym) = LABEL_NAMESPACE;
      break;
    case DNTT_TYPE_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 DNTT_TYPE_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.global)
	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 DNTT_TYPE_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.global)
	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 DNTT_TYPE_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.global)
	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 DNTT_TYPE_TYPEDEF:
      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
      SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dtype.type, objfile);
      if (dn_bufp->dtype.global)
	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 DNTT_TYPE_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.global)
	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 DNTT_TYPE_POINTER:
      SYMBOL_TYPE (sym) = lookup_pointer_type (hpread_type_lookup
					       (dn_bufp->dptr.pointsto,
						objfile));
      add_symbol_to_list (sym, &file_symbols);
      break;
    case DNTT_TYPE_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 DNTT_TYPE_MEMENUM:
      break;
    case DNTT_TYPE_SET:
      SYMBOL_TYPE (sym) = hpread_read_set_type (hp_type, dn_bufp, objfile);
      add_symbol_to_list (sym, &file_symbols);
      break;
    case DNTT_TYPE_SUBRANGE:
      SYMBOL_TYPE (sym) = hpread_read_subrange_type (hp_type, dn_bufp,
						     objfile);
      add_symbol_to_list (sym, &file_symbols);
      break;
    case DNTT_TYPE_ARRAY:
      SYMBOL_TYPE (sym) = hpread_read_array_type (hp_type, dn_bufp, objfile);
      add_symbol_to_list (sym, &file_symbols);
      break;
    case DNTT_TYPE_STRUCT:
    case DNTT_TYPE_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;
    }
}
