/* Read a symbol table in ECOFF format (Third-Eye).

   Copyright (C) 1986-2023 Free Software Foundation, Inc.

   Original version contributed by Alessandro Forin (af@cs.cmu.edu) at
   CMU.  Major work by Per Bothner, John Gilmore and Ian Lance Taylor
   at Cygnus Support.

   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 3 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, see <http://www.gnu.org/licenses/>.  */

/* This module provides the function mdebug_build_psymtabs.  It reads
   ECOFF debugging information into partial symbol tables.  The
   debugging information is read from two structures.  A struct
   ecoff_debug_swap includes the sizes of each ECOFF structure and
   swapping routines; these are fixed for a particular target.  A
   struct ecoff_debug_info points to the debugging information for a
   particular object file.

   ECOFF symbol tables are mostly written in the byte order of the
   target machine.  However, one section of the table (the auxiliary
   symbol information) is written in the host byte order.  There is a
   bit in the other symbol info which describes which host byte order
   was used.  ECOFF thereby takes the trophy from Intel `b.out' for
   the most brain-dead adaptation of a file format to byte order.

   This module can read all four of the known byte-order combinations,
   on any type of host.  */

#include "defs.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "gdbcore.h"
#include "filenames.h"
#include "objfiles.h"
#include "gdbsupport/gdb_obstack.h"
#include "buildsym-legacy.h"
#include "stabsread.h"
#include "complaints.h"
#include "demangle.h"
#include "gdb-demangle.h"
#include "block.h"
#include "dictionary.h"
#include "mdebugread.h"
#include <sys/stat.h>
#include "psymtab.h"
#include "source.h"

#include "bfd.h"

#include "coff/ecoff.h"

#include "libaout.h"
#include "aout/aout64.h"
#include "aout/stab_gnu.h"

#include "expression.h"

#include <algorithm>

/* Provide a way to test if we have both ECOFF and ELF symbol tables.
   We use this define in order to know whether we should override a 
   symbol's ECOFF section with its ELF section.  This is necessary in 
   case the symbol's ELF section could not be represented in ECOFF.  */
#define ECOFF_IN_ELF(bfd) (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
			   && bfd_get_section_by_name (bfd, ".mdebug") != NULL)

/* The objfile we are currently reading.  */

static struct objfile *mdebugread_objfile;



/* We put a pointer to this structure in the read_symtab_private field
   of the psymtab.  */

struct md_symloc
  {
    /* Index of the FDR that this psymtab represents.  */
    int fdr_idx;
    /* The BFD that the psymtab was created from.  */
    bfd *cur_bfd;
    const struct ecoff_debug_swap *debug_swap;
    struct ecoff_debug_info *debug_info;
    struct mdebug_pending **pending_list;
    /* Pointer to external symbols for this file.  */
    EXTR *extern_tab;
    /* Size of extern_tab.  */
    int extern_count;
    enum language pst_language;
  };

#define PST_PRIVATE(p) ((struct md_symloc *)(p)->read_symtab_private)
#define FDR_IDX(p) (PST_PRIVATE(p)->fdr_idx)
#define CUR_BFD(p) (PST_PRIVATE(p)->cur_bfd)
#define DEBUG_SWAP(p) (PST_PRIVATE(p)->debug_swap)
#define DEBUG_INFO(p) (PST_PRIVATE(p)->debug_info)
#define PENDING_LIST(p) (PST_PRIVATE(p)->pending_list)

#define SC_IS_TEXT(sc) ((sc) == scText \
		   || (sc) == scRConst \
	  	   || (sc) == scInit \
	  	   || (sc) == scFini)
#define SC_IS_DATA(sc) ((sc) == scData \
		   || (sc) == scSData \
		   || (sc) == scRData \
		   || (sc) == scPData \
		   || (sc) == scXData)
#define SC_IS_COMMON(sc) ((sc) == scCommon || (sc) == scSCommon)
#define SC_IS_BSS(sc) ((sc) == scBss)
#define SC_IS_SBSS(sc) ((sc) == scSBss)
#define SC_IS_UNDEF(sc) ((sc) == scUndefined || (sc) == scSUndefined)

/* Various complaints about symbol reading that don't abort the process.  */
static void
index_complaint (const char *arg1)
{
  complaint (_("bad aux index at symbol %s"), arg1);
}

static void
unknown_ext_complaint (const char *arg1)
{
  complaint (_("unknown external symbol %s"), arg1);
}

static void
basic_type_complaint (int arg1, const char *arg2)
{
  complaint (_("cannot map ECOFF basic type 0x%x for %s"),
	     arg1, arg2);
}

static void
bad_tag_guess_complaint (const char *arg1)
{
  complaint (_("guessed tag type of %s incorrectly"), arg1);
}

static void
bad_rfd_entry_complaint (const char *arg1, int arg2, int arg3)
{
  complaint (_("bad rfd entry for %s: file %d, index %d"),
	     arg1, arg2, arg3);
}

static void
unexpected_type_code_complaint (const char *arg1)
{
  complaint (_("unexpected type code for %s"), arg1);
}

/* Macros and extra defs.  */

/* Puns: hard to find whether -g was used and how.  */

#define MIN_GLEVEL GLEVEL_0
#define compare_glevel(a,b)					\
	(((a) == GLEVEL_3) ? ((b) < GLEVEL_3) :			\
	 ((b) == GLEVEL_3) ? -1 : (int)((b) - (a)))

/* Things that really are local to this module.  */

/* Remember what we deduced to be the source language of this psymtab.  */

static enum language psymtab_language = language_unknown;

/* Current BFD.  */

static bfd *cur_bfd;

/* How to parse debugging information for CUR_BFD.  */

static const struct ecoff_debug_swap *debug_swap;

/* Pointers to debugging information for CUR_BFD.  */

static struct ecoff_debug_info *debug_info;

/* Pointer to current file descriptor record, and its index.  */

static FDR *cur_fdr;
static int cur_fd;

/* Index of current symbol.  */

static int cur_sdx;

/* Note how much "debuggable" this image is.  We would like
   to see at least one FDR with full symbols.  */

static int max_gdbinfo;
static int max_glevel;

/* When examining .o files, report on undefined symbols.  */

static int n_undef_symbols, n_undef_labels, n_undef_vars, n_undef_procs;

/* Pseudo symbol to use when putting stabs into the symbol table.  */

static char stabs_symbol[] = STABS_SYMBOL;

/* Nonzero if we have seen ecoff debugging info for a file.  */

static int found_ecoff_debugging_info;

/* Forward declarations.  */

static int upgrade_type (int, struct type **, int, union aux_ext *,
			 int, const char *);

static void parse_partial_symbols (minimal_symbol_reader &,
				   psymtab_storage *,
				   struct objfile *);

static int has_opaque_xref (FDR *, SYMR *);

static int cross_ref (int, union aux_ext *, struct type **, enum type_code,
		      const char **, int, const char *);

static struct symbol *new_symbol (const char *);

static struct type *new_type (char *);

enum block_type { FUNCTION_BLOCK, NON_FUNCTION_BLOCK };

static struct block *new_block (struct objfile *objfile,
				enum block_type, enum language);

static struct compunit_symtab *new_symtab (const char *, int, struct objfile *);

static struct linetable *new_linetable (int);

static struct blockvector *new_bvect (int);

static struct type *parse_type (int, union aux_ext *, unsigned int, int *,
				int, const char *);

static struct symbol *mylookup_symbol (const char *, const struct block *,
				       domain_enum, enum address_class);

static void sort_blocks (struct symtab *);

static legacy_psymtab *new_psymtab (const char *, psymtab_storage *,
				    struct objfile *);

static void mdebug_expand_psymtab (legacy_psymtab *pst,
				  struct objfile *objfile);

static void add_block (struct block *, struct symtab *);

static void add_symbol (struct symbol *, struct symtab *, struct block *);

static int add_line (struct linetable *, int, CORE_ADDR, int);

static struct linetable *shrink_linetable (struct linetable *);

static void handle_psymbol_enumerators (struct objfile *, psymtab_storage *,
					partial_symtab *,
					FDR *, int, CORE_ADDR);

static const char *mdebug_next_symbol_text (struct objfile *);

/* Exported procedure: Builds a symtab from the partial symtab SELF.
   Restores the environment in effect when SELF was created, delegates
   most of the work to an ancillary procedure, and sorts
   and reorders the symtab list at the end.  SELF is not NULL.  */

