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

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

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

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

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

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

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

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

#include "bfd.h"

#include "coff/ecoff.h"		/* COFF-like aspects of ecoff files.  */

#include "libaout.h"		/* Private BFD a.out information.  */
#include "aout/aout64.h"
#include "aout/stab_gnu.h"	/* STABS information.  */

#include "expression.h"

#include <algorithm>

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

/* The objfile we are currently reading.  */

static struct objfile *mdebugread_objfile;



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

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

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

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

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

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

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

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

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

/* Macros and extra defs.  */

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

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

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

static enum language psymtab_language = language_unknown;

/* Current BFD.  */

static bfd *cur_bfd;

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

static const struct ecoff_debug_swap *debug_swap;

/* Pointers to debugging information for CUR_BFD.  */

static struct ecoff_debug_info *debug_info;

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

static FDR *cur_fdr;
static int cur_fd;

/* Index of current symbol.  */

static int cur_sdx;

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

static int max_gdbinfo;
static int max_glevel;

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

static int n_undef_symbols, n_undef_labels, n_undef_vars, n_undef_procs;

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

static char stabs_symbol[] = STABS_SYMBOL;

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

static int found_ecoff_debugging_info;

/* Forward declarations.  */

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

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

static int has_opaque_xref (FDR *, SYMR *);

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

static struct symbol *new_symbol (const char *);

static struct type *new_type (char *);

enum block_type { FUNCTION_BLOCK, NON_FUNCTION_BLOCK };

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

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

static struct linetable *new_linetable (int);

static struct blockvector *new_bvect (int);

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

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

static void sort_blocks (struct symtab *);

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

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

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

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

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

static struct linetable *shrink_linetable (struct linetable *);

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

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

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

  self->expand_psymtab (objfile);

  /* Match with global symbols.  This only needs to be done once,
     after all of the symtabs and dependencies have been read in.  */
  scan_file_globals (objfile);
}

/* File-level interface functions.  */

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

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

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

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

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


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

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

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

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

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

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

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

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


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

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

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

    int blocktype;

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

 *top_stack;			/* Top stack ptr */


/* Enter a new lexical context.  */

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

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

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

/* Exit a lexical context.  */

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


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

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


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

static struct mdebug_pending **pending_list;

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

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

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

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

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

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

/* Parsing Routines proper.  */

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

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

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

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

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

  return regno;
}

static const struct symbol_register_ops mdebug_register_funcs = {
  mdebug_reg_to_regnum
};

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

static int mdebug_register_index;
static int mdebug_regparm_index;

/* Common code for symbols describing data.  */

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	t->set_code (type_code);
	t->set_length (sh->value);
	t->set_num_fields (nfields);
	f = ((struct field *) TYPE_ALLOC (t, nfields * sizeof (struct field)));
	t->set_fields (f);

	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);
		FIELD_BITSIZE (*f) = 0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	      if (nparams > 0)
		{
		  ftype->set_num_fields (nparams);
		  ftype->set_fields
		    ((struct field *)
		     TYPE_ALLOC (ftype, nparams * sizeof (struct field)));

		  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 ());
			  TYPE_FIELD_ARTIFICIAL (ftype, iparams) = 0;
			  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));
	FIELD_BITSIZE (*f) = bitsize;
      }
      break;

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

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

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

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

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

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

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

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

		 Sigh.

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

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

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

  return count;
}

/* Basic types.  */

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

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

  if (bt >= btMax)
    return NULL;

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

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

  type_allocator alloc (objfile);

  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);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  return tp;
}

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

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

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

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

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

    case tqArray:
      off = 0;

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

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

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

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

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

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

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

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

      *tpp = t;
      return 4 + off;

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

      adr = pr->adr - lowest_pdr_addr;

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

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

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

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

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

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

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

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

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

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

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

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

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

  set_last_source_file (NULL);

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

  max_gdbinfo = 0;
  max_glevel = MIN_GLEVEL;

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

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

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

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

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

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

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

  /* ECOFF in ELF:

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

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

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

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

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

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

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


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


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

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

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

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

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

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

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

	      if (sbss_sect_index == -1)
		continue;

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

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

      cur_fdr = fh = debug_info->fdr + f_idx;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		switch (type_code)
		  {
		    const char *p;

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

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

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

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

		  case N_ABS | N_EXT:
		  record_it:
		    continue;

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

		  case N_NBTEXT:

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

		  case N_FN:
		  case N_FN_SEQ:
		  case N_TEXT:
		    continue;

		  case N_DATA:
		    goto record_it;

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

		  case N_UNDF:
		    continue;

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

		  case N_ABS:
		  case N_NBDATA:
		  case N_NBBSS:
		    continue;

		    /* Keep going . . .  */

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

		    /*
		     * Debugger symbols
		     */

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

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

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

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

		      prev_so_symnum = symnum;

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

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

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

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

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

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

		  case N_BINCL:
		    continue;

		  case N_SOL:
		    {
		      enum language tmp_language;

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

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

		      tmp_language
			= deduce_language_from_filename (namestring);

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

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

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

		      {
			int i;

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

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

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

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

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

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



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

		    switch (p[1])
		      {
		      case 'S':
			pst->add_psymbol (gdb::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 (gdb::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
			      (gdb::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
				  (gdb::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
			      (gdb::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 (gdb::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 (gdb::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 (gdb::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 (gdb::string_view (namestring,
							    p - namestring),
					  true, VAR_DOMAIN, LOC_BLOCK,
					  SECT_OFF_TEXT (objfile),
					  psymbol_placement::GLOBAL,
					  unrelocated_addr (sh.value),
					  psymtab_language,
					  partial_symtabs, objfile);
			continue;

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

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

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

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

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

		  case N_EXCL:
		    continue;

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

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

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

		    continue;

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

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

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

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

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

	      minsym_value = unrelocated_addr (sh.value);

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

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

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

		  /* FALLTHROUGH */

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

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

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

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

		  procaddr = unrelocated_addr (sh.value);

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

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

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

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

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

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

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

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

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

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

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

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

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

	      gdb_assert (ext_ptr->ifd == f_idx);

	      psh = &ext_ptr->asym;

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

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

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

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

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

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

      if (pst == NULL)
	continue;

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

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

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

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

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

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

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

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

  switch (stype)
    {
    case stEnum:
      break;

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

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

    default:
      return;
    }

  for (;;)
    {
      char *name;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

      /* Parse local symbols first.  */

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

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

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

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

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

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

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

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

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

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

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

      int maxlines, size;
      EXTR *ext_ptr;

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

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

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

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

      /* Get a new lexical context.  */

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	}
      pop_parse_stack ();

      sort_blocks (cust->primary_filetab ());
    }

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

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

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

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

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

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

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

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

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

  *tpp = NULL;

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

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

  type_allocator alloc (mdebugread_objfile);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/* Constructor/restructor/destructor procedures.  */

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

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

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

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

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

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

/* Allocate a new partial_symtab NAME.  */

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

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

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

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

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


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

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

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

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

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

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

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

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

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

  return bv;
}

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

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

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

  return retval;
}

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

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

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

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

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

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

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

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

  minimal_symbol_reader reader (objfile);

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

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

  mdebug_build_psymtabs (reader, objfile, swap, info);

  reader.install ();
}

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