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

   Copyright (C) 1986-2025 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 "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.  */

static 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 address 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 (LABEL_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 (FUNCTION_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;
      /* Beginning 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 (TYPE_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
		 referring 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 preferable (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:
	  /* Beginning 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 beginning 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, referring 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;
	      stabs_deprecated_warning ();
	    }
	}

      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.  stabs_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-existent .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.  stabs_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;
	      int 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;
	      int 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.  stabs_end_psymtab returns NULL if the psymtab was
	 empty and put on the free list.  */
      fdr_to_pst[f_idx].pst
	= stabs_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 behavior, 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 behavior, 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 ();
}

/* see mdebugread.h.  */

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

  minimal_symbol_reader reader (objfile);

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

  mdebug_build_psymtabs (reader, objfile, swap, info);

  reader.install ();
}

INIT_GDB_FILE (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);
}