static void
mdebug_read_symtab (legacy_psymtab *self, struct objfile *objfile)
{
  next_symbol_text_func = mdebug_next_symbol_text;

  self->expand_psymtab (objfile);

  /* 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 (objfile);
}

/* File-level interface functions.  */

/* Find a file descriptor given its index RF relative to a file CF.  */

static FDR *
get_rfd (int cf, int rf)
{
  FDR *fdrs;
  FDR *f;
  RFDT rfd;

  fdrs = debug_info->fdr;
  f = fdrs + cf;
  /* Object files do not have the RFD table, all refs are absolute.  */
  if (f->rfdBase == 0)
    return fdrs + rf;
  (*debug_swap->swap_rfd_in) (cur_bfd,
			      ((char *) debug_info->external_rfd
			       + ((f->rfdBase + rf)
				  * debug_swap->external_rfd_size)),
			      &rfd);
  return fdrs + rfd;
}

/* Return a safer print NAME for a file descriptor.  */

static const char *
fdr_name (FDR *f)
{
  if (f->rss == -1)
    return "<stripped file>";
  if (f->rss == 0)
    return "<NFY>";
  return debug_info->ss + f->issBase + f->rss;
}


/* Read in and parse the symtab of the file OBJFILE.  Symbols from
   different sections are relocated via the SECTION_OFFSETS.  */

void
mdebug_build_psymtabs (minimal_symbol_reader &reader,
		       struct objfile *objfile,
		       const struct ecoff_debug_swap *swap,
		       struct ecoff_debug_info *info)
{
  cur_bfd = objfile->obfd.get ();
  debug_swap = swap;
  debug_info = info;

  stabsread_new_init ();
  free_header_files ();
  init_header_files ();
	
  /* Make sure all the FDR information is swapped in.  */
  if (info->fdr == NULL)
    {
      char *fdr_src;
      char *fdr_end;
      FDR *fdr_ptr;

      info->fdr = (FDR *) XOBNEWVEC (&objfile->objfile_obstack, FDR,
				     info->symbolic_header.ifdMax);
      fdr_src = (char *) info->external_fdr;
      fdr_end = (fdr_src
		 + info->symbolic_header.ifdMax * swap->external_fdr_size);
      fdr_ptr = info->fdr;
      for (; fdr_src < fdr_end; fdr_src += swap->external_fdr_size, fdr_ptr++)
	(*swap->swap_fdr_in) (objfile->obfd.get (), fdr_src, fdr_ptr);
    }

  psymbol_functions *psf = new psymbol_functions ();
  psymtab_storage *partial_symtabs = psf->get_partial_symtabs ().get ();
  objfile->qf.emplace_front (psf);
  parse_partial_symbols (reader, partial_symtabs, objfile);

#if 0
  /* Check to make sure file was compiled with -g.  If not, warn the
     user of this limitation.  */
  if (compare_glevel (max_glevel, GLEVEL_2) < 0)
    {
      if (max_gdbinfo == 0)
	gdb_printf (_("\n%s not compiled with -g, "
		      "debugging support is limited.\n"),
		    objfile->name);
      gdb_printf (_("You should compile with -g2 or "
		    "-g3 for best debugging support.\n"));
    }
#endif
}

/* Local utilities */

/* Map of FDR indexes to partial symtabs.  */

struct pst_map
{
  legacy_psymtab *pst = nullptr;  /* the psymtab proper */
  long n_globals = 0;		  /* exported globals (external symbols) */
  long globals_offset = 0;	  /* cumulative */
};


/* Utility stack, used to nest procedures and blocks properly.
   It is a doubly linked list, to avoid too many alloc/free.
   Since we might need it quite a few times it is NOT deallocated
   after use.  */

static struct parse_stack
  {
    struct parse_stack *next, *prev;
    struct symtab *cur_st;	/* Current symtab.  */
    struct block *cur_block;	/* Block in it.  */

    /* What are we parsing.  stFile, or stBlock are for files and
       blocks.  stProc or stStaticProc means we have seen the start of a
       procedure, but not the start of the block within in.  When we see
       the start of that block, we change it to stNil, without pushing a
       new block, i.e. stNil means both a procedure and a block.  */

    int blocktype;

    struct type *cur_type;	/* Type we parse fields for.  */
    int cur_field;		/* Field number in cur_type.  */
    CORE_ADDR procadr;		/* Start addres of this procedure.  */
    int numargs;		/* Its argument count.  */
  }

 *top_stack;			/* Top stack ptr */


/* Enter a new lexical context.  */

static void
push_parse_stack (void)
{
  struct parse_stack *newobj;

  /* Reuse frames if possible.  */
  if (top_stack && top_stack->prev)
    newobj = top_stack->prev;
  else
    newobj = XCNEW (struct parse_stack);
  /* Initialize new frame with previous content.  */
  if (top_stack)
    {
      struct parse_stack *prev = newobj->prev;

      *newobj = *top_stack;
      top_stack->prev = newobj;
      newobj->prev = prev;
      newobj->next = top_stack;
    }
  top_stack = newobj;
}

/* Exit a lexical context.  */

static void
pop_parse_stack (void)
{
  if (!top_stack)
    return;
  if (top_stack->next)
    top_stack = top_stack->next;
}


/* Cross-references might be to things we haven't looked at
   yet, e.g. type references.  To avoid too many type
   duplications we keep a quick fixup table, an array
   of lists of references indexed by file descriptor.  */

struct mdebug_pending
{
  struct mdebug_pending *next;	/* link */
  char *s;			/* the unswapped symbol */
  struct type *t;		/* its partial type descriptor */
};


/* The pending information is kept for an entire object file.  We
   allocate the pending information table when we create the partial
   symbols, and we store a pointer to the single table in each
   psymtab.  */

static struct mdebug_pending **pending_list;

/* Check whether we already saw symbol SH in file FH.  */

static struct mdebug_pending *
is_pending_symbol (FDR *fh, char *sh)
{
  int f_idx = fh - debug_info->fdr;
  struct mdebug_pending *p;

  /* Linear search is ok, list is typically no more than 10 deep.  */
  for (p = pending_list[f_idx]; p; p = p->next)
    if (p->s == sh)
      break;
  return p;
}

/* Add a new symbol SH of type T.  */

static void
add_pending (FDR *fh, char *sh, struct type *t)
{
  int f_idx = fh - debug_info->fdr;
  struct mdebug_pending *p = is_pending_symbol (fh, sh);

  /* Make sure we do not make duplicates.  */
  if (!p)
    {
      p = XOBNEW (&mdebugread_objfile->objfile_obstack, mdebug_pending);
      p->s = sh;
      p->t = t;
      p->next = pending_list[f_idx];
      pending_list[f_idx] = p;
    }
}


/* Parsing Routines proper.  */

static void
reg_value_complaint (int regnum, int num_regs, const char *sym)
{
  complaint (_("bad register number %d (max %d) in symbol %s"),
	     regnum, num_regs - 1, sym);
}

/* Parse a single symbol.  Mostly just make up a GDB symbol for it.
   For blocks, procedures and types we open a new lexical context.
   This is basically just a big switch on the symbol's type.  Argument
   AX is the base pointer of aux symbols for this file (fh->iauxBase).
   EXT_SH points to the unswapped symbol, which is needed for struct,
   union, etc., types; it is NULL for an EXTR.  BIGEND says whether
   aux symbols are big-endian or little-endian.  Return count of
   SYMR's handled (normally one).  */

static int
mdebug_reg_to_regnum (struct symbol *sym, struct gdbarch *gdbarch)
{
  int regno = gdbarch_ecoff_reg_to_regnum (gdbarch, sym->value_longest ());

  if (regno < 0 || regno >= gdbarch_num_cooked_regs (gdbarch))
    {
      reg_value_complaint (regno, gdbarch_num_cooked_regs (gdbarch),
			   sym->print_name ());

      regno = gdbarch_sp_regnum (gdbarch); /* Known safe, though useless.  */
    }

  return regno;
}

static const struct symbol_register_ops mdebug_register_funcs = {
  mdebug_reg_to_regnum
};

/* The "aclass" indices for computed symbols.  */

static int mdebug_register_index;
static int mdebug_regparm_index;

/* Common code for symbols describing data.  */

static void
add_data_symbol (SYMR *sh, union aux_ext *ax, int bigend,
		 struct symbol *s, int aclass_index, struct block *b,
		 struct objfile *objfile, const char *name)
{
  s->set_domain (VAR_DOMAIN);
  s->set_aclass_index (aclass_index);
  add_symbol (s, top_stack->cur_st, b);

  /* Type could be missing if file is compiled without debugging info.  */
  if (SC_IS_UNDEF (sh->sc)
      || sh->sc == scNil || sh->index == indexNil)
    s->set_type (builtin_type (objfile)->nodebug_data_symbol);
  else
    s->set_type (parse_type (cur_fd, ax, sh->index, 0, bigend, name));
  /* Value of a data symbol is its memory address.  */
}

static int
parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend,
	      const section_offsets &section_offsets, struct objfile *objfile)
{
  struct gdbarch *gdbarch = objfile->arch ();
  const bfd_size_type external_sym_size = debug_swap->external_sym_size;
  void (*const swap_sym_in) (bfd *, void *, SYMR *) = debug_swap->swap_sym_in;
  const char *name;
  struct symbol *s;
  struct block *b;
  struct mdebug_pending *pend;
  struct type *t;
  int count = 1;
  TIR tir;
  long svalue = sh->value;
  int bitsize;

  if (ext_sh == NULL)
    name = debug_info->ssext + sh->iss;
  else
    name = debug_info->ss + cur_fdr->issBase + sh->iss;

  int section_index = -1;
  switch (sh->sc)
    {
    case scText:
    case scRConst:
      /* Do not relocate relative values.
	 The value of a stEnd symbol is the displacement from the
	 corresponding start symbol value.
	 The value of a stBlock symbol is the displacement from the
	 procedure address.  */
      if (sh->st != stEnd && sh->st != stBlock)
	section_index = SECT_OFF_TEXT (objfile);
      break;
    case scData:
    case scSData:
    case scRData:
    case scPData:
    case scXData:
      section_index = SECT_OFF_DATA (objfile);
      break;
    case scBss:
    case scSBss:
      section_index = SECT_OFF_BSS (objfile);
      break;
    }

  if (section_index != -1)
    sh->value += section_offsets[section_index];

  switch (sh->st)
    {
    case stNil:
      break;

    case stGlobal:		/* External symbol, goes into global block.  */
      b = top_stack->cur_st->compunit ()->blockvector ()->global_block ();
      s = new_symbol (name);
      s->set_section_index (section_index);
      s->set_value_address (sh->value);
      add_data_symbol (sh, ax, bigend, s, LOC_STATIC, b, objfile, name);
      break;

    case stStatic:		/* Static data, goes into current block.  */
      b = top_stack->cur_block;
      s = new_symbol (name);
      if (SC_IS_COMMON (sh->sc))
	{
	  /* It is a FORTRAN common block.  At least for SGI Fortran the
	     address is not in the symbol; we need to fix it later in
	     scan_file_globals.  */
	  int bucket = hashname (s->linkage_name ());
	  s->set_value_chain (global_sym_chain[bucket]);
	  global_sym_chain[bucket] = s;
	}
      else
	{
	  s->set_section_index (section_index);
	  s->set_value_address (sh->value);
	}
      add_data_symbol (sh, ax, bigend, s, LOC_STATIC, b, objfile, name);
      break;

    case stLocal:		/* Local variable, goes into current block.  */
      b = top_stack->cur_block;
      s = new_symbol (name);
      s->set_value_longest (svalue);
      if (sh->sc == scRegister)
	add_data_symbol (sh, ax, bigend, s, mdebug_register_index,
			 b, objfile, name);
      else
	add_data_symbol (sh, ax, bigend, s, LOC_LOCAL,
			 b, objfile, name);
      break;

    case stParam:		/* Arg to procedure, goes into current
				   block.  */
      max_gdbinfo++;
      found_ecoff_debugging_info = 1;
      top_stack->numargs++;

      /* Special GNU C++ name.  */
      if (is_cplus_marker (name[0]) && name[1] == 't' && name[2] == 0)
	name = "this";		/* FIXME, not alloc'd in obstack.  */
      s = new_symbol (name);

      s->set_domain (VAR_DOMAIN);
      s->set_is_argument (1);
      switch (sh->sc)
	{
	case scRegister:
	  /* Pass by value in register.  */
	  s->set_aclass_index (mdebug_register_index);
	  break;
	case scVar:
	  /* Pass by reference on stack.  */
	  s->set_aclass_index (LOC_REF_ARG);
	  break;
	case scVarRegister:
	  /* Pass by reference in register.  */
	  s->set_aclass_index (mdebug_regparm_index);
	  break;
	default:
	  /* Pass by value on stack.  */
	  s->set_aclass_index (LOC_ARG);
	  break;
	}
      s->set_value_longest (svalue);
      s->set_type (parse_type (cur_fd, ax, sh->index, 0, bigend, name));
      add_symbol (s, top_stack->cur_st, top_stack->cur_block);
      break;

    case stLabel:		/* label, goes into current block.  */
      s = new_symbol (name);
      s->set_domain (VAR_DOMAIN);	/* So that it can be used */
      s->set_aclass_index (LOC_LABEL);	/* but not misused.  */
      s->set_section_index (section_index);
      s->set_value_address (sh->value);
      s->set_type (builtin_type (objfile)->builtin_int);
      add_symbol (s, top_stack->cur_st, top_stack->cur_block);
      break;

    case stProc:	/* Procedure, usually goes into global block.  */
    case stStaticProc:	/* Static procedure, goes into current block.  */
      /* For stProc symbol records, we need to check the storage class
	 as well, as only (stProc, scText) entries represent "real"
	 procedures - See the Compaq document titled "Object File /
	 Symbol Table Format Specification" for more information.
	 If the storage class is not scText, we discard the whole block
	 of symbol records for this stProc.  */
      if (sh->st == stProc && sh->sc != scText)
	{
	  char *ext_tsym = ext_sh;
	  int keep_counting = 1;
	  SYMR tsym;

	  while (keep_counting)
	    {
	      ext_tsym += external_sym_size;
	      (*swap_sym_in) (cur_bfd, ext_tsym, &tsym);
	      count++;
	      switch (tsym.st)
		{
		  case stParam:
		    break;
		  case stEnd:
		    keep_counting = 0;
		    break;
		  default:
		    complaint (_("unknown symbol type 0x%x"), sh->st);
		    break;
		}
	    }
	  break;
	}
      s = new_symbol (name);
      s->set_domain (VAR_DOMAIN);
      s->set_aclass_index (LOC_BLOCK);
      s->set_section_index (section_index);
      /* Type of the return value.  */
      if (SC_IS_UNDEF (sh->sc) || sh->sc == scNil)
	t = builtin_type (objfile)->builtin_int;
      else
	{
	  t = parse_type (cur_fd, ax, sh->index + 1, 0, bigend, name);
	  if (strcmp (name, "malloc") == 0
	      && t->code () == TYPE_CODE_VOID)
	    {
	      /* I don't know why, but, at least under Alpha GNU/Linux,
		 when linking against a malloc without debugging
		 symbols, its read as a function returning void---this
		 is bad because it means we cannot call functions with
		 string arguments interactively; i.e., "call
		 printf("howdy\n")" would fail with the error message
		 "program has no memory available".  To avoid this, we
		 patch up the type and make it void*
		 instead. (davidm@azstarnet.com).  */
	      t = make_pointer_type (t, NULL);
	    }
	}
      b = top_stack->cur_block;
      if (sh->st == stProc)
	{
	  struct blockvector *bv
	    = top_stack->cur_st->compunit ()->blockvector ();

	  /* The next test should normally be true, but provides a
	     hook for nested functions (which we don't want to make
	     global).  */
	  if (b == bv->static_block ())
	    b = bv->global_block ();
	  /* Irix 5 sometimes has duplicate names for the same
	     function.  We want to add such names up at the global
	     level, not as a nested function.  */
	  else if (sh->value == top_stack->procadr)
	    b = bv->global_block ();
	}
      add_symbol (s, top_stack->cur_st, b);

      /* Make a type for the procedure itself.  */
      s->set_type (lookup_function_type (t));

      /* All functions in C++ have prototypes.  For C we don't have enough
	 information in the debug info.  */
      if (s->language () == language_cplus)
	s->type ()->set_is_prototyped (true);

      /* Create and enter a new lexical context.  */
      b = new_block (objfile, FUNCTION_BLOCK, s->language ());
      s->set_value_block (b);
      b->set_function (s);
      b->set_start (sh->value);
      b->set_end (sh->value);
      b->set_superblock (top_stack->cur_block);
      add_block (b, top_stack->cur_st);

      /* Not if we only have partial info.  */
      if (SC_IS_UNDEF (sh->sc) || sh->sc == scNil)
	break;

      push_parse_stack ();
      top_stack->cur_block = b;
      top_stack->blocktype = sh->st;
      top_stack->cur_type = s->type ();
      top_stack->cur_field = -1;
      top_stack->procadr = sh->value;
      top_stack->numargs = 0;
      break;

      /* Beginning of code for structure, union, and enum definitions.
	 They all share a common set of local variables, defined here.  */
      {
	enum type_code type_code;
	char *ext_tsym;
	int nfields;
	long max_value;
	struct field *f;

    case stStruct:		/* Start a block defining a struct type.  */
	type_code = TYPE_CODE_STRUCT;
	goto structured_common;

    case stUnion:		/* Start a block defining a union type.  */
	type_code = TYPE_CODE_UNION;
	goto structured_common;

    case stEnum:		/* Start a block defining an enum type.  */
	type_code = TYPE_CODE_ENUM;
	goto structured_common;

    case stBlock:		/* Either a lexical block, or some type.  */
	if (sh->sc != scInfo && !SC_IS_COMMON (sh->sc))
	  goto case_stBlock_code;	/* Lexical block */

	type_code = TYPE_CODE_UNDEF;	/* We have a type.  */

	/* Common code for handling struct, union, enum, and/or as-yet-
	   unknown-type blocks of info about structured data.  `type_code'
	   has been set to the proper TYPE_CODE, if we know it.  */
      structured_common:
	found_ecoff_debugging_info = 1;
	push_parse_stack ();
	top_stack->blocktype = stBlock;

	/* First count the number of fields and the highest value.  */
	nfields = 0;
	max_value = 0;
	for (ext_tsym = ext_sh + external_sym_size;
	     ;
	     ext_tsym += external_sym_size)
	  {
	    SYMR tsym;

	    (*swap_sym_in) (cur_bfd, ext_tsym, &tsym);

	    switch (tsym.st)
	      {
	      case stEnd:
		/* C++ encodes class types as structures where there the
		   methods are encoded as stProc.  The scope of stProc
		   symbols also ends with stEnd, thus creating a risk of
		   taking the wrong stEnd symbol record as the end of
		   the current struct, which would cause GDB to undercount
		   the real number of fields in this struct.  To make sure
		   we really reached the right stEnd symbol record, we
		   check the associated name, and match it against the
		   struct name.  Since method names are mangled while
		   the class name is not, there is no risk of having a
		   method whose name is identical to the class name
		   (in particular constructor method names are different
		   from the class name).  There is therefore no risk that
		   this check stops the count on the StEnd of a method.
		   
		   Also, assume that we're really at the end when tsym.iss
		   is 0 (issNull).  */
		if (tsym.iss == issNull
		    || strcmp (debug_info->ss + cur_fdr->issBase + tsym.iss,
			       name) == 0)
		  goto end_of_fields;
		break;

	      case stMember:
		if (nfields == 0 && type_code == TYPE_CODE_UNDEF)
		  {
		    /* If the type of the member is Nil (or Void),
		       without qualifiers, assume the tag is an
		       enumeration.
		       Alpha cc -migrate enums are recognized by a zero
		       index and a zero symbol value.
		       DU 4.0 cc enums are recognized by a member type of
		       btEnum without qualifiers and a zero symbol value.  */
		    if (tsym.index == indexNil
			|| (tsym.index == 0 && sh->value == 0))
		      type_code = TYPE_CODE_ENUM;
		    else
		      {
			(*debug_swap->swap_tir_in) (bigend,
						    &ax[tsym.index].a_ti,
						    &tir);
			if ((tir.bt == btNil || tir.bt == btVoid
			     || (tir.bt == btEnum && sh->value == 0))
			    && tir.tq0 == tqNil)
			  type_code = TYPE_CODE_ENUM;
		      }
		  }
		nfields++;
		if (tsym.value > max_value)
		  max_value = tsym.value;
		break;

	      case stBlock:
	      case stUnion:
	      case stEnum:
	      case stStruct:
		{
#if 0
		  /* This is a no-op; is it trying to tell us something
		     we should be checking?  */
		  if (tsym.sc == scVariant);	/*UNIMPLEMENTED */
#endif
		  if (tsym.index != 0)
		    {
		      /* This is something like a struct within a
			 struct.  Skip over the fields of the inner
			 struct.  The -1 is because the for loop will
			 increment ext_tsym.  */
		      ext_tsym = ((char *) debug_info->external_sym
				  + ((cur_fdr->isymBase + tsym.index - 1)
				     * external_sym_size));
		    }
		}
		break;

	      case stTypedef:
		/* mips cc puts out a typedef for struct x if it is not yet
		   defined when it encounters
		   struct y { struct x *xp; };
		   Just ignore it.  */
		break;

	      case stIndirect:
		/* Irix5 cc puts out a stIndirect for struct x if it is not
		   yet defined when it encounters
		   struct y { struct x *xp; };
		   Just ignore it.  */
		break;

	      default:
		complaint (_("declaration block contains "
			     "unhandled symbol type %d"),
			   tsym.st);
	      }
	  }
      end_of_fields:

	/* In an stBlock, there is no way to distinguish structs,
	   unions, and enums at this point.  This is a bug in the
	   original design (that has been fixed with the recent
	   addition of the stStruct, stUnion, and stEnum symbol
	   types.)  The way you can tell is if/when you see a variable
	   or field of that type.  In that case the variable's type
	   (in the AUX table) says if the type is struct, union, or
	   enum, and points back to the stBlock here.  So you can
	   patch the tag kind up later - but only if there actually is
	   a variable or field of that type.

	   So until we know for sure, we will guess at this point.
	   The heuristic is:
	   If the first member has index==indexNil or a void type,
	   assume we have an enumeration.
	   Otherwise, if there is more than one member, and all
	   the members have offset 0, assume we have a union.
	   Otherwise, assume we have a struct.

	   The heuristic could guess wrong in the case of of an
	   enumeration with no members or a union with one (or zero)
	   members, or when all except the last field of a struct have
	   width zero.  These are uncommon and/or illegal situations,
	   and in any case guessing wrong probably doesn't matter
	   much.

	   But if we later do find out we were wrong, we fixup the tag
	   kind.  Members of an enumeration must be handled
	   differently from struct/union fields, and that is harder to
	   patch up, but luckily we shouldn't need to.  (If there are
	   any enumeration members, we can tell for sure it's an enum
	   here.)  */

	if (type_code == TYPE_CODE_UNDEF)
	  {
	    if (nfields > 1 && max_value == 0)
	      type_code = TYPE_CODE_UNION;
	    else
	      type_code = TYPE_CODE_STRUCT;
	  }

	/* Create a new type or use the pending type.  */
	pend = is_pending_symbol (cur_fdr, ext_sh);
	if (pend == NULL)
	  {
	    t = new_type (NULL);
	    add_pending (cur_fdr, ext_sh, t);
	  }
	else
	  t = pend->t;

	/* Do not set the tag name if it is a compiler generated tag name
	   (.Fxx or .xxfake or empty) for unnamed struct/union/enums.
	   Alpha cc puts out an sh->iss of zero for those.  */
	if (sh->iss == 0 || name[0] == '.' || name[0] == '\0')
	  t->set_name (NULL);
	else
	  t->set_name (obconcat (&mdebugread_objfile->objfile_obstack,
				 name, (char *) NULL));

	t->set_code (type_code);
	t->set_length (sh->value);
	t->alloc_fields (nfields);
	f = t->fields();

	if (type_code == TYPE_CODE_ENUM)
	  {
	    int unsigned_enum = 1;

	    /* This is a non-empty enum.  */

	    /* DEC c89 has the number of enumerators in the sh.value field,
	       not the type length, so we have to compensate for that
	       incompatibility quirk.
	       This might do the wrong thing for an enum with one or two
	       enumerators and gcc -gcoff -fshort-enums, but these cases
	       are hopefully rare enough.
	       Alpha cc -migrate has a sh.value field of zero, we adjust
	       that too.  */
	    if (t->length () == t->num_fields ()
		|| t->length () == 0)
	      t->set_length (gdbarch_int_bit (gdbarch) / HOST_CHAR_BIT);
	    for (ext_tsym = ext_sh + external_sym_size;
		 ;
		 ext_tsym += external_sym_size)
	      {
		SYMR tsym;
		struct symbol *enum_sym;

		(*swap_sym_in) (cur_bfd, ext_tsym, &tsym);

		if (tsym.st != stMember)
		  break;

		f->set_loc_enumval (tsym.value);
		f->set_type (t);
		f->set_name (debug_info->ss + cur_fdr->issBase + tsym.iss);
		f->set_bitsize (0);

		enum_sym = new (&mdebugread_objfile->objfile_obstack) symbol;
		enum_sym->set_linkage_name
		  (obstack_strdup (&mdebugread_objfile->objfile_obstack,
				   f->name ()));
		enum_sym->set_aclass_index (LOC_CONST);
		enum_sym->set_type (t);
		enum_sym->set_domain (VAR_DOMAIN);
		enum_sym->set_value_longest (tsym.value);
		if (enum_sym->value_longest () < 0)
		  unsigned_enum = 0;
		add_symbol (enum_sym, top_stack->cur_st, top_stack->cur_block);

		/* Skip the stMembers that we've handled.  */
		count++;
		f++;
	      }
	    if (unsigned_enum)
	      t->set_is_unsigned (true);
	  }
	/* Make this the current type.  */
	top_stack->cur_type = t;
	top_stack->cur_field = 0;

	/* Do not create a symbol for alpha cc unnamed structs.  */
	if (sh->iss == 0)
	  break;

	/* gcc puts out an empty struct for an opaque struct definitions,
	   do not create a symbol for it either.  */
	if (t->num_fields () == 0)
	  {
	    t->set_is_stub (true);
	    break;
	  }

	s = new_symbol (name);
	s->set_domain (STRUCT_DOMAIN);
	s->set_aclass_index (LOC_TYPEDEF);
	s->set_value_longest (0);
	s->set_type (t);
	add_symbol (s, top_stack->cur_st, top_stack->cur_block);
	break;

	/* End of local variables shared by struct, union, enum, and
	   block (as yet unknown struct/union/enum) processing.  */
      }

    case_stBlock_code:
      found_ecoff_debugging_info = 1;
      /* Beginnning of (code) block.  Value of symbol
	 is the displacement from procedure start.  */
      push_parse_stack ();

      /* Do not start a new block if this is the outermost block of a
	 procedure.  This allows the LOC_BLOCK symbol to point to the
	 block with the local variables, so funcname::var works.  */
      if (top_stack->blocktype == stProc
	  || top_stack->blocktype == stStaticProc)
	{
	  top_stack->blocktype = stNil;
	  break;
	}

      top_stack->blocktype = stBlock;
      b = new_block (objfile, NON_FUNCTION_BLOCK, psymtab_language);
      b->set_start (sh->value + top_stack->procadr);
      b->set_superblock (top_stack->cur_block);
      top_stack->cur_block = b;
      add_block (b, top_stack->cur_st);
      break;

    case stEnd:		/* end (of anything) */
      if (sh->sc == scInfo || SC_IS_COMMON (sh->sc))
	{
	  /* Finished with type */
	  top_stack->cur_type = 0;
	}
      else if (sh->sc == scText &&
	       (top_stack->blocktype == stProc ||
		top_stack->blocktype == stStaticProc))
	{
	  /* Finished with procedure */
	  struct blockvector *bv
	    = top_stack->cur_st->compunit ()->blockvector ();
	  struct mdebug_extra_func_info *e;
	  struct block *cblock = top_stack->cur_block;
	  struct type *ftype = top_stack->cur_type;

	  top_stack->cur_block->set_end
	    (top_stack->cur_block->end () + sh->value); /* size */

	  /* Make up special symbol to contain procedure specific info.  */
	  s = new_symbol (MDEBUG_EFI_SYMBOL_NAME);
	  s->set_domain (LABEL_DOMAIN);
	  s->set_aclass_index (LOC_CONST);
	  s->set_type (builtin_type (mdebugread_objfile)->builtin_void);
	  e = OBSTACK_ZALLOC (&mdebugread_objfile->objfile_obstack,
			      mdebug_extra_func_info);
	  s->set_value_bytes ((gdb_byte *) e);
	  e->numargs = top_stack->numargs;
	  e->pdr.framereg = -1;
	  add_symbol (s, top_stack->cur_st, top_stack->cur_block);

	  /* f77 emits proc-level with address bounds==[0,0],
	     So look for such child blocks, and patch them.  */
	  for (block *b_bad : bv->blocks ())
	    {
	      if (b_bad->superblock () == cblock
		  && b_bad->start () == top_stack->procadr
		  && b_bad->end () == top_stack->procadr)
		{
		  b_bad->set_start (cblock->start ());
		  b_bad->set_end (cblock->end ());
		}
	    }

	  if (ftype->num_fields () <= 0)
	    {
	      /* No parameter type information is recorded with the function's
		 type.  Set that from the type of the parameter symbols.  */
	      int nparams = top_stack->numargs;
	      int iparams;

	      if (nparams > 0)
		{
		  ftype->alloc_fields (nparams);

		  iparams = 0;
		  for (struct symbol *sym : block_iterator_range (cblock))
		    {
		      if (iparams == nparams)
			break;

		      if (sym->is_argument ())
			{
			  ftype->field (iparams).set_type (sym->type ());
			  ftype->field (iparams).set_is_artificial (false);
			  iparams++;
			}
		    }
		}
	    }
	}
      else if (sh->sc == scText && top_stack->blocktype == stBlock)
	{
	  /* End of (code) block.  The value of the symbol is the
	     displacement from the procedure`s start address of the
	     end of this block.  */
	  top_stack->cur_block->set_end (sh->value + top_stack->procadr);
	}
      else if (sh->sc == scText && top_stack->blocktype == stNil)
	{
	  /* End of outermost block.  Pop parse stack and ignore.  The
	     following stEnd of stProc will take care of the block.  */
	  ;
	}
      else if (sh->sc == scText && top_stack->blocktype == stFile)
	{
	  /* End of file.  Pop parse stack and ignore.  Higher
	     level code deals with this.  */
	  ;
	}
      else
	complaint (_("stEnd with storage class %d not handled"), sh->sc);

      pop_parse_stack ();	/* Restore previous lexical context.  */
      break;

    case stMember:		/* member of struct or union */
      {
	struct field *f = &top_stack->cur_type->field (top_stack->cur_field);
	top_stack->cur_field++;
	f->set_name (name);
	f->set_loc_bitpos (sh->value);
	bitsize = 0;
	f->set_type (parse_type (cur_fd, ax, sh->index, &bitsize, bigend,
				 name));
	f->set_bitsize (bitsize);
      }
      break;

    case stIndirect:		/* forward declaration on Irix5 */
      /* Forward declarations from Irix5 cc are handled by cross_ref,
	 skip them.  */
      break;

    case stTypedef:		/* type definition */
      found_ecoff_debugging_info = 1;

      /* Typedefs for forward declarations and opaque structs from alpha cc
	 are handled by cross_ref, skip them.  */
      if (sh->iss == 0)
	break;

      /* Parse the type or use the pending type.  */
      pend = is_pending_symbol (cur_fdr, ext_sh);
      if (pend == NULL)
	{
	  t = parse_type (cur_fd, ax, sh->index, NULL, bigend, name);
	  add_pending (cur_fdr, ext_sh, t);
	}
      else
	t = pend->t;

      /* Mips cc puts out a typedef with the name of the struct for forward
	 declarations.  These should not go into the symbol table and
	 TYPE_NAME should not be set for them.
	 They can't be distinguished from an intentional typedef to
	 the same name however:
	 x.h:
	 struct x { int ix; int jx; };
	 struct xx;
	 x.c:
	 typedef struct x x;
	 struct xx {int ixx; int jxx; };
	 generates a cross referencing stTypedef for x and xx.
	 The user visible effect of this is that the type of a pointer
	 to struct foo sometimes is given as `foo *' instead of `struct foo *'.
	 The problem is fixed with alpha cc and Irix5 cc.  */

      /* However if the typedef cross references to an opaque aggregate, it
	 is safe to omit it from the symbol table.  */

      if (has_opaque_xref (cur_fdr, sh))
	break;
      s = new_symbol (name);
      s->set_domain (VAR_DOMAIN);
      s->set_aclass_index (LOC_TYPEDEF);
      s->set_value_block (top_stack->cur_block);
      s->set_type (t);
      add_symbol (s, top_stack->cur_st, top_stack->cur_block);

      /* Incomplete definitions of structs should not get a name.  */
      if (s->type ()->name () == NULL
	  && (s->type ()->num_fields () != 0
	      || (s->type ()->code () != TYPE_CODE_STRUCT
		  && s->type ()->code () != TYPE_CODE_UNION)))
	{
	  if (s->type ()->code () == TYPE_CODE_PTR
	      || s->type ()->code () == TYPE_CODE_FUNC)
	    {
	      /* If we are giving a name to a type such as "pointer to
		 foo" or "function returning foo", we better not set
		 the TYPE_NAME.  If the program contains "typedef char
		 *caddr_t;", we don't want all variables of type char
		 * to print as caddr_t.  This is not just a
		 consequence of GDB's type management; CC and GCC (at
		 least through version 2.4) both output variables of
		 either type char * or caddr_t with the type
		 refering to the stTypedef symbol for caddr_t.  If a future
		 compiler cleans this up it GDB is not ready for it
		 yet, but if it becomes ready we somehow need to
		 disable this check (without breaking the PCC/GCC2.4
		 case).

		 Sigh.

		 Fortunately, this check seems not to be necessary
		 for anything except pointers or functions.  */
	    }
	  else
	    s->type ()->set_name (s->linkage_name ());
	}
      break;

    case stFile:		/* file name */
      push_parse_stack ();
      top_stack->blocktype = sh->st;
      break;

      /* I`ve never seen these for C */
    case stRegReloc:
      break;			/* register relocation */
    case stForward:
      break;			/* forwarding address */
    case stConstant:
      break;			/* constant */
    default:
      complaint (_("unknown symbol type 0x%x"), sh->st);
      break;
    }

  return count;
}

/* Basic types.  */

static const registry<objfile>::key<struct type *,
				    gdb::noop_deleter<struct type *>>
  basic_type_data;

static struct type *
basic_type (int bt, struct objfile *objfile)
{
  struct gdbarch *gdbarch = objfile->arch ();
  struct type **map_bt = basic_type_data.get (objfile);
  struct type *tp;

  if (bt >= btMax)
    return NULL;

  if (!map_bt)
    {
      map_bt = OBSTACK_CALLOC (&objfile->objfile_obstack,
			       btMax, struct type *);
      basic_type_data.set (objfile, map_bt);
    }

  if (map_bt[bt])
    return map_bt[bt];

  type_allocator alloc (objfile, get_current_subfile ()->language);

  switch (bt)
    {
    case btNil:
      tp = builtin_type (objfile)->builtin_void;
      break;

    case btAdr:
      tp = init_pointer_type (alloc, 32, "adr_32",
			      builtin_type (objfile)->builtin_void);
      break;

    case btChar:
      tp = init_integer_type (alloc, 8, 0, "char");
      tp->set_has_no_signedness (true);
      break;

    case btUChar:
      tp = init_integer_type (alloc, 8, 1, "unsigned char");
      break;

    case btShort:
      tp = init_integer_type (alloc, 16, 0, "short");
      break;

    case btUShort:
      tp = init_integer_type (alloc, 16, 1, "unsigned short");
      break;

    case btInt:
      tp = init_integer_type (alloc, 32, 0, "int");
      break;

   case btUInt:
      tp = init_integer_type (alloc, 32, 1, "unsigned int");
      break;

    case btLong:
      tp = init_integer_type (alloc, 32, 0, "long");
      break;

    case btULong:
      tp = init_integer_type (alloc, 32, 1, "unsigned long");
      break;

    case btFloat:
      tp = init_float_type (alloc, gdbarch_float_bit (gdbarch),
			    "float", gdbarch_float_format (gdbarch));
      break;

    case btDouble:
      tp = init_float_type (alloc, gdbarch_double_bit (gdbarch),
			    "double", gdbarch_double_format (gdbarch));
      break;

    case btComplex:
      tp = init_complex_type ("complex", basic_type (btFloat, objfile));
      break;

    case btDComplex:
      tp = init_complex_type ("double complex", basic_type (btFloat, objfile));
      break;

    case btFixedDec:
      /* We use TYPE_CODE_INT to print these as integers.  Does this do any
	 good?  Would we be better off with TYPE_CODE_ERROR?  Should
	 TYPE_CODE_ERROR print things in hex if it knows the size?  */
      tp = init_integer_type (alloc, gdbarch_int_bit (gdbarch), 0,
			      "fixed decimal");
      break;

    case btFloatDec:
      tp = alloc.new_type (TYPE_CODE_ERROR,
			   gdbarch_double_bit (gdbarch), "floating decimal");
      break;

    case btString:
      /* Is a "string" the way btString means it the same as TYPE_CODE_STRING?
	 FIXME.  */
      tp = alloc.new_type (TYPE_CODE_STRING, TARGET_CHAR_BIT, "string");
      break;

    case btVoid:
      tp = builtin_type (objfile)->builtin_void;
      break;

    case btLong64:
      tp = init_integer_type (alloc, 64, 0, "long");
      break;

    case btULong64:
      tp = init_integer_type (alloc, 64, 1, "unsigned long");
      break;

    case btLongLong64:
      tp = init_integer_type (alloc, 64, 0, "long long");
      break;

    case btULongLong64:
      tp = init_integer_type (alloc, 64, 1, "unsigned long long");
      break;

    case btAdr64:
      tp = init_pointer_type (alloc, 64, "adr_64",
			      builtin_type (objfile)->builtin_void);
      break;

    case btInt64:
      tp = init_integer_type (alloc, 64, 0, "int");
      break;

    case btUInt64:
      tp = init_integer_type (alloc, 64, 1, "unsigned int");
      break;

    default:
      tp = NULL;
      break;
    }

  map_bt[bt] = tp;
  return tp;
}

/* Parse the type information provided in the raw AX entries for
   the symbol SH.  Return the bitfield size in BS, in case.
   We must byte-swap the AX entries before we use them; BIGEND says whether
   they are big-endian or little-endian (from fh->fBigendian).  */

static struct type *
parse_type (int fd, union aux_ext *ax, unsigned int aux_index, int *bs,
	    int bigend, const char *sym_name)
{
  TIR t[1];
  struct type *tp = 0;
  enum type_code type_code = TYPE_CODE_UNDEF;

  /* Handle undefined types, they have indexNil.  */
  if (aux_index == indexNil)
    return basic_type (btInt, mdebugread_objfile);

  /* Handle corrupt aux indices.  */
  if (aux_index >= (debug_info->fdr + fd)->caux)
    {
      index_complaint (sym_name);
      return basic_type (btInt, mdebugread_objfile);
    }
  ax += aux_index;

  /* Use aux as a type information record, map its basic type.  */
  (*debug_swap->swap_tir_in) (bigend, &ax->a_ti, t);
  tp = basic_type (t->bt, mdebugread_objfile);
  if (tp == NULL)
    {
      /* Cannot use builtin types -- build our own.  */
      switch (t->bt)
	{
	case btStruct:
	  type_code = TYPE_CODE_STRUCT;
	  break;
	case btUnion:
	  type_code = TYPE_CODE_UNION;
	  break;
	case btEnum:
	  type_code = TYPE_CODE_ENUM;
	  break;
	case btRange:
	  type_code = TYPE_CODE_RANGE;
	  break;
	case btSet:
	  type_code = TYPE_CODE_SET;
	  break;
	case btIndirect:
	  /* alpha cc -migrate uses this for typedefs.  The true type will
	     be obtained by crossreferencing below.  */
	  type_code = TYPE_CODE_ERROR;
	  break;
	case btTypedef:
	  /* alpha cc uses this for typedefs.  The true type will be
	     obtained by crossreferencing below.  */
	  type_code = TYPE_CODE_ERROR;
	  break;
	default:
	  basic_type_complaint (t->bt, sym_name);
	  return basic_type (btInt, mdebugread_objfile);
	}
    }

  type_allocator alloc (mdebugread_objfile, get_current_subfile ()->language);

  /* Move on to next aux.  */
  ax++;

  if (t->fBitfield)
    {
      int width = AUX_GET_WIDTH (bigend, ax);

      /* Inhibit core dumps if TIR is corrupted.  */
      if (bs == NULL)
	{
	  /* Alpha cc -migrate encodes char and unsigned char types
	     as short and unsigned short types with a field width of 8.
	     Enum types also have a field width which we ignore for now.  */
	  if (t->bt == btShort && width == 8)
	    tp = basic_type (btChar, mdebugread_objfile);
	  else if (t->bt == btUShort && width == 8)
	    tp = basic_type (btUChar, mdebugread_objfile);
	  else if (t->bt == btEnum)
	    ;
	  else
	    complaint (_("can't handle TIR fBitfield for %s"),
		       sym_name);
	}
      else
	*bs = width;
      ax++;
    }

  /* A btIndirect entry cross references to an aux entry containing
     the type.  */
  if (t->bt == btIndirect)
    {
      RNDXR rn[1];
      int rf;
      FDR *xref_fh;
      int xref_fd;

      (*debug_swap->swap_rndx_in) (bigend, &ax->a_rndx, rn);
      ax++;
      if (rn->rfd == 0xfff)
	{
	  rf = AUX_GET_ISYM (bigend, ax);
	  ax++;
	}
      else
	rf = rn->rfd;

      if (rf == -1)
	{
	  complaint (_("unable to cross ref btIndirect for %s"), sym_name);
	  return basic_type (btInt, mdebugread_objfile);
	}
      xref_fh = get_rfd (fd, rf);
      xref_fd = xref_fh - debug_info->fdr;
      tp = parse_type (xref_fd, debug_info->external_aux + xref_fh->iauxBase,
		    rn->index, NULL, xref_fh->fBigendian, sym_name);
    }

  /* All these types really point to some (common) MIPS type
     definition, and only the type-qualifiers fully identify
     them.  We'll make the same effort at sharing.  */
  if (t->bt == btStruct ||
      t->bt == btUnion ||
      t->bt == btEnum ||

  /* btSet (I think) implies that the name is a tag name, not a typedef
     name.  This apparently is a MIPS extension for C sets.  */
      t->bt == btSet)
    {
      const char *name;

      /* Try to cross reference this type, build new type on failure.  */
      ax += cross_ref (fd, ax, &tp, type_code, &name, bigend, sym_name);
      if (tp == NULL)
	tp = alloc.new_type (type_code, 0, NULL);

      /* DEC c89 produces cross references to qualified aggregate types,
	 dereference them.  */
      while (tp->code () == TYPE_CODE_PTR
	     || tp->code () == TYPE_CODE_ARRAY)
	tp = tp->target_type ();

      /* Make sure that TYPE_CODE(tp) has an expected type code.
	 Any type may be returned from cross_ref if file indirect entries
	 are corrupted.  */
      if (tp->code () != TYPE_CODE_STRUCT
	  && tp->code () != TYPE_CODE_UNION
	  && tp->code () != TYPE_CODE_ENUM)
	{
	  unexpected_type_code_complaint (sym_name);
	}
      else
	{
	  /* Usually, TYPE_CODE(tp) is already type_code.  The main
	     exception is if we guessed wrong re struct/union/enum.
	     But for struct vs. union a wrong guess is harmless, so
	     don't complain().  */
	  if ((tp->code () == TYPE_CODE_ENUM
	       && type_code != TYPE_CODE_ENUM)
	      || (tp->code () != TYPE_CODE_ENUM
		  && type_code == TYPE_CODE_ENUM))
	    {
	      bad_tag_guess_complaint (sym_name);
	    }

	  if (tp->code () != type_code)
	    {
	      tp->set_code (type_code);
	    }

	  /* Do not set the tag name if it is a compiler generated tag name
	     (.Fxx or .xxfake or empty) for unnamed struct/union/enums.  */
	  if (name[0] == '.' || name[0] == '\0')
	    tp->set_name (NULL);
	  else if (tp->name () == NULL
		   || strcmp (tp->name (), name) != 0)
	    tp->set_name (obstack_strdup (&mdebugread_objfile->objfile_obstack,
					  name));
	}
    }

  /* All these types really point to some (common) MIPS type
     definition, and only the type-qualifiers fully identify
     them.  We'll make the same effort at sharing.
     FIXME: We are not doing any guessing on range types.  */
  if (t->bt == btRange)
    {
      const char *name;

      /* Try to cross reference this type, build new type on failure.  */
      ax += cross_ref (fd, ax, &tp, type_code, &name, bigend, sym_name);
      if (tp == NULL)
	tp = alloc.new_type (type_code, 0, NULL);

      /* Make sure that TYPE_CODE(tp) has an expected type code.
	 Any type may be returned from cross_ref if file indirect entries
	 are corrupted.  */
      if (tp->code () != TYPE_CODE_RANGE)
	{
	  unexpected_type_code_complaint (sym_name);
	}
      else
	{
	  /* Usually, TYPE_CODE(tp) is already type_code.  The main
	     exception is if we guessed wrong re struct/union/enum.  */
	  if (tp->code () != type_code)
	    {
	      bad_tag_guess_complaint (sym_name);
	      tp->set_code (type_code);
	    }
	  if (tp->name () == NULL
	      || strcmp (tp->name (), name) != 0)
	    tp->set_name (obstack_strdup (&mdebugread_objfile->objfile_obstack,
					  name));
	}
    }
  if (t->bt == btTypedef)
    {
      const char *name;

      /* Try to cross reference this type, it should succeed.  */
      ax += cross_ref (fd, ax, &tp, type_code, &name, bigend, sym_name);
      if (tp == NULL)
	{
	  complaint (_("unable to cross ref btTypedef for %s"), sym_name);
	  tp = basic_type (btInt, mdebugread_objfile);
	}
    }

  /* Deal with range types.  */
  if (t->bt == btRange)
    {
      tp->set_num_fields (0);
      tp->set_bounds (((struct range_bounds *)
			TYPE_ZALLOC (tp, sizeof (struct range_bounds))));
      tp->bounds ()->low.set_const_val (AUX_GET_DNLOW (bigend, ax));
      ax++;
      tp->bounds ()->high.set_const_val (AUX_GET_DNHIGH (bigend, ax));
      ax++;
    }

  /* Parse all the type qualifiers now.  If there are more
     than 6 the game will continue in the next aux.  */

  while (1)
    {
#define PARSE_TQ(tq) \
      if (t->tq != tqNil) \
	ax += upgrade_type(fd, &tp, t->tq, ax, bigend, sym_name); \
      else \
	break;

      PARSE_TQ (tq0);
      PARSE_TQ (tq1);
      PARSE_TQ (tq2);
      PARSE_TQ (tq3);
      PARSE_TQ (tq4);
      PARSE_TQ (tq5);
#undef	PARSE_TQ

      /* mips cc 2.x and gcc never put out continued aux entries.  */
      if (!t->continued)
	break;

      (*debug_swap->swap_tir_in) (bigend, &ax->a_ti, t);
      ax++;
    }

  /* Complain for illegal continuations due to corrupt aux entries.  */
  if (t->continued)
    complaint (_("illegal TIR continued for %s"), sym_name);

  return tp;
}

/* Make up a complex type from a basic one.  Type is passed by
   reference in TPP and side-effected as necessary.  The type
   qualifier TQ says how to handle the aux symbols at AX for
   the symbol SX we are currently analyzing.  BIGEND says whether
   aux symbols are big-endian or little-endian.
   Returns the number of aux symbols we parsed.  */

static int
upgrade_type (int fd, struct type **tpp, int tq, union aux_ext *ax, int bigend,
	      const char *sym_name)
{
  int off;
  struct type *t;

  /* Used in array processing.  */
  int rf, id;
  FDR *fh;
  struct type *range;
  struct type *indx;
  int lower, upper;
  RNDXR rndx;

  switch (tq)
    {
    case tqPtr:
      t = lookup_pointer_type (*tpp);
      *tpp = t;
      return 0;

    case tqProc:
      t = lookup_function_type (*tpp);
      *tpp = t;
      return 0;

    case tqArray:
      off = 0;

      /* Determine and record the domain type (type of index).  */
      (*debug_swap->swap_rndx_in) (bigend, &ax->a_rndx, &rndx);
      id = rndx.index;
      rf = rndx.rfd;
      if (rf == 0xfff)
	{
	  ax++;
	  rf = AUX_GET_ISYM (bigend, ax);
	  off++;
	}
      fh = get_rfd (fd, rf);

      indx = parse_type (fh - debug_info->fdr,
			 debug_info->external_aux + fh->iauxBase,
			 id, NULL, bigend, sym_name);

      /* The bounds type should be an integer type, but might be anything
	 else due to corrupt aux entries.  */
      if (indx->code () != TYPE_CODE_INT)
	{
	  complaint (_("illegal array index type for %s, assuming int"),
		     sym_name);
	  indx = builtin_type (mdebugread_objfile)->builtin_int;
	}

      /* Get the bounds, and create the array type.  */
      ax++;
      lower = AUX_GET_DNLOW (bigend, ax);
      ax++;
      upper = AUX_GET_DNHIGH (bigend, ax);
      ax++;
      rf = AUX_GET_WIDTH (bigend, ax);	/* bit size of array element */

      {
	type_allocator alloc (indx);
	range = create_static_range_type (alloc, indx, lower, upper);

	t = create_array_type (alloc, *tpp, range);
      }

      /* We used to fill in the supplied array element bitsize
	 here if the TYPE_LENGTH of the target type was zero.
	 This happens for a `pointer to an array of anonymous structs',
	 but in this case the array element bitsize is also zero,
	 so nothing is gained.
	 And we used to check the TYPE_LENGTH of the target type against
	 the supplied array element bitsize.
	 gcc causes a mismatch for `pointer to array of object',
	 since the sdb directives it uses do not have a way of
	 specifying the bitsize, but it does no harm (the
	 TYPE_LENGTH should be correct) and we should be able to
	 ignore the erroneous bitsize from the auxiliary entry safely.
	 dbx seems to ignore it too.  */

      /* TYPE_TARGET_STUB now takes care of the zero TYPE_LENGTH problem.  */
      if ((*tpp)->length () == 0)
	t->set_target_is_stub (true);

      *tpp = t;
      return 4 + off;

    case tqVol:
      /* Volatile -- currently ignored */
      return 0;

    case tqConst:
      /* Const -- currently ignored */
      return 0;

    default:
      complaint (_("unknown type qualifier 0x%x"), tq);
      return 0;
    }
}


/* Parse a procedure descriptor record PR.  Note that the procedure is
   parsed _after_ the local symbols, now we just insert the extra
   information we need into a MDEBUG_EFI_SYMBOL_NAME symbol that has
   already been placed in the procedure's main block.  Note also that
   images that have been partially stripped (ld -x) have been deprived
   of local symbols, and we have to cope with them here.  FIRST_OFF is
   the offset of the first procedure for this FDR; we adjust the
   address by this amount, but I don't know why.  SEARCH_SYMTAB is the symtab
   to look for the function which contains the MDEBUG_EFI_SYMBOL_NAME symbol
   in question, or NULL to use top_stack->cur_block.  */

static void
parse_procedure (PDR *pr, struct compunit_symtab *search_symtab,
		 legacy_psymtab *pst)
{
  struct symbol *s, *i;
  const struct block *b;
  char *sh_name;

  /* Simple rule to find files linked "-x".  */
  if (cur_fdr->rss == -1)
    {
      if (pr->isym == -1)
	{
	  /* Static procedure at address pr->adr.  Sigh.  */
	  /* FIXME-32x64.  assuming pr->adr fits in long.  */
	  complaint (_("can't handle PDR for static proc at 0x%lx"),
		     (unsigned long) pr->adr);
	  return;
	}
      else
	{
	  /* external */
	  EXTR she;

	  (*debug_swap->swap_ext_in) (cur_bfd,
				      ((char *) debug_info->external_ext
				       + (pr->isym
					  * debug_swap->external_ext_size)),
				      &she);
	  sh_name = debug_info->ssext + she.asym.iss;
	}
    }
  else
    {
      /* Full symbols */
      SYMR sh;

      (*debug_swap->swap_sym_in) (cur_bfd,
				  ((char *) debug_info->external_sym
				   + ((cur_fdr->isymBase + pr->isym)
				      * debug_swap->external_sym_size)),
				  &sh);
      sh_name = debug_info->ss + cur_fdr->issBase + sh.iss;
    }

  if (search_symtab != NULL)
    {
#if 0
      /* This loses both in the case mentioned (want a static, find a global),
	 but also if we are looking up a non-mangled name which happens to
	 match the name of a mangled function.  */
      /* We have to save the cur_fdr across the call to lookup_symbol.
	 If the pdr is for a static function and if a global function with
	 the same name exists, lookup_symbol will eventually read in the symtab
	 for the global function and clobber cur_fdr.  */
      FDR *save_cur_fdr = cur_fdr;

      s = lookup_symbol (sh_name, NULL, VAR_DOMAIN, 0);
      cur_fdr = save_cur_fdr;
#else
      s = mylookup_symbol
	(sh_name,
	 search_symtab->blockvector ()->static_block (),
	 VAR_DOMAIN,
	 LOC_BLOCK);
#endif
    }
  else
    s = mylookup_symbol (sh_name, top_stack->cur_block,
			 VAR_DOMAIN, LOC_BLOCK);

  if (s != 0)
    {
      b = s->value_block ();
    }
  else
    {
      complaint (_("PDR for %s, but no symbol"), sh_name);
#if 1
      return;
#else
/* FIXME -- delete.  We can't do symbol allocation now; it's all done.  */
      s = new_symbol (sh_name);
      s->set_domain (VAR_DOMAIN);
      SYMBOL_CLASS (s) = LOC_BLOCK;
      /* Don't know its type, hope int is ok.  */
      s->type ()
	= lookup_function_type (builtin_type (pst->objfile)->builtin_int);
      add_symbol (s, top_stack->cur_st, top_stack->cur_block);
      /* Won't have symbols for this one.  */
      b = new_block (2);
      SYMBOL_BLOCK_VALUE (s) = b;
      BLOCK_FUNCTION (b) = s;
      BLOCK_START (b) = pr->adr;
      /* BOUND used to be the end of procedure's text, but the
	 argument is no longer passed in.  */
      BLOCK_END (b) = bound;
      BLOCK_SUPERBLOCK (b) = top_stack->cur_block;
      add_block (b, top_stack->cur_st);
#endif
    }

  i = mylookup_symbol (MDEBUG_EFI_SYMBOL_NAME, b, LABEL_DOMAIN, LOC_CONST);

  if (i)
    {
      struct mdebug_extra_func_info *e;
      
      e = (struct mdebug_extra_func_info *) i->value_bytes ();
      e->pdr = *pr;

      /* GDB expects the absolute function start address for the
	 procedure descriptor in e->pdr.adr.
	 As the address in the procedure descriptor is usually relative,
	 we would have to relocate e->pdr.adr with cur_fdr->adr.
	 Unfortunately cur_fdr->adr and e->pdr.adr are both absolute
	 in shared libraries on some systems, and on other systems
	 e->pdr.adr is sometimes offset by a bogus value.
	 To work around these problems, we replace e->pdr.adr with
	 the start address of the function.  */
      e->pdr.adr = b->start ();
    }

  /* It would be reasonable that functions that have been compiled
     without debugging info have a btNil type for their return value,
     and functions that are void and are compiled with debugging info
     have btVoid.
     gcc and DEC f77 put out btNil types for both cases, so btNil is mapped
     to TYPE_CODE_VOID in parse_type to get the `compiled with debugging info'
     case right.
     The glevel field in cur_fdr could be used to determine the presence
     of debugging info, but GCC doesn't always pass the -g switch settings
     to the assembler and GAS doesn't set the glevel field from the -g switch
     settings.
     To work around these problems, the return value type of a TYPE_CODE_VOID
     function is adjusted accordingly if no debugging info was found in the
     compilation unit.  */

  if (processing_gcc_compilation == 0
      && found_ecoff_debugging_info == 0
      && s->type ()->target_type ()->code () == TYPE_CODE_VOID)
    s->set_type (builtin_type (mdebugread_objfile)->nodebug_text_symbol);
}

/* Parse the external symbol ES.  Just call parse_symbol() after
   making sure we know where the aux are for it.
   BIGEND says whether aux entries are big-endian or little-endian.

   This routine clobbers top_stack->cur_block and ->cur_st.  */

static void
parse_external (EXTR *es, int bigend, const section_offsets &section_offsets,
		struct objfile *objfile)
{
  union aux_ext *ax;

  if (es->ifd != ifdNil)
    {
      cur_fd = es->ifd;
      cur_fdr = debug_info->fdr + cur_fd;
      ax = debug_info->external_aux + cur_fdr->iauxBase;
    }
  else
    {
      cur_fdr = debug_info->fdr;
      ax = 0;
    }

  /* Reading .o files */
  if (SC_IS_UNDEF (es->asym.sc) || es->asym.sc == scNil)
    {
      const char *what;
      switch (es->asym.st)
	{
	case stNil:
	  /* These are generated for static symbols in .o files,
	     ignore them.  */
	  return;
	case stStaticProc:
	case stProc:
	  what = "procedure";
	  n_undef_procs++;
	  break;
	case stGlobal:
	  what = "variable";
	  n_undef_vars++;
	  break;
	case stLabel:
	  what = "label";
	  n_undef_labels++;
	  break;
	default:
	  what = "symbol";
	  break;
	}
      n_undef_symbols++;
      /* FIXME:  Turn this into a complaint?  */
      if (info_verbose)
	gdb_printf (_("Warning: %s `%s' is undefined (in %s)\n"),
		    what, debug_info->ssext + es->asym.iss,
		    fdr_name (cur_fdr));
      return;
    }

  switch (es->asym.st)
    {
    case stProc:
    case stStaticProc:
      /* There is no need to parse the external procedure symbols.
	 If they are from objects compiled without -g, their index will
	 be indexNil, and the symbol definition from the minimal symbol
	 is preferrable (yielding a function returning int instead of int).
	 If the index points to a local procedure symbol, the local
	 symbol already provides the correct type.
	 Note that the index of the external procedure symbol points
	 to the local procedure symbol in the local symbol table, and
	 _not_ to the auxiliary symbol info.  */
      break;
    case stGlobal:
    case stLabel:
      /* Global common symbols are resolved by the runtime loader,
	 ignore them.  */
      if (SC_IS_COMMON (es->asym.sc))
	break;

      /* Note that the case of a symbol with indexNil must be handled
	 anyways by parse_symbol().  */
      parse_symbol (&es->asym, ax, NULL,
		    bigend, section_offsets, objfile);
      break;
    default:
      break;
    }
}

/* Parse the line number info for file descriptor FH into
   GDB's linetable LT.  MIPS' encoding requires a little bit
   of magic to get things out.  Note also that MIPS' line
   numbers can go back and forth, apparently we can live
   with that and do not need to reorder our linetables.  */

static void
parse_lines (FDR *fh, PDR *pr, struct linetable *lt, int maxlines,
	     CORE_ADDR lowest_pdr_addr)
{
  unsigned char *base;
  int j, k;
  int delta, count, lineno = 0;

  if (fh->cbLine == 0)
    return;

  /* Scan by procedure descriptors.  */
  k = 0;
  for (j = 0; j < fh->cpd; j++, pr++)
    {
      CORE_ADDR l;
      CORE_ADDR adr;
      unsigned char *halt;

      /* No code for this one.  */
      if (pr->iline == ilineNil ||
	  pr->lnLow == -1 || pr->lnHigh == -1)
	continue;

      /* Determine start and end address of compressed line bytes for
	 this procedure.  */
      base = debug_info->line + fh->cbLineOffset;
      if (j != (fh->cpd - 1))
	halt = base + pr[1].cbLineOffset;
      else
	halt = base + fh->cbLine;
      base += pr->cbLineOffset;

      adr = pr->adr - lowest_pdr_addr;

      l = adr >> 2;		/* in words */
      for (lineno = pr->lnLow; base < halt;)
	{
	  count = *base & 0x0f;
	  delta = *base++ >> 4;
	  if (delta >= 8)
	    delta -= 16;
	  if (delta == -8)
	    {
	      delta = (base[0] << 8) | base[1];
	      if (delta >= 0x8000)
		delta -= 0x10000;
	      base += 2;
	    }
	  lineno += delta;	/* first delta is 0 */

	  /* Complain if the line table overflows.  Could happen
	     with corrupt binaries.  */
	  if (lt->nitems >= maxlines)
	    {
	      complaint (_("guessed size of linetable for %s incorrectly"),
			 fdr_name (fh));
	      break;
	    }
	  k = add_line (lt, lineno, l, k);
	  l += count + 1;
	}
    }
}

static void
function_outside_compilation_unit_complaint (const char *arg1)
{
  complaint (_("function `%s' appears to be defined "
	       "outside of all compilation units"),
	     arg1);
}

/* Use the STORAGE_CLASS to compute which section the given symbol
   belongs to, and then records this new minimal symbol.  */

static void
record_minimal_symbol (minimal_symbol_reader &reader,
		       const char *name, const unrelocated_addr address,
		       enum minimal_symbol_type ms_type, int storage_class,
		       struct objfile *objfile)
{
  int section;

  switch (storage_class)
    {
      case scText:
	section = SECT_OFF_TEXT (objfile);
	break;
      case scData:
	section = SECT_OFF_DATA (objfile);
	break;
      case scBss:
	section = SECT_OFF_BSS (objfile);
	break;
      case scSData:
	section = get_section_index (objfile, ".sdata");
	break;
      case scSBss:
	section = get_section_index (objfile, ".sbss");
	break;
      case scRData:
	section = get_section_index (objfile, ".rdata");
	break;
      case scInit:
	section = get_section_index (objfile, ".init");
	break;
      case scXData:
	section = get_section_index (objfile, ".xdata");
	break;
      case scPData:
	section = get_section_index (objfile, ".pdata");
	break;
      case scFini:
	section = get_section_index (objfile, ".fini");
	break;
      case scRConst:
	section = get_section_index (objfile, ".rconst");
	break;
#ifdef scTlsData
      case scTlsData:
	section = get_section_index (objfile, ".tlsdata");
	break;
#endif
#ifdef scTlsBss
      case scTlsBss:
	section = get_section_index (objfile, ".tlsbss");
	break;
#endif
      default:
	/* This kind of symbol is not associated to a section.  */
	section = -1;
    }

  reader.record_with_info (name, address, ms_type, section);
}

/* Master parsing procedure for first-pass reading of file symbols
   into a partial_symtab.  */

static void
parse_partial_symbols (minimal_symbol_reader &reader,
		       psymtab_storage *partial_symtabs,
		       struct objfile *objfile)
{
  struct gdbarch *gdbarch = objfile->arch ();
  const bfd_size_type external_sym_size = debug_swap->external_sym_size;
  const bfd_size_type external_rfd_size = debug_swap->external_rfd_size;
  const bfd_size_type external_ext_size = debug_swap->external_ext_size;
  void (*const swap_ext_in) (bfd *, void *, EXTR *) = debug_swap->swap_ext_in;
  void (*const swap_sym_in) (bfd *, void *, SYMR *) = debug_swap->swap_sym_in;
  void (*const swap_rfd_in) (bfd *, void *, RFDT *) = debug_swap->swap_rfd_in;
  int f_idx, s_idx;
  HDRR *hdr = &debug_info->symbolic_header;
  /* Running pointers */
  FDR *fh;
  char *ext_out;
  char *ext_out_end;
  EXTR *ext_in;
  EXTR *ext_in_end;
  SYMR sh;
  legacy_psymtab *pst;
  int textlow_not_set = 1;

  /* List of current psymtab's include files.  */
  const char **psymtab_include_list;
  int includes_allocated;
  int includes_used;
  EXTR *extern_tab;
  struct pst_map *fdr_to_pst;
  /* Index within current psymtab dependency list.  */
  legacy_psymtab **dependency_list;
  int dependencies_used, dependencies_allocated;
  char *name;
  enum language prev_language;
  asection *text_sect;
  int relocatable = 0;

  /* Irix 5.2 shared libraries have a fh->adr field of zero, but
     the shared libraries are prelinked at a high memory address.
     We have to adjust the start address of the object file for this case,
     by setting it to the start address of the first procedure in the file.
     But we should do no adjustments if we are debugging a .o file, where
     the text section (and fh->adr) really starts at zero.  */
  text_sect = bfd_get_section_by_name (cur_bfd, ".text");
  if (text_sect != NULL
      && (bfd_section_flags (text_sect) & SEC_RELOC))
    relocatable = 1;

  extern_tab = XOBNEWVEC (&objfile->objfile_obstack, EXTR, hdr->iextMax);

  includes_allocated = 30;
  includes_used = 0;
  psymtab_include_list = (const char **) alloca (includes_allocated *
						 sizeof (const char *));
  next_symbol_text_func = mdebug_next_symbol_text;

  dependencies_allocated = 30;
  dependencies_used = 0;
  dependency_list =
    (legacy_psymtab **) alloca (dependencies_allocated *
				sizeof (legacy_psymtab *));

  set_last_source_file (NULL);

  /*
   * Big plan:
   *
   * Only parse the Local and External symbols, and the Relative FDR.
   * Fixup enough of the loader symtab to be able to use it.
   * Allocate space only for the file's portions we need to
   * look at.  (XXX)
   */

  max_gdbinfo = 0;
  max_glevel = MIN_GLEVEL;

  /* Allocate the map FDR -> PST.
     Minor hack: -O3 images might claim some global data belongs
     to FDR -1.  We`ll go along with that.  */
  std::vector<struct pst_map> fdr_to_pst_holder (hdr->ifdMax + 1);
  fdr_to_pst = fdr_to_pst_holder.data ();
  fdr_to_pst++;
  {
    legacy_psymtab *new_pst = new_psymtab ("", partial_symtabs, objfile);

    fdr_to_pst[-1].pst = new_pst;
    FDR_IDX (new_pst) = -1;
  }

  /* Allocate the global pending list.  */
  pending_list = XOBNEWVEC (&objfile->objfile_obstack, mdebug_pending *,
			    hdr->ifdMax);
  memset (pending_list, 0,
	  hdr->ifdMax * sizeof (struct mdebug_pending *));

  /* Pass 0 over external syms: swap them in.  */
  gdb::def_vector<EXTR> ext_block (hdr->iextMax);

  ext_out = (char *) debug_info->external_ext;
  ext_out_end = ext_out + hdr->iextMax * external_ext_size;
  ext_in = ext_block.data ();
  for (; ext_out < ext_out_end; ext_out += external_ext_size, ext_in++)
    (*swap_ext_in) (cur_bfd, ext_out, ext_in);

  /* Pass 1 over external syms: Presize and partition the list.  */
  ext_in = ext_block.data ();
  ext_in_end = ext_in + hdr->iextMax;
  for (; ext_in < ext_in_end; ext_in++)
    {
      /* See calls to complain below.  */
      if (ext_in->ifd >= -1
	  && ext_in->ifd < hdr->ifdMax
	  && ext_in->asym.iss >= 0
	  && ext_in->asym.iss < hdr->issExtMax)
	fdr_to_pst[ext_in->ifd].n_globals++;
    }

  /* Pass 1.5 over files:  partition out global symbol space.  */
  s_idx = 0;
  for (f_idx = -1; f_idx < hdr->ifdMax; f_idx++)
    {
      fdr_to_pst[f_idx].globals_offset = s_idx;
      s_idx += fdr_to_pst[f_idx].n_globals;
      fdr_to_pst[f_idx].n_globals = 0;
    }

  /* ECOFF in ELF:

     For ECOFF in ELF, we skip the creation of the minimal symbols.
     The ECOFF symbols should be a subset of the Elf symbols, and the 
     section information of the elf symbols will be more accurate.
     FIXME!  What about Irix 5's native linker?

     By default, Elf sections which don't exist in ECOFF 
     get put in ECOFF's absolute section by the gnu linker.
     Since absolute sections don't get relocated, we 
     end up calculating an address different from that of 
     the symbol's minimal symbol (created earlier from the
     Elf symtab).

     To fix this, either :
     1) don't create the duplicate symbol
     (assumes ECOFF symtab is a subset of the ELF symtab;
     assumes no side-effects result from ignoring ECOFF symbol)
     2) create it, only if lookup for existing symbol in ELF's minimal 
     symbols fails
     (inefficient; 
     assumes no side-effects result from ignoring ECOFF symbol)
     3) create it, but lookup ELF's minimal symbol and use it's section
     during relocation, then modify "uniquify" phase to merge and
     eliminate the duplicate symbol
     (highly inefficient)

     I've implemented #1 here...
     Skip the creation of the minimal symbols based on the ECOFF 
     symbol table.  */

  /* Pass 2 over external syms: fill in external symbols.  */
  ext_in = ext_block.data ();
  ext_in_end = ext_in + hdr->iextMax;
  for (; ext_in < ext_in_end; ext_in++)
    {
      enum minimal_symbol_type ms_type = mst_text;
      unrelocated_addr svalue = unrelocated_addr (ext_in->asym.value);

      /* The Irix 5 native tools seem to sometimes generate bogus
	 external symbols.  */
      if (ext_in->ifd < -1 || ext_in->ifd >= hdr->ifdMax)
	{
	  complaint (_("bad ifd for external symbol: %d (max %ld)"),
		     ext_in->ifd, hdr->ifdMax);
	  continue;
	}
      if (ext_in->asym.iss < 0 || ext_in->asym.iss >= hdr->issExtMax)
	{
	  complaint (_("bad iss for external symbol: %ld (max %ld)"),
		     ext_in->asym.iss, hdr->issExtMax);
	  continue;
	}

      extern_tab[fdr_to_pst[ext_in->ifd].globals_offset
		 + fdr_to_pst[ext_in->ifd].n_globals++] = *ext_in;


      if (SC_IS_UNDEF (ext_in->asym.sc) || ext_in->asym.sc == scNil)
	continue;


      /* Pass 3 over files, over local syms: fill in static symbols.  */
      name = debug_info->ssext + ext_in->asym.iss;

      /* Process ECOFF Symbol Types and Storage Classes.  */
      switch (ext_in->asym.st)
	{
	case stProc:
	  /* Beginnning of Procedure */
	  break;
	case stStaticProc:
	  /* Load time only static procs */
	  ms_type = mst_file_text;
	  break;
	case stGlobal:
	  /* External symbol */
	  if (SC_IS_COMMON (ext_in->asym.sc))
	    {
	      /* The value of a common symbol is its size, not its address.
		 Ignore it.  */
	      continue;
	    }
	  else if (SC_IS_DATA (ext_in->asym.sc))
	    {
	      ms_type = mst_data;
	    }
	  else if (SC_IS_BSS (ext_in->asym.sc))
	    {
	      ms_type = mst_bss;
	    }
	  else if (SC_IS_SBSS (ext_in->asym.sc))
	    {
	      ms_type = mst_bss;
	    }
	  else
	    ms_type = mst_abs;
	  break;
	case stLabel:
	  /* Label */

	  /* On certain platforms, some extra label symbols can be
	     generated by the linker.  One possible usage for this kind
	     of symbols is to represent the address of the begining of a
	     given section.  For instance, on Tru64 5.1, the address of
	     the _ftext label is the start address of the .text section.

	     The storage class of these symbols is usually directly
	     related to the section to which the symbol refers.  For
	     instance, on Tru64 5.1, the storage class for the _fdata
	     label is scData, refering to the .data section.

	     It is actually possible that the section associated to the
	     storage class of the label does not exist.  On True64 5.1
	     for instance, the libm.so shared library does not contain
	     any .data section, although it contains a _fpdata label
	     which storage class is scData...  Since these symbols are
	     usually useless for the debugger user anyway, we just
	     discard these symbols.  */
	  
	  if (SC_IS_TEXT (ext_in->asym.sc))
	    {
	      if (objfile->sect_index_text == -1)
		continue;
		
	      ms_type = mst_file_text;
	    }
	  else if (SC_IS_DATA (ext_in->asym.sc))
	    {
	      if (objfile->sect_index_data == -1)
		continue;

	      ms_type = mst_file_data;
	    }
	  else if (SC_IS_BSS (ext_in->asym.sc))
	    {
	      if (objfile->sect_index_bss == -1)
		continue;

	      ms_type = mst_file_bss;
	    }
	  else if (SC_IS_SBSS (ext_in->asym.sc))
	    {
	      const int sbss_sect_index = get_section_index (objfile, ".sbss");

	      if (sbss_sect_index == -1)
		continue;

	      ms_type = mst_file_bss;
	    }
	  else
	    ms_type = mst_abs;
	  break;
	case stLocal:
	case stNil:
	  /* The alpha has the section start addresses in stLocal symbols
	     whose name starts with a `.'.  Skip those but complain for all
	     other stLocal symbols.
	     Irix6 puts the section start addresses in stNil symbols, skip
	     those too.  */
	  if (name[0] == '.')
	    continue;
	  [[fallthrough]];
	default:
	  ms_type = mst_unknown;
	  unknown_ext_complaint (name);
	}
      if (!ECOFF_IN_ELF (cur_bfd))
	record_minimal_symbol (reader, name, svalue, ms_type, ext_in->asym.sc,
			       objfile);
    }

  /* Pass 3 over files, over local syms: fill in static symbols.  */
  for (f_idx = 0; f_idx < hdr->ifdMax; f_idx++)
    {
      legacy_psymtab *save_pst;
      EXTR *ext_ptr;
      unrelocated_addr textlow;

      cur_fdr = fh = debug_info->fdr + f_idx;

      if (fh->csym == 0)
	{
	  fdr_to_pst[f_idx].pst = NULL;
	  continue;
	}

      /* Determine the start address for this object file from the
	 file header and relocate it, except for Irix 5.2 zero fh->adr.  */
      if (fh->cpd)
	textlow = unrelocated_addr (fh->adr);
      else
	textlow = unrelocated_addr (0);
      pst = new legacy_psymtab (fdr_name (fh), partial_symtabs,
				objfile->per_bfd, textlow);
      pst->read_symtab_private = XOBNEW (&objfile->objfile_obstack, md_symloc);
      memset (pst->read_symtab_private, 0, sizeof (struct md_symloc));

      save_pst = pst;
      FDR_IDX (pst) = f_idx;
      CUR_BFD (pst) = cur_bfd;
      DEBUG_SWAP (pst) = debug_swap;
      DEBUG_INFO (pst) = debug_info;
      PENDING_LIST (pst) = pending_list;

      /* The way to turn this into a symtab is to call...  */
      pst->legacy_read_symtab = mdebug_read_symtab;
      pst->legacy_expand_psymtab = mdebug_expand_psymtab;

      /* Set up language for the pst.
	 The language from the FDR is used if it is unambiguous (e.g. cfront
	 with native cc and g++ will set the language to C).
	 Otherwise we have to deduce the language from the filename.
	 Native ecoff has every header file in a separate FDR, so
	 deduce_language_from_filename will return language_unknown for
	 a header file, which is not what we want.
	 But the FDRs for the header files are after the FDR for the source
	 file, so we can assign the language of the source file to the
	 following header files.  Then we save the language in the private
	 pst data so that we can reuse it when building symtabs.  */
      prev_language = psymtab_language;

      switch (fh->lang)
	{
	case langCplusplusV2:
	  psymtab_language = language_cplus;
	  break;
	default:
	  psymtab_language = deduce_language_from_filename (fdr_name (fh));
	  break;
	}
      if (psymtab_language == language_unknown)
	psymtab_language = prev_language;
      PST_PRIVATE (pst)->pst_language = psymtab_language;

      pst->set_text_high (pst->unrelocated_text_low ());

      /* For stabs-in-ecoff files, the second symbol must be @stab.
	 This symbol is emitted by mips-tfile to signal that the
	 current object file uses encapsulated stabs instead of mips
	 ecoff for local symbols.  (It is the second symbol because
	 the first symbol is the stFile used to signal the start of a
	 file).  */
      processing_gcc_compilation = 0;
      if (fh->csym >= 2)
	{
	  (*swap_sym_in) (cur_bfd,
			  ((char *) debug_info->external_sym
			   + (fh->isymBase + 1) * external_sym_size),
			  &sh);
	  if (strcmp (debug_info->ss + fh->issBase + sh.iss,
		      stabs_symbol) == 0)
	    processing_gcc_compilation = 2;
	}

      if (processing_gcc_compilation != 0)
	{
	  for (cur_sdx = 2; cur_sdx < fh->csym; cur_sdx++)
	    {
	      int type_code;
	      const char *namestring;

	      (*swap_sym_in) (cur_bfd,
			      (((char *) debug_info->external_sym)
			    + (fh->isymBase + cur_sdx) * external_sym_size),
			      &sh);
	      type_code = ECOFF_UNMARK_STAB (sh.index);
	      if (!ECOFF_IS_STAB (&sh))
		{
		  if (sh.st == stProc || sh.st == stStaticProc)
		    {
		      unrelocated_addr procaddr;
		      long isym;

		      if (sh.st == stStaticProc)
			{
			  namestring = debug_info->ss + fh->issBase + sh.iss;
			  record_minimal_symbol (reader, namestring,
						 unrelocated_addr (sh.value),
						 mst_file_text, sh.sc,
						 objfile);
			}
		      procaddr = unrelocated_addr (sh.value);

		      isym = AUX_GET_ISYM (fh->fBigendian,
					   (debug_info->external_aux
					    + fh->iauxBase
					    + sh.index));
		      (*swap_sym_in) (cur_bfd,
				      ((char *) debug_info->external_sym
				       + ((fh->isymBase + isym - 1)
					  * external_sym_size)),
				      &sh);
		      if (sh.st == stEnd)
			{
			  unrelocated_addr high
			    = unrelocated_addr (CORE_ADDR (procaddr)
						+ sh.value);

			  /* Kludge for Irix 5.2 zero fh->adr.  */
			  if (!relocatable
			      && (!pst->text_low_valid
				  || procaddr < pst->unrelocated_text_low ()))
			    pst->set_text_low (procaddr);
			  if (high > pst->unrelocated_text_high ())
			    pst->set_text_high (high);
			}
		    }
		  else if (sh.st == stStatic)
		    {
		      switch (sh.sc)
			{
			case scUndefined:
			case scSUndefined:
			case scNil:
			case scAbs:
			  break;

			case scData:
			case scSData:
			case scRData:
			case scPData:
			case scXData:
			  namestring = debug_info->ss + fh->issBase + sh.iss;
			  record_minimal_symbol (reader, namestring,
						 unrelocated_addr (sh.value),
						 mst_file_data, sh.sc,
						 objfile);
			  break;

			default:
			  /* FIXME!  Shouldn't this use cases for bss, 
			     then have the default be abs?  */
			  namestring = debug_info->ss + fh->issBase + sh.iss;
			  record_minimal_symbol (reader, namestring,
						 unrelocated_addr (sh.value),
						 mst_file_bss, sh.sc,
						 objfile);
			  break;
			}
		    }
		  continue;
		}
	      /* Handle stabs continuation.  */
	      {
		char *stabstring = debug_info->ss + fh->issBase + sh.iss;
		/* If we need to heap-allocate STABSTRING, this owns
		   it.  */
		gdb::unique_xmalloc_ptr<char> stabstring_storage;
		int len = strlen (stabstring);

		while (stabstring[len - 1] == '\\')
		  {
		    SYMR sh2;
		    char *stabstring1 = stabstring;
		    char *stabstring2;
		    int len2;

		    /* Ignore continuation char from 1st string.  */
		    len--;

		    /* Read next stabstring.  */
		    cur_sdx++;
		    (*swap_sym_in) (cur_bfd,
				    (((char *) debug_info->external_sym)
				     + (fh->isymBase + cur_sdx)
				     * external_sym_size),
				    &sh2);
		    stabstring2 = debug_info->ss + fh->issBase + sh2.iss;
		    len2 = strlen (stabstring2);

		    /* Concatenate stabstring2 with stabstring1.  */
		    if (stabstring_storage != nullptr)
		      {
			stabstring_storage.reset
			  ((char *) xrealloc (stabstring_storage.release (),
					      len + len2 + 1));
			stabstring = stabstring_storage.get ();
		      }
		    else
		      {
			stabstring_storage.reset
			  ((char *) xmalloc (len + len2 + 1));
			stabstring = stabstring_storage.get ();
			strcpy (stabstring, stabstring1);
		      }
		    strcpy (stabstring + len, stabstring2);
		    len += len2;
		  }

		switch (type_code)
		  {
		    const char *p;

		    /* Standard, external, non-debugger, symbols.  */

		  case N_TEXT | N_EXT:
		  case N_NBTEXT | N_EXT:
		    goto record_it;

		  case N_DATA | N_EXT:
		  case N_NBDATA | N_EXT:
		    goto record_it;

		  case N_BSS:
		  case N_BSS | N_EXT:
		  case N_NBBSS | N_EXT:
		  case N_SETV | N_EXT:		/* FIXME, is this in BSS?  */
		    goto record_it;

		  case N_ABS | N_EXT:
		  record_it:
		    continue;

		  /* Standard, local, non-debugger, symbols.  */

		  case N_NBTEXT:

		    /* We need to be able to deal with both N_FN or
		       N_TEXT, because we have no way of knowing
		       whether the sys-supplied ld or GNU ld was used
		       to make the executable.  Sequents throw in
		       another wrinkle -- they renumbered N_FN.  */

		  case N_FN:
		  case N_FN_SEQ:
		  case N_TEXT:
		    continue;

		  case N_DATA:
		    goto record_it;

		  case N_UNDF | N_EXT:
		    continue;		/* Just undefined, not COMMON.  */

		  case N_UNDF:
		    continue;

		    /* Lots of symbol types we can just ignore.  */

		  case N_ABS:
		  case N_NBDATA:
		  case N_NBBSS:
		    continue;

		    /* Keep going . . .  */

		    /*
		     * Special symbol types for GNU
		     */
		  case N_INDR:
		  case N_INDR | N_EXT:
		  case N_SETA:
		  case N_SETA | N_EXT:
		  case N_SETT:
		  case N_SETT | N_EXT:
		  case N_SETD:
		  case N_SETD | N_EXT:
		  case N_SETB:
		  case N_SETB | N_EXT:
		  case N_SETV:
		    continue;

		    /*
		     * Debugger symbols
		     */

		  case N_SO:
		    {
		      static int prev_so_symnum = -10;
		      const char *basename;

		      /* A zero value is probably an indication for the
			 SunPRO 3.0 compiler.  dbx_end_psymtab explicitly tests
			 for zero, so don't relocate it.  */

		      if (sh.value == 0
			  && gdbarch_sofun_address_maybe_missing (gdbarch))
			textlow_not_set = 1;
		      else
			textlow_not_set = 0;

		      if (prev_so_symnum != symnum - 1)
			{		/* Here if prev stab wasn't N_SO.  */
			  if (pst)
			    {
			      pst = (legacy_psymtab *) 0;
			      includes_used = 0;
			      dependencies_used = 0;
			    }
			}

		      prev_so_symnum = symnum;

		      /* End the current partial symtab and start a
			 new one.  */

		      /* SET_NAMESTRING ();*/
		      namestring = stabstring;

		      /* Null name means end of .o file.  Don't start a new
			 one.  */
		      if (*namestring == '\000')
			continue;

		      /* Some compilers (including gcc) emit a pair of
			 initial N_SOs.  The first one is a directory name;
			 the second the file name.  If pst exists, is
			 empty, and has a filename ending in '/', we assume
			 the previous N_SO was a directory name.  */
		      basename = lbasename (namestring);
		      if (basename != namestring && *basename == '\000')
			continue;		/* Simply ignore directory
						   name SOs.  */

		      /* Some other compilers (C++ ones in particular) emit
			 useless SOs for non-existant .c files.  We ignore
			 all subsequent SOs that immediately follow the
			 first.  */

		      if (!pst)
			pst = save_pst;
		      continue;
		    }

		  case N_BINCL:
		    continue;

		  case N_SOL:
		    {
		      enum language tmp_language;

		      /* Mark down an include file in the current psymtab.  */

		      /* SET_NAMESTRING (); */
		      namestring = stabstring;

		      tmp_language
			= deduce_language_from_filename (namestring);

		      /* Only change the psymtab's language if we've
			 learned something useful (eg. tmp_language is not
			 language_unknown).  In addition, to match what
			 start_subfile does, never change from C++ to
			 C.  */
		      if (tmp_language != language_unknown
			  && (tmp_language != language_c
			      || psymtab_language != language_cplus))
			psymtab_language = tmp_language;

		      /* In C++, one may expect the same filename to come
			 round many times, when code is coming alternately
			 from the main file and from inline functions in
			 other files.  So I check to see if this is a file
			 we've seen before -- either the main source file,
			 or a previously included file.

			 This seems to be a lot of time to be spending on
			 N_SOL, but things like "break c-exp.y:435" need to
			 work (I suppose the psymtab_include_list could be
			 hashed or put in a binary tree, if profiling shows
			 this is a major hog).  */
		      if (pst && filename_cmp (namestring, pst->filename) == 0)
			continue;

		      {
			int i;

			for (i = 0; i < includes_used; i++)
			  if (filename_cmp (namestring,
					    psymtab_include_list[i]) == 0)
			    {
			      i = -1;
			      break;
			    }
			if (i == -1)
			  continue;
		      }

		      psymtab_include_list[includes_used++] = namestring;
		      if (includes_used >= includes_allocated)
			{
			  const char **orig = psymtab_include_list;

			  psymtab_include_list = (const char **)
			    alloca ((includes_allocated *= 2) *
				    sizeof (const char *));
			  memcpy (psymtab_include_list, orig,
				  includes_used * sizeof (const char *));
			}
		      continue;
		    }
		  case N_LSYM:	    /* Typedef or automatic variable.  */
		  case N_STSYM:	    /* Data seg var -- static  */
		  case N_LCSYM:	    /* BSS      "  */
		  case N_ROSYM:	    /* Read-only data seg var -- static.  */
		  case N_NBSTS:	    /* Gould nobase.  */
		  case N_NBLCS:	    /* symbols.  */
		  case N_FUN:
		  case N_GSYM:	    /* Global (extern) variable; can be
				       data or bss (sigh FIXME).  */

		    /* Following may probably be ignored; I'll leave them here
		       for now (until I do Pascal and Modula 2 extensions).  */

		  case N_PC:	    /* I may or may not need this; I
				       suspect not.  */
		  case N_M2C:	    /* I suspect that I can ignore this
				       here.  */
		  case N_SCOPE:	    /* Same.  */

		    /*    SET_NAMESTRING (); */
		    namestring = stabstring;
		    p = (char *) strchr (namestring, ':');
		    if (!p)
		      continue;	    /* Not a debugging symbol.  */



		    /* Main processing section for debugging symbols which
		       the initial read through the symbol tables needs to
		       worry about.  If we reach this point, the symbol
		       which we are considering is definitely one we are
		       interested in.  p must also contain the (valid)
		       index into the namestring which indicates the
		       debugging type symbol.  */

		    switch (p[1])
		      {
		      case 'S':
			pst->add_psymbol (std::string_view (namestring,
							    p - namestring),
					  true, VAR_DOMAIN, LOC_STATIC,
					  SECT_OFF_DATA (objfile),
					  psymbol_placement::STATIC,
					  unrelocated_addr (sh.value),
					  psymtab_language,
					  partial_symtabs, objfile);
			continue;
		      case 'G':
			/* The addresses in these entries are reported
			   to be wrong.  See the code that reads 'G's
			   for symtabs.  */
			pst->add_psymbol (std::string_view (namestring,
							    p - namestring),
					  true, VAR_DOMAIN, LOC_STATIC,
					  SECT_OFF_DATA (objfile),
					  psymbol_placement::GLOBAL,
					  unrelocated_addr (sh.value),
					  psymtab_language,
					  partial_symtabs, objfile);
			continue;

		      case 'T':
			/* When a 'T' entry is defining an anonymous enum, it
			   may have a name which is the empty string, or a
			   single space.  Since they're not really defining a
			   symbol, those shouldn't go in the partial symbol
			   table.  We do pick up the elements of such enums at
			   'check_enum:', below.  */
			if (p >= namestring + 2
			    || (p == namestring + 1
				&& namestring[0] != ' '))
			  {
			    pst->add_psymbol
			      (std::string_view (namestring, p - namestring),
			       true, STRUCT_DOMAIN, LOC_TYPEDEF, -1,
			       psymbol_placement::STATIC,
			       unrelocated_addr (0),
			       psymtab_language,
			       partial_symtabs, objfile);
			    if (p[2] == 't')
			      {
				/* Also a typedef with the same name.  */
				pst->add_psymbol
				  (std::string_view (namestring,
						     p - namestring),
				   true, VAR_DOMAIN, LOC_TYPEDEF, -1,
				   psymbol_placement::STATIC,
				   unrelocated_addr (0),
				   psymtab_language,
				   partial_symtabs, objfile);
				p += 1;
			      }
			  }
			goto check_enum;
		      case 't':
			if (p != namestring)	/* a name is there, not
						   just :T...  */
			  {
			    pst->add_psymbol
			      (std::string_view (namestring,
						 p - namestring),
			       true, VAR_DOMAIN, LOC_TYPEDEF, -1,
			       psymbol_placement::STATIC,
			       unrelocated_addr (0),
			       psymtab_language,
			       partial_symtabs, objfile);
			  }
		      check_enum:
			/* If this is an enumerated type, we need to add
			   all the enum constants to the partial symbol
			   table.  This does not cover enums without names,
			   e.g. "enum {a, b} c;" in C, but fortunately
			   those are rare.  There is no way for GDB to find
			   those from the enum type without spending too
			   much time on it.  Thus to solve this problem,
			   the compiler needs to put out the enum in a
			   nameless type.  GCC2 does this.  */

			/* We are looking for something of the form
			   <name> ":" ("t" | "T") [<number> "="] "e"
			   {<constant> ":" <value> ","} ";".  */

			/* Skip over the colon and the 't' or 'T'.  */
			p += 2;
			/* This type may be given a number.  Also, numbers
			   can come in pairs like (0,26).  Skip over it.  */
			while ((*p >= '0' && *p <= '9')
			       || *p == '(' || *p == ',' || *p == ')'
			       || *p == '=')
			  p++;

			if (*p++ == 'e')
			  {
			    /* The aix4 compiler emits extra crud before
			       the members.  */
			    if (*p == '-')
			      {
				/* Skip over the type (?).  */
				while (*p != ':')
				  p++;

				/* Skip over the colon.  */
				p++;
			      }

			    /* We have found an enumerated type.  */
			    /* According to comments in read_enum_type
			       a comma could end it instead of a semicolon.
			       I don't know where that happens.
			       Accept either.  */
			    while (*p && *p != ';' && *p != ',')
			      {
				const char *q;

				/* Check for and handle cretinous dbx
				   symbol name continuation!  */
				if (*p == '\\' || (*p == '?' && p[1] == '\0'))
				  p = next_symbol_text (objfile);

				/* Point to the character after the name
				   of the enum constant.  */
				for (q = p; *q && *q != ':'; q++)
				  ;
				/* Note that the value doesn't matter for
				   enum constants in psymtabs, just in
				   symtabs.  */
				pst->add_psymbol (std::string_view (p,
								    q - p),
						  true, VAR_DOMAIN,
						  LOC_CONST, -1,
						  psymbol_placement::STATIC,
						  unrelocated_addr (0),
						  psymtab_language,
						  partial_symtabs, objfile);
				/* Point past the name.  */
				p = q;
				/* Skip over the value.  */
				while (*p && *p != ',')
				  p++;
				/* Advance past the comma.  */
				if (*p)
				  p++;
			      }
			  }
			continue;
		      case 'c':
			/* Constant, e.g. from "const" in Pascal.  */
			pst->add_psymbol (std::string_view (namestring,
							    p - namestring),
					  true, VAR_DOMAIN, LOC_CONST, -1,
					  psymbol_placement::STATIC,
					  unrelocated_addr (0),
					  psymtab_language,
					  partial_symtabs, objfile);
			continue;

		      case 'f':
			if (! pst)
			  {
			    std::string copy (namestring, p);
			    function_outside_compilation_unit_complaint
			      (copy.c_str ());
			  }
			pst->add_psymbol (std::string_view (namestring,
							    p - namestring),
					  true, VAR_DOMAIN, LOC_BLOCK,
					  SECT_OFF_TEXT (objfile),
					  psymbol_placement::STATIC,
					  unrelocated_addr (sh.value),
					  psymtab_language,
					  partial_symtabs, objfile);
			continue;

			/* Global functions were ignored here, but now they
			   are put into the global psymtab like one would
			   expect.  They're also in the minimal symbol
			   table.  */
		      case 'F':
			if (! pst)
			  {
			    std::string copy (namestring, p);
			    function_outside_compilation_unit_complaint
			      (copy.c_str ());
			  }
			pst->add_psymbol (std::string_view (namestring,
							    p - namestring),
					  true, VAR_DOMAIN, LOC_BLOCK,
					  SECT_OFF_TEXT (objfile),
					  psymbol_placement::GLOBAL,
					  unrelocated_addr (sh.value),
					  psymtab_language,
					  partial_symtabs, objfile);
			continue;

			/* Two things show up here (hopefully); static
			   symbols of local scope (static used inside
			   braces) or extensions of structure symbols.  We
			   can ignore both.  */
		      case 'V':
		      case '(':
		      case '0':
		      case '1':
		      case '2':
		      case '3':
		      case '4':
		      case '5':
		      case '6':
		      case '7':
		      case '8':
		      case '9':
		      case '-':
		      case '#':		/* For symbol identification (used
					   in live ranges).  */
			continue;

		      case ':':
			/* It is a C++ nested symbol.  We don't need to
			   record it (I don't think); if we try to look up
			   foo::bar::baz, then symbols for the symtab
			   containing foo should get read in, I think.  */
			/* Someone says sun cc puts out symbols like
			   /foo/baz/maclib::/usr/local/bin/maclib,
			   which would get here with a symbol type of ':'.  */
			continue;

		      default:
			/* Unexpected symbol descriptor.  The second and
			   subsequent stabs of a continued stab can show up
			   here.  The question is whether they ever can
			   mimic a normal stab--it would be nice if not,
			   since we certainly don't want to spend the time
			   searching to the end of every string looking for
			   a backslash.  */

			complaint (_("unknown symbol descriptor `%c'"), p[1]);

			/* Ignore it; perhaps it is an extension that we don't
			   know about.  */
			continue;
		      }

		  case N_EXCL:
		    continue;

		  case N_ENDM:
		    /* Solaris 2 end of module, finish current partial
		       symbol table.  dbx_end_psymtab will set the
		       high text address of PST to the proper value,
		       which is necessary if a module compiled without
		       debugging info follows this module.  */
		    if (pst
			&& gdbarch_sofun_address_maybe_missing (gdbarch))
		      {
			pst = (legacy_psymtab *) 0;
			includes_used = 0;
			dependencies_used = 0;
		      }
		    continue;

		  case N_RBRAC:
		    {
		      unrelocated_addr unrel_value
			= unrelocated_addr (sh.value);
		      if (unrel_value > save_pst->unrelocated_text_high ())
			save_pst->set_text_high (unrel_value);
		    }
		    continue;
		  case N_EINCL:
		  case N_DSLINE:
		  case N_BSLINE:
		  case N_SSYM:		/* Claim: Structure or union
					   element.  Hopefully, I can
					   ignore this.  */
		  case N_ENTRY:		/* Alternate entry point; can
					   ignore.  */
		  case N_MAIN:		/* Can definitely ignore this.   */
		  case N_CATCH:		/* These are GNU C++ extensions.  */
		  case N_EHDECL:	/* that can safely be ignored here.  */
		  case N_LENG:
		  case N_BCOMM:
		  case N_ECOMM:
		  case N_ECOML:
		  case N_FNAME:
		  case N_SLINE:
		  case N_RSYM:
		  case N_PSYM:
		  case N_LBRAC:
		  case N_NSYMS:		/* Ultrix 4.0: symbol count */
		  case N_DEFD:			/* GNU Modula-2 */
		  case N_ALIAS:		/* SunPro F77: alias name, ignore
					   for now.  */

		  case N_OBJ:		/* Useless types from Solaris.  */
		  case N_OPT:
		    /* These symbols aren't interesting; don't worry about
		       them.  */

		    continue;

		  default:
		    /* If we haven't found it yet, ignore it.  It's
		       probably some new type we don't know about yet.  */
		    complaint (_("unknown symbol type %s"),
			       hex_string (type_code)); /* CUR_SYMBOL_TYPE */
		    continue;
		  }
	      }
	      /* end - Handle continuation */
	    }
	}
      else
	{
	  for (cur_sdx = 0; cur_sdx < fh->csym;)
	    {
	      char *sym_name;
	      enum address_class theclass;
	      unrelocated_addr minsym_value;
	      short section = -1;

	      (*swap_sym_in) (cur_bfd,
			      ((char *) debug_info->external_sym
			       + ((fh->isymBase + cur_sdx)
				  * external_sym_size)),
			      &sh);

	      if (ECOFF_IS_STAB (&sh))
		{
		  cur_sdx++;
		  continue;
		}

	      /* Non absolute static symbols go into the minimal table.  */
	      if (SC_IS_UNDEF (sh.sc) || sh.sc == scNil
		  || (sh.index == indexNil
		      && (sh.st != stStatic || sh.sc == scAbs)))
		{
		  /* FIXME, premature?  */
		  cur_sdx++;
		  continue;
		}

	      sym_name = debug_info->ss + fh->issBase + sh.iss;

	      minsym_value = unrelocated_addr (sh.value);

	      switch (sh.sc)
		{
		case scText:
		case scRConst:
		  /* The value of a stEnd symbol is the displacement from the
		     corresponding start symbol value, do not relocate it.  */
		  if (sh.st != stEnd)
		    section = SECT_OFF_TEXT (objfile);
		  break;
		case scData:
		case scSData:
		case scRData:
		case scPData:
		case scXData:
		  section = SECT_OFF_DATA (objfile);
		  break;
		case scBss:
		case scSBss:
		  section = SECT_OFF_BSS (objfile);
		  break;
		}

	      switch (sh.st)
		{
		  unrelocated_addr high;
		  unrelocated_addr procaddr;
		  int new_sdx;

		case stStaticProc:
		  reader.record_with_info (sym_name, minsym_value,
					   mst_file_text,
					   SECT_OFF_TEXT (objfile));

		  [[fallthrough]];

		case stProc:
		  /* Ignore all parameter symbol records.  */
		  if (sh.index >= hdr->iauxMax)
		    {
		      /* Should not happen, but does when cross-compiling
			 with the MIPS compiler.  FIXME -- pull later.  */
		      index_complaint (sym_name);
		      new_sdx = cur_sdx + 1;	/* Don't skip at all.  */
		    }
		  else
		    new_sdx = AUX_GET_ISYM (fh->fBigendian,
					    (debug_info->external_aux
					     + fh->iauxBase
					     + sh.index));

		  if (new_sdx <= cur_sdx)
		    {
		      /* This should not happen either... FIXME.  */
		      complaint (_("bad proc end in aux found from symbol %s"),
				 sym_name);
		      new_sdx = cur_sdx + 1;	/* Don't skip backward.  */
		    }

		  /* For stProc symbol records, we need to check the
		     storage class as well, as only (stProc, scText)
		     entries represent "real" procedures - See the
		     Compaq document titled "Object File / Symbol Table
		     Format Specification" for more information.  If the
		     storage class is not scText, we discard the whole
		     block of symbol records for this stProc.  */
		  if (sh.st == stProc && sh.sc != scText)
		    goto skip;

		  /* Usually there is a local and a global stProc symbol
		     for a function.  This means that the function name
		     has already been entered into the minimal symbol table
		     while processing the global symbols in pass 2 above.
		     One notable exception is the PROGRAM name from
		     f77 compiled executables, it is only put out as
		     local stProc symbol, and a global MAIN__ stProc symbol
		     points to it.  It doesn't matter though, as gdb is
		     still able to find the PROGRAM name via the partial
		     symbol table, and the MAIN__ symbol via the minimal
		     symbol table.  */
		  if (sh.st == stProc)
		    pst->add_psymbol (sym_name, true,
				      VAR_DOMAIN, LOC_BLOCK,
				      section,
				      psymbol_placement::GLOBAL,
				      unrelocated_addr (sh.value),
				      psymtab_language,
				      partial_symtabs, objfile);
		  else
		    pst->add_psymbol (sym_name, true,
				      VAR_DOMAIN, LOC_BLOCK,
				      section,
				      psymbol_placement::STATIC,
				      unrelocated_addr (sh.value),
				      psymtab_language,
				      partial_symtabs, objfile);

		  procaddr = unrelocated_addr (sh.value);

		  cur_sdx = new_sdx;
		  (*swap_sym_in) (cur_bfd,
				  ((char *) debug_info->external_sym
				   + ((fh->isymBase + cur_sdx - 1)
				      * external_sym_size)),
				  &sh);
		  if (sh.st != stEnd)
		    continue;

		  /* Kludge for Irix 5.2 zero fh->adr.  */
		  if (!relocatable
		      && (!pst->text_low_valid
			  || procaddr < pst->unrelocated_text_low ()))
		    pst->set_text_low (procaddr);

		  high = unrelocated_addr (CORE_ADDR (procaddr) + sh.value);
		  if (high > pst->unrelocated_text_high ())
		    pst->set_text_high (high);
		  continue;

		case stStatic:	/* Variable */
		  if (SC_IS_DATA (sh.sc))
		    reader.record_with_info (sym_name, minsym_value,
					     mst_file_data,
					     SECT_OFF_DATA (objfile));
		  else
		    reader.record_with_info (sym_name, minsym_value,
					     mst_file_bss,
					     SECT_OFF_BSS (objfile));
		  theclass = LOC_STATIC;
		  break;

		case stIndirect:	/* Irix5 forward declaration */
		  /* Skip forward declarations from Irix5 cc.  */
		  goto skip;

		case stTypedef:	/* Typedef */
		  /* Skip typedefs for forward declarations and opaque
		     structs from alpha and mips cc.  */
		  if (sh.iss == 0 || has_opaque_xref (fh, &sh))
		    goto skip;
		  theclass = LOC_TYPEDEF;
		  break;

		case stConstant:	/* Constant decl */
		  theclass = LOC_CONST;
		  break;

		case stUnion:
		case stStruct:
		case stEnum:
		case stBlock:	/* { }, str, un, enum */
		  /* Do not create a partial symbol for cc unnamed aggregates
		     and gcc empty aggregates.  */
		  if ((sh.sc == scInfo
		       || SC_IS_COMMON (sh.sc))
		      && sh.iss != 0
		      && sh.index != cur_sdx + 2)
		    {
		      pst->add_psymbol (sym_name, true,
					STRUCT_DOMAIN, LOC_TYPEDEF, -1,
					psymbol_placement::STATIC,
					unrelocated_addr (0),
					psymtab_language,
					partial_symtabs, objfile);
		    }
		  handle_psymbol_enumerators (objfile, partial_symtabs,
					      pst, fh, sh.st, sh.value);

		  /* Skip over the block.  */
		  new_sdx = sh.index;
		  if (new_sdx <= cur_sdx)
		    {
		      /* This happens with the Ultrix kernel.  */
		      complaint (_("bad aux index at block symbol %s"),
				 sym_name);
		      new_sdx = cur_sdx + 1;	/* Don't skip backward.  */
		    }
		  cur_sdx = new_sdx;
		  continue;

		case stFile:	/* File headers */
		case stLabel:	/* Labels */
		case stEnd:	/* Ends of files */
		  goto skip;

		case stLocal:	/* Local variables */
		  /* Normally these are skipped because we skip over
		     all blocks we see.  However, these can occur
		     as visible symbols in a .h file that contains code.  */
		  goto skip;

		default:
		  /* Both complaints are valid:  one gives symbol sym_name,
		     the other the offending symbol type.  */
		  complaint (_("unknown local symbol %s"),
			     sym_name);
		  complaint (_("with type %d"), sh.st);
		  cur_sdx++;
		  continue;
		}
	      /* Use this gdb symbol.  */
	      pst->add_psymbol (sym_name, true,
				VAR_DOMAIN, theclass, section,
				psymbol_placement::STATIC,
				unrelocated_addr (sh.value),
				psymtab_language,
				partial_symtabs, objfile);
	    skip:
	      cur_sdx++;	/* Go to next file symbol.  */
	    }

	  /* Now do enter the external symbols.  */
	  ext_ptr = &extern_tab[fdr_to_pst[f_idx].globals_offset];
	  cur_sdx = fdr_to_pst[f_idx].n_globals;
	  PST_PRIVATE (save_pst)->extern_count = cur_sdx;
	  PST_PRIVATE (save_pst)->extern_tab = ext_ptr;
	  for (; --cur_sdx >= 0; ext_ptr++)
	    {
	      enum address_class theclass;
	      SYMR *psh;
	      CORE_ADDR svalue;
	      short section;

	      gdb_assert (ext_ptr->ifd == f_idx);

	      psh = &ext_ptr->asym;

	      /* Do not add undefined symbols to the partial symbol table.  */
	      if (SC_IS_UNDEF (psh->sc) || psh->sc == scNil)
		continue;

	      svalue = psh->value;
	      switch (psh->sc)
		{
		default:
		case scText:
		case scRConst:
		  section = SECT_OFF_TEXT (objfile);
		  break;
		case scData:
		case scSData:
		case scRData:
		case scPData:
		case scXData:
		  section = SECT_OFF_DATA (objfile);
		  break;
		case scBss:
		case scSBss:
		  section = SECT_OFF_BSS (objfile);
		  break;
		}

	      switch (psh->st)
		{
		case stNil:
		  /* These are generated for static symbols in .o files,
		     ignore them.  */
		  continue;
		case stProc:
		case stStaticProc:
		  /* External procedure symbols have been entered
		     into the minimal symbol table in pass 2 above.
		     Ignore them, as parse_external will ignore them too.  */
		  continue;
		case stLabel:
		  theclass = LOC_LABEL;
		  break;
		default:
		  unknown_ext_complaint (debug_info->ssext + psh->iss);
		  /* Pretend it's global.  */
		  [[fallthrough]];
		case stGlobal:
		  /* Global common symbols are resolved by the runtime loader,
		     ignore them.  */
		  if (SC_IS_COMMON (psh->sc))
		    continue;

		  theclass = LOC_STATIC;
		  break;
		}
	      char *sym_name = debug_info->ssext + psh->iss;
	      pst->add_psymbol (sym_name, true,
				VAR_DOMAIN, theclass,
				section,
				psymbol_placement::GLOBAL,
				unrelocated_addr (svalue),
				psymtab_language,
				partial_symtabs, objfile);
	    }
	}

      /* Link pst to FDR.  dbx_end_psymtab returns NULL if the psymtab was
	 empty and put on the free list.  */
      fdr_to_pst[f_idx].pst
	= dbx_end_psymtab (objfile, partial_symtabs, save_pst,
			   psymtab_include_list, includes_used,
			   -1, save_pst->unrelocated_text_high (),
			   dependency_list, dependencies_used,
			   textlow_not_set);
      includes_used = 0;
      dependencies_used = 0;
    }

  /* Now scan the FDRs for dependencies.  */
  for (f_idx = 0; f_idx < hdr->ifdMax; f_idx++)
    {
      fh = f_idx + debug_info->fdr;
      pst = fdr_to_pst[f_idx].pst;

      if (pst == NULL)
	continue;

      /* This should catch stabs-in-ecoff.  */
      if (fh->crfd <= 1)
	continue;

      /* Skip the first file indirect entry as it is a self dependency for
	 source files or a reverse .h -> .c dependency for header files.  */
      pst->number_of_dependencies = 0;
      pst->dependencies
	= partial_symtabs->allocate_dependencies (fh->crfd - 1);
      for (s_idx = 1; s_idx < fh->crfd; s_idx++)
	{
	  RFDT rh;

	  (*swap_rfd_in) (cur_bfd,
			  ((char *) debug_info->external_rfd
			   + (fh->rfdBase + s_idx) * external_rfd_size),
			  &rh);
	  if (rh < 0 || rh >= hdr->ifdMax)
	    {
	      complaint (_("bad file number %ld"), rh);
	      continue;
	    }

	  /* Skip self dependencies of header files.  */
	  if (rh == f_idx)
	    continue;

	  /* Do not add to dependency list if psymtab was empty.  */
	  if (fdr_to_pst[rh].pst == NULL)
	    continue;
	  pst->dependencies[pst->number_of_dependencies++]
	    = fdr_to_pst[rh].pst;
	}
    }

  /* Remove the dummy psymtab created for -O3 images above, if it is
     still empty, to enable the detection of stripped executables.  */
  partial_symtab *pst_del = partial_symtabs->psymtabs;
  if (pst_del->next == NULL
      && pst_del->number_of_dependencies == 0
      && pst_del->empty ())
    partial_symtabs->discard_psymtab (pst_del);
}

/* If the current psymbol has an enumerated type, we need to add
   all the enum constants to the partial symbol table.  */

static void
handle_psymbol_enumerators (struct objfile *objfile,
			    psymtab_storage *partial_symtabs,
			    partial_symtab *pst,
			    FDR *fh, int stype, CORE_ADDR svalue)
{
  const bfd_size_type external_sym_size = debug_swap->external_sym_size;
  void (*const swap_sym_in) (bfd *, void *, SYMR *) = debug_swap->swap_sym_in;
  char *ext_sym = ((char *) debug_info->external_sym
		   + ((fh->isymBase + cur_sdx + 1) * external_sym_size));
  SYMR sh;
  TIR tir;

  switch (stype)
    {
    case stEnum:
      break;

    case stBlock:
      /* It is an enumerated type if the next symbol entry is a stMember
	 and its auxiliary index is indexNil or its auxiliary entry
	 is a plain btNil or btVoid.
	 Alpha cc -migrate enums are recognized by a zero index and
	 a zero symbol value.
	 DU 4.0 cc enums are recognized by a member type of btEnum without
	 qualifiers and a zero symbol value.  */
      (*swap_sym_in) (cur_bfd, ext_sym, &sh);
      if (sh.st != stMember)
	return;

      if (sh.index == indexNil
	  || (sh.index == 0 && svalue == 0))
	break;
      (*debug_swap->swap_tir_in) (fh->fBigendian,
				  &(debug_info->external_aux
				    + fh->iauxBase + sh.index)->a_ti,
				  &tir);
      if ((tir.bt != btNil
	   && tir.bt != btVoid
	   && (tir.bt != btEnum || svalue != 0))
	  || tir.tq0 != tqNil)
	return;
      break;

    default:
      return;
    }

  for (;;)
    {
      char *name;

      (*swap_sym_in) (cur_bfd, ext_sym, &sh);
      if (sh.st != stMember)
	break;
      name = debug_info->ss + cur_fdr->issBase + sh.iss;

      /* Note that the value doesn't matter for enum constants
	 in psymtabs, just in symtabs.  */
      pst->add_psymbol (name, true,
			VAR_DOMAIN, LOC_CONST, -1,
			psymbol_placement::STATIC,
			unrelocated_addr (0),
			psymtab_language, partial_symtabs, objfile);
      ext_sym += external_sym_size;
    }
}

/* Get the next symbol.  OBJFILE is unused.  */

static const char *
mdebug_next_symbol_text (struct objfile *objfile)
{
  SYMR sh;

  cur_sdx++;
  (*debug_swap->swap_sym_in) (cur_bfd,
			      ((char *) debug_info->external_sym
			       + ((cur_fdr->isymBase + cur_sdx)
				  * debug_swap->external_sym_size)),
			      &sh);
  return debug_info->ss + cur_fdr->issBase + sh.iss;
}

/* Ancillary function to psymtab_to_symtab().  Does all the work
   for turning the partial symtab PST into a symtab, recurring
   first on all dependent psymtabs.  The argument FILENAME is
   only passed so we can see in debug stack traces what file
   is being read.

   This function has a split personality, based on whether the
   symbol table contains ordinary ecoff symbols, or stabs-in-ecoff.
   The flow of control and even the memory allocation differs.  FIXME.  */

static void
mdebug_expand_psymtab (legacy_psymtab *pst, struct objfile *objfile)
{
  bfd_size_type external_sym_size;
  bfd_size_type external_pdr_size;
  void (*swap_sym_in) (bfd *, void *, SYMR *);
  void (*swap_pdr_in) (bfd *, void *, PDR *);
  int i;
  struct compunit_symtab *cust = NULL;
  FDR *fh;
  struct linetable *lines;
  CORE_ADDR lowest_pdr_addr = 0;
  int last_symtab_ended = 0;
  const section_offsets &section_offsets = objfile->section_offsets;

  if (pst->readin)
    return;
  pst->readin = true;

  /* Read in all partial symtabs on which this one is dependent.
     NOTE that we do have circular dependencies, sigh.  We solved
     that by setting pst->readin before this point.  */
  pst->expand_dependencies (objfile);

  /* Do nothing if this is a dummy psymtab.  */

  if (pst->empty () && !pst->text_low_valid && !pst->text_high_valid)
    return;

  /* Now read the symbols for this symtab.  */

  cur_bfd = CUR_BFD (pst);
  debug_swap = DEBUG_SWAP (pst);
  debug_info = DEBUG_INFO (pst);
  pending_list = PENDING_LIST (pst);
  external_sym_size = debug_swap->external_sym_size;
  external_pdr_size = debug_swap->external_pdr_size;
  swap_sym_in = debug_swap->swap_sym_in;
  swap_pdr_in = debug_swap->swap_pdr_in;
  mdebugread_objfile = objfile;
  cur_fd = FDR_IDX (pst);
  fh = ((cur_fd == -1)
	? NULL
	: debug_info->fdr + cur_fd);
  cur_fdr = fh;

  /* See comment in parse_partial_symbols about the @stabs sentinel.  */
  processing_gcc_compilation = 0;
  if (fh != NULL && fh->csym >= 2)
    {
      SYMR sh;

      (*swap_sym_in) (cur_bfd,
		      ((char *) debug_info->external_sym
		       + (fh->isymBase + 1) * external_sym_size),
		      &sh);
      if (strcmp (debug_info->ss + fh->issBase + sh.iss,
		  stabs_symbol) == 0)
	{
	  /* We indicate that this is a GCC compilation so that certain
	     features will be enabled in stabsread/dbxread.  */
	  processing_gcc_compilation = 2;
	}
    }

  if (processing_gcc_compilation != 0)
    {
      struct gdbarch *gdbarch = objfile->arch ();

      /* This symbol table contains stabs-in-ecoff entries.  */

      /* Parse local symbols first.  */

      if (fh->csym <= 2)	/* FIXME, this blows psymtab->symtab ptr.  */
	{
	  mdebugread_objfile = NULL;
	  return;
	}
      for (cur_sdx = 2; cur_sdx < fh->csym; cur_sdx++)
	{
	  SYMR sh;
	  char *name;
	  CORE_ADDR valu;

	  (*swap_sym_in) (cur_bfd,
			  (((char *) debug_info->external_sym)
			   + (fh->isymBase + cur_sdx) * external_sym_size),
			  &sh);
	  name = debug_info->ss + fh->issBase + sh.iss;
	  valu = sh.value;
	  /* XXX This is a hack.  It will go away!  */
	  if (ECOFF_IS_STAB (&sh) || (name[0] == '#'))
	    {
	      int type_code = ECOFF_UNMARK_STAB (sh.index);
	      enum language language = PST_PRIVATE (pst)->pst_language;

	      /* We should never get non N_STAB symbols here, but they
		 should be harmless, so keep process_one_symbol from
		 complaining about them.  */
	      if (type_code & N_STAB)
		{
		  /* If we found a trailing N_SO with no name, process
		     it here instead of in process_one_symbol, so we
		     can keep a handle to its symtab.  The symtab
		     would otherwise be ended twice, once in
		     process_one_symbol, and once after this loop.  */
		  if (type_code == N_SO
		      && get_last_source_file ()
		      && previous_stab_code != (unsigned char) N_SO
		      && *name == '\000')
		    {
		      valu += section_offsets[SECT_OFF_TEXT (objfile)];
		      previous_stab_code = N_SO;
		      cust = end_compunit_symtab (valu);
		      end_stabs ();
		      last_symtab_ended = 1;
		    }
		  else
		    {
		      last_symtab_ended = 0;
		      process_one_symbol (type_code, 0, valu, name,
					  section_offsets, objfile, language);
		    }
		}
	      /* Similarly a hack.  */
	      else if (name[0] == '#')
		{
		  process_one_symbol (N_SLINE, 0, valu, name,
				      section_offsets, objfile, language);
		}
	      if (type_code == N_FUN)
		{
		  /* Make up special symbol to contain
		     procedure specific info.  */
		  mdebug_extra_func_info *e
		    = OBSTACK_ZALLOC (&mdebugread_objfile->objfile_obstack,
				      mdebug_extra_func_info);
		  struct symbol *s = new_symbol (MDEBUG_EFI_SYMBOL_NAME);

		  s->set_domain (LABEL_DOMAIN);
		  s->set_aclass_index (LOC_CONST);
		  s->set_type (builtin_type (objfile)->builtin_void);
		  s->set_value_bytes ((gdb_byte *) e);
		  e->pdr.framereg = -1;
		  add_symbol_to_list (s, get_local_symbols ());
		}
	    }
	  else if (sh.st == stLabel)
	    {
	      if (sh.index == indexNil)
		{
		  /* This is what the gcc2_compiled and __gnu_compiled_*
		     show up as.  So don't complain.  */
		  ;
		}
	      else
		{
		  /* Handle encoded stab line number.  */
		  record_line
		    (get_current_subfile (), sh.index,
		     unrelocated_addr (gdbarch_addr_bits_remove (gdbarch,
								 valu)));
		}
	    }
	  else if (sh.st == stProc || sh.st == stStaticProc
		   || sh.st == stStatic || sh.st == stEnd)
	    /* These are generated by gcc-2.x, do not complain.  */
	    ;
	  else
	    complaint (_("unknown stabs symbol %s"), name);
	}

      if (! last_symtab_ended)
	{
	  cust = end_compunit_symtab (pst->text_high (objfile));
	  end_stabs ();
	}

      /* There used to be a call to sort_blocks here, but this should not
	 be necessary for stabs symtabs.  And as sort_blocks modifies the
	 start address of the GLOBAL_BLOCK to the FIRST_LOCAL_BLOCK,
	 it did the wrong thing if the first procedure in a file was
	 generated via asm statements.  */

      /* Fill in procedure info next.  */
      if (fh->cpd > 0)
	{
	  char *pdr_ptr;
	  char *pdr_end;
	  PDR *pdr_in;
	  PDR *pdr_in_end;

	  gdb::def_vector<PDR> pr_block (fh->cpd);

	  pdr_ptr = ((char *) debug_info->external_pdr
		     + fh->ipdFirst * external_pdr_size);
	  pdr_end = pdr_ptr + fh->cpd * external_pdr_size;
	  pdr_in = pr_block.data ();
	  for (;
	       pdr_ptr < pdr_end;
	       pdr_ptr += external_pdr_size, pdr_in++)
	    {
	      (*swap_pdr_in) (cur_bfd, pdr_ptr, pdr_in);

	      /* Determine lowest PDR address, the PDRs are not always
		 sorted.  */
	      if (pdr_in == pr_block.data ())
		lowest_pdr_addr = pdr_in->adr;
	      else if (pdr_in->adr < lowest_pdr_addr)
		lowest_pdr_addr = pdr_in->adr;
	    }

	  pdr_in = pr_block.data ();
	  pdr_in_end = pdr_in + fh->cpd;
	  for (; pdr_in < pdr_in_end; pdr_in++)
	    parse_procedure (pdr_in, cust, pst);
	}
    }
  else
    {
      /* This symbol table contains ordinary ecoff entries.  */

      int maxlines, size;
      EXTR *ext_ptr;

      if (fh == 0)
	{
	  maxlines = 0;
	  cust = new_symtab ("unknown", 0, objfile);
	}
      else
	{
	  maxlines = 2 * fh->cline;
	  cust = new_symtab (pst->filename, maxlines, objfile);

	  /* The proper language was already determined when building
	     the psymtab, use it.  */
	  cust->primary_filetab ()->set_language
	    (PST_PRIVATE (pst)->pst_language);
	}

      psymtab_language = cust->primary_filetab ()->language ();

      /* This code allocates the line table on the heap and then later
	 copies it to the obstack.  So, while casting away const here
	 is ugly, it's not incorrect.  */
      lines = const_cast<linetable *> (cust->primary_filetab ()->linetable ());

      /* Get a new lexical context.  */

      push_parse_stack ();
      top_stack->cur_st = cust->primary_filetab ();
      top_stack->cur_block = cust->blockvector ()->static_block ();
      top_stack->cur_block->set_start (pst->text_low (objfile));
      top_stack->cur_block->set_end (0);
      top_stack->blocktype = stFile;
      top_stack->cur_type = 0;
      top_stack->procadr = 0;
      top_stack->numargs = 0;
      found_ecoff_debugging_info = 0;

      if (fh)
	{
	  char *sym_ptr;
	  char *sym_end;

	  /* Parse local symbols first.  */
	  sym_ptr = ((char *) debug_info->external_sym
		     + fh->isymBase * external_sym_size);
	  sym_end = sym_ptr + fh->csym * external_sym_size;
	  while (sym_ptr < sym_end)
	    {
	      SYMR sh;
	      int c;

	      (*swap_sym_in) (cur_bfd, sym_ptr, &sh);
	      c = parse_symbol (&sh,
				debug_info->external_aux + fh->iauxBase,
				sym_ptr, fh->fBigendian,
				section_offsets, objfile);
	      sym_ptr += c * external_sym_size;
	    }

	  /* Linenumbers.  At the end, check if we can save memory.
	     parse_lines has to look ahead an arbitrary number of PDR
	     structures, so we swap them all first.  */
	  if (fh->cpd > 0)
	    {
	      char *pdr_ptr;
	      char *pdr_end;
	      PDR *pdr_in;
	      PDR *pdr_in_end;

	      gdb::def_vector<PDR> pr_block (fh->cpd);

	      pdr_ptr = ((char *) debug_info->external_pdr
			 + fh->ipdFirst * external_pdr_size);
	      pdr_end = pdr_ptr + fh->cpd * external_pdr_size;
	      pdr_in = pr_block.data ();
	      for (;
		   pdr_ptr < pdr_end;
		   pdr_ptr += external_pdr_size, pdr_in++)
		{
		  (*swap_pdr_in) (cur_bfd, pdr_ptr, pdr_in);

		  /* Determine lowest PDR address, the PDRs are not always
		     sorted.  */
		  if (pdr_in == pr_block.data ())
		    lowest_pdr_addr = pdr_in->adr;
		  else if (pdr_in->adr < lowest_pdr_addr)
		    lowest_pdr_addr = pdr_in->adr;
		}

	      parse_lines (fh, pr_block.data (), lines, maxlines,
			   lowest_pdr_addr);
	      if (lines->nitems < fh->cline)
		lines = shrink_linetable (lines);

	      /* Fill in procedure info next.  */
	      pdr_in = pr_block.data ();
	      pdr_in_end = pdr_in + fh->cpd;
	      for (; pdr_in < pdr_in_end; pdr_in++)
		parse_procedure (pdr_in, NULL, pst);
	    }
	}

      size = lines->nitems;
      if (size > 1)
	--size;
      cust->primary_filetab ()->set_linetable
	((struct linetable *)
	 obstack_copy (&mdebugread_objfile->objfile_obstack,
		       lines, (sizeof (struct linetable)
			       + size * sizeof (lines->item))));
      xfree (lines);

      /* .. and our share of externals.
	 XXX use the global list to speed up things here.  How?
	 FIXME, Maybe quit once we have found the right number of ext's?  */
      top_stack->cur_st = cust->primary_filetab ();
      top_stack->cur_block
	= top_stack->cur_st->compunit ()->blockvector ()->global_block ();
      top_stack->blocktype = stFile;

      ext_ptr = PST_PRIVATE (pst)->extern_tab;
      for (i = PST_PRIVATE (pst)->extern_count; --i >= 0; ext_ptr++)
	parse_external (ext_ptr, fh->fBigendian,
			section_offsets, objfile);

      /* If there are undefined symbols, tell the user.
	 The alpha has an undefined symbol for every symbol that is
	 from a shared library, so tell the user only if verbose is on.  */
      if (info_verbose && n_undef_symbols)
	{
	  gdb_printf (_("File %s contains %d unresolved references:"),
		      symtab_to_filename_for_display
		      (cust->primary_filetab ()),
		      n_undef_symbols);
	  gdb_printf ("\n\t%4d variables\n\t%4d "
		      "procedures\n\t%4d labels\n",
		      n_undef_vars, n_undef_procs, n_undef_labels);
	  n_undef_symbols = n_undef_labels = n_undef_vars = n_undef_procs = 0;

	}
      pop_parse_stack ();

      sort_blocks (cust->primary_filetab ());
    }

  /* Now link the psymtab and the symtab.  */
  pst->compunit_symtab = cust;

  mdebugread_objfile = NULL;
}

/* Ancillary parsing procedures.  */

/* Return 1 if the symbol pointed to by SH has a cross reference
   to an opaque aggregate type, else 0.  */

static int
has_opaque_xref (FDR *fh, SYMR *sh)
{
  TIR tir;
  union aux_ext *ax;
  RNDXR rn[1];
  unsigned int rf;

  if (sh->index == indexNil)
    return 0;

  ax = debug_info->external_aux + fh->iauxBase + sh->index;
  (*debug_swap->swap_tir_in) (fh->fBigendian, &ax->a_ti, &tir);
  if (tir.bt != btStruct && tir.bt != btUnion && tir.bt != btEnum)
    return 0;

  ax++;
  (*debug_swap->swap_rndx_in) (fh->fBigendian, &ax->a_rndx, rn);
  if (rn->rfd == 0xfff)
    rf = AUX_GET_ISYM (fh->fBigendian, ax + 1);
  else
    rf = rn->rfd;
  if (rf != -1)
    return 0;
  return 1;
}

/* Lookup the type at relative index RN.  Return it in TPP
   if found and in any event come up with its name PNAME.
   BIGEND says whether aux symbols are big-endian or not (from fh->fBigendian).
   Return value says how many aux symbols we ate.  */

static int
cross_ref (int fd, union aux_ext *ax, struct type **tpp,
	   enum type_code type_code,
	   /* Use to alloc new type if none is found.  */
	   const char **pname, int bigend, const char *sym_name)
{
  RNDXR rn[1];
  unsigned int rf;
  int result = 1;
  FDR *fh;
  char *esh;
  SYMR sh;
  int xref_fd;
  struct mdebug_pending *pend;

  *tpp = NULL;

  (*debug_swap->swap_rndx_in) (bigend, &ax->a_rndx, rn);

  /* Escape index means 'the next one'.  */
  if (rn->rfd == 0xfff)
    {
      result++;
      rf = AUX_GET_ISYM (bigend, ax + 1);
    }
  else
    {
      rf = rn->rfd;
    }

  type_allocator alloc (mdebugread_objfile, get_current_subfile ()->language);

  /* mips cc uses a rf of -1 for opaque struct definitions.
     Set TYPE_STUB for these types so that check_typedef will
     resolve them if the struct gets defined in another compilation unit.  */
  if (rf == -1)
    {
      *pname = "<undefined>";
      *tpp = alloc.new_type (type_code, 0, NULL);
      (*tpp)->set_is_stub (true);
      return result;
    }

  /* mips cc uses an escaped rn->index of 0 for struct return types
     of procedures that were compiled without -g.  These will always remain
     undefined.  */
  if (rn->rfd == 0xfff && rn->index == 0)
    {
      *pname = "<undefined>";
      return result;
    }

  /* Find the relative file descriptor and the symbol in it.  */
  fh = get_rfd (fd, rf);
  xref_fd = fh - debug_info->fdr;

  if (rn->index >= fh->csym)
    {
      /* File indirect entry is corrupt.  */
      *pname = "<illegal>";
      bad_rfd_entry_complaint (sym_name, xref_fd, rn->index);
      return result;
    }

  /* If we have processed this symbol then we left a forwarding
     pointer to the type in the pending list.  If not, we`ll put
     it in a list of pending types, to be processed later when
     the file will be.  In any event, we collect the name for the
     type here.  */

  esh = ((char *) debug_info->external_sym
	 + ((fh->isymBase + rn->index)
	    * debug_swap->external_sym_size));
  (*debug_swap->swap_sym_in) (cur_bfd, esh, &sh);

  /* Make sure that this type of cross reference can be handled.  */
  if ((sh.sc != scInfo
       || (sh.st != stBlock && sh.st != stTypedef && sh.st != stIndirect
	   && sh.st != stStruct && sh.st != stUnion
	   && sh.st != stEnum))
      && (sh.st != stBlock || !SC_IS_COMMON (sh.sc)))
    {
      /* File indirect entry is corrupt.  */
      *pname = "<illegal>";
      bad_rfd_entry_complaint (sym_name, xref_fd, rn->index);
      return result;
    }

  *pname = debug_info->ss + fh->issBase + sh.iss;

  pend = is_pending_symbol (fh, esh);
  if (pend)
    *tpp = pend->t;
  else
    {
      /* We have not yet seen this type.  */

      if ((sh.iss == 0 && sh.st == stTypedef) || sh.st == stIndirect)
	{
	  TIR tir;

	  /* alpha cc puts out a stTypedef with a sh.iss of zero for
	     two cases:
	     a) forward declarations of structs/unions/enums which are not
	     defined in this compilation unit.
	     For these the type will be void.  This is a bad design decision
	     as cross referencing across compilation units is impossible
	     due to the missing name.
	     b) forward declarations of structs/unions/enums/typedefs which
	     are defined later in this file or in another file in the same
	     compilation unit.  Irix5 cc uses a stIndirect symbol for this.
	     Simply cross reference those again to get the true type.
	     The forward references are not entered in the pending list and
	     in the symbol table.  */

	  (*debug_swap->swap_tir_in) (bigend,
				      &(debug_info->external_aux
					+ fh->iauxBase + sh.index)->a_ti,
				      &tir);
	  if (tir.tq0 != tqNil)
	    complaint (_("illegal tq0 in forward typedef for %s"), sym_name);
	  switch (tir.bt)
	    {
	    case btVoid:
	      *tpp = alloc.new_type (type_code, 0, NULL);
	      *pname = "<undefined>";
	      break;

	    case btStruct:
	    case btUnion:
	    case btEnum:
	      cross_ref (xref_fd,
			 (debug_info->external_aux
			  + fh->iauxBase + sh.index + 1),
			 tpp, type_code, pname,
			 fh->fBigendian, sym_name);
	      break;

	    case btTypedef:
	      /* Follow a forward typedef.  This might recursively
		 call cross_ref till we get a non typedef'ed type.
		 FIXME: This is not correct behaviour, but gdb currently
		 cannot handle typedefs without type copying.  Type
		 copying is impossible as we might have mutual forward
		 references between two files and the copied type would not
		 get filled in when we later parse its definition.  */
	      *tpp = parse_type (xref_fd,
				 debug_info->external_aux + fh->iauxBase,
				 sh.index,
				 NULL,
				 fh->fBigendian,
				 debug_info->ss + fh->issBase + sh.iss);
	      add_pending (fh, esh, *tpp);
	      break;

	    default:
	      complaint (_("illegal bt %d in forward typedef for %s"), tir.bt,
			 sym_name);
	      *tpp = alloc.new_type (type_code, 0, NULL);
	      break;
	    }
	  return result;
	}
      else if (sh.st == stTypedef)
	{
	  /* Parse the type for a normal typedef.  This might recursively call
	     cross_ref till we get a non typedef'ed type.
	     FIXME: This is not correct behaviour, but gdb currently
	     cannot handle typedefs without type copying.  But type copying is
	     impossible as we might have mutual forward references between
	     two files and the copied type would not get filled in when
	     we later parse its definition.   */
	  *tpp = parse_type (xref_fd,
			     debug_info->external_aux + fh->iauxBase,
			     sh.index,
			     NULL,
			     fh->fBigendian,
			     debug_info->ss + fh->issBase + sh.iss);
	}
      else
	{
	  /* Cross reference to a struct/union/enum which is defined
	     in another file in the same compilation unit but that file
	     has not been parsed yet.
	     Initialize the type only, it will be filled in when
	     it's definition is parsed.  */
	  *tpp = alloc.new_type (type_code, 0, NULL);
	}
      add_pending (fh, esh, *tpp);
    }

  /* We used one auxent normally, two if we got a "next one" rf.  */
  return result;
}


/* Quick&dirty lookup procedure, to avoid the MI ones that require
   keeping the symtab sorted.  */

static struct symbol *
mylookup_symbol (const char *name, const struct block *block,
		 domain_enum domain, enum address_class theclass)
{
  int inc;

  inc = name[0];
  for (struct symbol *sym : block_iterator_range (block))
    {
      if (sym->linkage_name ()[0] == inc
	  && sym->domain () == domain
	  && sym->aclass () == theclass
	  && strcmp (sym->linkage_name (), name) == 0)
	return sym;
    }

  block = block->superblock ();
  if (block)
    return mylookup_symbol (name, block, domain, theclass);
  return 0;
}


/* Add a new symbol S to a block B.  */

static void
add_symbol (struct symbol *s, struct symtab *symtab, struct block *b)
{
  s->set_symtab (symtab);
  mdict_add_symbol (b->multidict (), s);
}

/* Add a new block B to a symtab S.  */

static void
add_block (struct block *b, struct symtab *s)
{
  /* Cast away "const", but that's ok because we're building the
     symtab and blockvector here.  */
  struct blockvector *bv
    = (struct blockvector *) s->compunit ()->blockvector ();

  bv = (struct blockvector *) xrealloc ((void *) bv,
					(sizeof (struct blockvector)
					 + bv->num_blocks ()
					 * sizeof (struct block)));
  if (bv != s->compunit ()->blockvector ())
    s->compunit ()->set_blockvector (bv);

  bv->set_block (bv->num_blocks (), b);
  bv->set_num_blocks (bv->num_blocks () + 1);
}

/* Add a new linenumber entry (LINENO,ADR) to a linevector LT.
   MIPS' linenumber encoding might need more than one byte
   to describe it, LAST is used to detect these continuation lines.

   Combining lines with the same line number seems like a bad idea.
   E.g: There could be a line number entry with the same line number after the
   prologue and GDB should not ignore it (this is a better way to find
   a prologue than mips_skip_prologue).
   But due to the compressed line table format there are line number entries
   for the same line which are needed to bridge the gap to the next
   line number entry.  These entries have a bogus address info with them
   and we are unable to tell them from intended duplicate line number
   entries.
   This is another reason why -ggdb debugging format is preferable.  */

static int
add_line (struct linetable *lt, int lineno, CORE_ADDR adr, int last)
{
  /* DEC c89 sometimes produces zero linenos which confuse gdb.
     Change them to something sensible.  */
  if (lineno == 0)
    lineno = 1;
  if (last == 0)
    last = -2;			/* Make sure we record first line.  */

  if (last == lineno)		/* Skip continuation lines.  */
    return lineno;

  lt->item[lt->nitems].line = lineno;
  lt->item[lt->nitems++].set_unrelocated_pc (unrelocated_addr (adr << 2));
  return lineno;
}

/* Sorting and reordering procedures.  */

/* Blocks with a smaller low bound should come first.  */

static bool
block_is_less_than (const struct block *b1, const struct block *b2)
{
  CORE_ADDR start1 = b1->start ();
  CORE_ADDR start2 = b2->start ();

  if (start1 != start2)
    return start1 < start2;

  return (b2->end ()) < (b1->end ());
}

/* Sort the blocks of a symtab S.
   Reorder the blocks in the blockvector by code-address,
   as required by some MI search routines.  */

static void
sort_blocks (struct symtab *s)
{
  /* We have to cast away const here, but this is ok because we're
     constructing the blockvector in this code.  */
  struct blockvector *bv
    = (struct blockvector *) s->compunit ()->blockvector ();

  if (bv->num_blocks () <= FIRST_LOCAL_BLOCK)
    {
      /* Cosmetic */
      if (bv->global_block ()->end () == 0)
	bv->global_block ()->set_start (0);
      if (bv->static_block ()->end () == 0)
	bv->static_block ()->set_start (0);
      return;
    }
  /*
   * This is very unfortunate: normally all functions are compiled in
   * the order they are found, but if the file is compiled -O3 things
   * are very different.  It would be nice to find a reliable test
   * to detect -O3 images in advance.
   */
  if (bv->num_blocks () > FIRST_LOCAL_BLOCK + 1)
    {
      gdb::array_view<block *> blocks_view = bv->blocks ();

      std::sort (blocks_view.begin () + FIRST_LOCAL_BLOCK,
		 blocks_view.end (), block_is_less_than);
    }

  {
    CORE_ADDR high = 0;
    int i, j = bv->num_blocks ();

    for (i = FIRST_LOCAL_BLOCK; i < j; i++)
      if (high < bv->block (i)->end ())
	high = bv->block (i)->end ();
    bv->global_block ()->set_end (high);
  }

  bv->global_block ()->set_start (bv->block (FIRST_LOCAL_BLOCK)->start ());
  bv->static_block ()->set_start (bv->global_block ()->start ());
  bv->static_block ()->set_end (bv->global_block ()->end ());
}


/* Constructor/restructor/destructor procedures.  */

/* Allocate a new symtab for NAME.  Needs an estimate of how many
   linenumbers MAXLINES we'll put in it.  */

static struct compunit_symtab *
new_symtab (const char *name, int maxlines, struct objfile *objfile)
{
  struct compunit_symtab *cust = allocate_compunit_symtab (objfile, name);
  struct symtab *symtab;
  struct blockvector *bv;
  enum language lang;

  add_compunit_symtab_to_objfile (cust);
  symtab = allocate_symtab (cust, name);

  symtab->set_linetable (new_linetable (maxlines));
  lang = cust->language ();

  /* All symtabs must have at least two blocks.  */
  bv = new_bvect (2);
  bv->set_block (GLOBAL_BLOCK, new_block (objfile, NON_FUNCTION_BLOCK, lang));
  bv->set_block (STATIC_BLOCK, new_block (objfile, NON_FUNCTION_BLOCK, lang));
  bv->static_block ()->set_superblock (bv->global_block ());
  cust->set_blockvector (bv);

  cust->set_debugformat ("ECOFF");
  return cust;
}

/* Allocate a new partial_symtab NAME.  */

static legacy_psymtab *
new_psymtab (const char *name, psymtab_storage *partial_symtabs,
	     struct objfile *objfile)
{
  legacy_psymtab *psymtab;

  psymtab = new legacy_psymtab (name, partial_symtabs, objfile->per_bfd);

  /* Keep a backpointer to the file's symbols.  */

  psymtab->read_symtab_private
    = OBSTACK_ZALLOC (&objfile->objfile_obstack, md_symloc);
  CUR_BFD (psymtab) = cur_bfd;
  DEBUG_SWAP (psymtab) = debug_swap;
  DEBUG_INFO (psymtab) = debug_info;
  PENDING_LIST (psymtab) = pending_list;

  /* The way to turn this into a symtab is to call...  */
  psymtab->legacy_read_symtab = mdebug_read_symtab;
  psymtab->legacy_expand_psymtab = mdebug_expand_psymtab;
  return (psymtab);
}


/* Allocate a linetable array of the given SIZE.  Since the struct
   already includes one item, we subtract one when calculating the
   proper size to allocate.  */

static struct linetable *
new_linetable (int size)
{
  struct linetable *l;

  if (size > 1)
    --size;
  size = size * sizeof (l->item) + sizeof (struct linetable);
  l = (struct linetable *) xmalloc (size);
  l->nitems = 0;
  return l;
}

/* Oops, too big.  Shrink it.  This was important with the 2.4 linetables,
   I am not so sure about the 3.4 ones.

   Since the struct linetable already includes one item, we subtract one when
   calculating the proper size to allocate.  */

static struct linetable *
shrink_linetable (struct linetable *lt)
{
  return (struct linetable *) xrealloc ((void *) lt,
					(sizeof (struct linetable)
					 + ((lt->nitems - 1)
					    * sizeof (lt->item))));
}

/* Allocate and zero a new blockvector of NBLOCKS blocks.  */

static struct blockvector *
new_bvect (int nblocks)
{
  struct blockvector *bv;
  int size;

  size = sizeof (struct blockvector) + nblocks * sizeof (struct block *);
  bv = (struct blockvector *) xzalloc (size);
  bv->set_num_blocks (nblocks);

  return bv;
}

/* Allocate and zero a new block of language LANGUAGE, and set its
   BLOCK_MULTIDICT.  If function is non-zero, assume the block is
   associated to a function, and make sure that the symbols are stored
   linearly; otherwise, store them hashed.  */

static struct block *
new_block (struct objfile *objfile, enum block_type type,
	   enum language language)
{
  struct block *retval = new (&objfile->objfile_obstack) block;

  if (type == FUNCTION_BLOCK)
    retval->set_multidict (mdict_create_linear_expandable (language));
  else
    retval->set_multidict (mdict_create_hashed_expandable (language));

  return retval;
}

/* Create a new symbol with printname NAME.  */

static struct symbol *
new_symbol (const char *name)
{
  struct symbol *s = new (&mdebugread_objfile->objfile_obstack) symbol;

  s->set_language (psymtab_language, &mdebugread_objfile->objfile_obstack);
  s->compute_and_set_names (name, true, mdebugread_objfile->per_bfd);
  return s;
}

/* Create a new type with printname NAME.  */

static struct type *
new_type (char *name)
{
  struct type *t;

  t = type_allocator (mdebugread_objfile,
		      get_current_subfile ()->language).new_type ();
  t->set_name (name);
  INIT_CPLUS_SPECIFIC (t);
  return t;
}

/* Read ECOFF debugging information from a BFD section.  This is
   called from elfread.c.  It parses the section into a
   ecoff_debug_info struct, and then lets the rest of the file handle
   it as normal.  */

void
elfmdebug_build_psymtabs (struct objfile *objfile,
			  const struct ecoff_debug_swap *swap, asection *sec)
{
  bfd *abfd = objfile->obfd.get ();
  struct ecoff_debug_info *info;

  /* FIXME: It's not clear whether we should be getting minimal symbol
     information from .mdebug in an ELF file, or whether we will.
     Re-initialize the minimal symbol reader in case we do.  */

  minimal_symbol_reader reader (objfile);

  info = XOBNEW (&objfile->objfile_obstack, ecoff_debug_info);

  if (!(*swap->read_debug_info) (abfd, sec, info))
    error (_("Error reading ECOFF debugging information: %s"),
	   bfd_errmsg (bfd_get_error ()));

  mdebug_build_psymtabs (reader, objfile, swap, info);

  reader.install ();
}

void _initialize_mdebugread ();
void
_initialize_mdebugread ()
{
  mdebug_register_index
    = register_symbol_register_impl (LOC_REGISTER, &mdebug_register_funcs);
  mdebug_regparm_index
    = register_symbol_register_impl (LOC_REGPARM_ADDR, &mdebug_register_funcs);
}
