register struct mdebug_pending *p;
struct mdebug_pending *p;
is_pending_symbol PARAMS ((FDR *, char *));static voidpop_parse_stack PARAMS ((void));static voidpush_parse_stack PARAMS ((void));static char *fdr_name PARAMS ((FDR *));static voidmdebug_psymtab_to_symtab PARAMS ((struct partial_symtab *));static intupgrade_type PARAMS ((int, struct type **, int, union aux_ext *, int, char *));static voidparse_partial_symbols PARAMS ((struct objfile *,			       struct section_offsets *));static FDR*get_rfd PARAMS ((int, int));static inthas_opaque_xref PARAMS ((FDR *, SYMR *));static intcross_ref PARAMS ((int, union aux_ext *, struct type **, enum type_code,		   char **, int, char *));static struct symbol *new_symbol PARAMS ((char *));static struct type *new_type PARAMS ((char *));static struct block *new_block PARAMS ((int));static struct symtab *new_symtab PARAMS ((char *, int, int, struct objfile *));static struct linetable *new_linetable PARAMS ((int));static struct blockvector *new_bvect PARAMS ((int));static intparse_symbol PARAMS ((SYMR *, union aux_ext *, char *, int, struct section_offsets *));static struct type *parse_type PARAMS ((int, union aux_ext *, unsigned int, int *, int, char *));static struct symbol *mylookup_symbol PARAMS ((char *, struct block *, namespace_enum,			 enum address_class));static struct block *shrink_block PARAMS ((struct block *, struct symtab *));static PTRxzalloc PARAMS ((unsigned int));static voidsort_blocks PARAMS ((struct symtab *));static intcompare_blocks PARAMS ((const void *, const void *));static struct partial_symtab *new_psymtab PARAMS ((char *, struct objfile *, struct section_offsets *));static voidpsymtab_to_symtab_1 PARAMS ((struct partial_symtab *, char *));static voidadd_block PARAMS ((struct block *, struct symtab *));static voidadd_symbol PARAMS ((struct symbol *, struct block *));static intadd_line PARAMS ((struct linetable *, int, CORE_ADDR, int));static struct linetable *shrink_linetable PARAMS ((struct linetable *));static voidhandle_psymbol_enumerators PARAMS ((struct objfile *, FDR *, int, CORE_ADDR));static char *mdebug_next_symbol_text PARAMS ((struct objfile *));/* Address bounds for the signal trampoline in inferior, if any */CORE_ADDR sigtramp_address, sigtramp_end;/* Allocate zeroed memory */static PTRxzalloc (size)     unsigned int size;{  PTR p = xmalloc (size);  memset (p, 0, size);  return p;}/* Exported procedure: Builds a symtab from the PST partial one.   Restores the environment in effect when PST was created, delegates   most of the work to an ancillary procedure, and sorts   and reorders the symtab list at the end */static voidmdebug_psymtab_to_symtab (pst)     struct partial_symtab *pst;{  if (!pst)    return;  if (info_verbose)    {      printf_filtered ("Reading in symbols for %s...", pst->filename);      gdb_flush (gdb_stdout);    }  next_symbol_text_func = mdebug_next_symbol_text;  psymtab_to_symtab_1 (pst, pst->filename);  /* Match with global symbols.  This only needs to be done once,     after all of the symtabs and dependencies have been read in.   */  scan_file_globals (pst->objfile);  if (info_verbose)    printf_filtered ("done.\n");}/* File-level interface functions *//* Find a file descriptor given its index RF relative to a file CF */static FDR *get_rfd (cf, rf)     int cf, rf;{  FDR *fdrs;  register 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 char *fdr_name (f)     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.  */voidmdebug_build_psymtabs (objfile, swap, info, section_offsets)     struct objfile *objfile;     const struct ecoff_debug_swap *swap;     struct ecoff_debug_info *info;     struct section_offsets *section_offsets;{  cur_bfd = objfile->obfd;  debug_swap = swap;  debug_info = info;  /* Make sure all the FDR information is swapped in.  */  if (info->fdr == (FDR *) NULL)    {      char *fdr_src;      char *fdr_end;      FDR *fdr_ptr;      info->fdr = (FDR *) obstack_alloc (&objfile->psymbol_obstack,					 (info->symbolic_header.ifdMax					  * sizeof (FDR)));      fdr_src = 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, fdr_src, fdr_ptr);    }  parse_partial_symbols (objfile, section_offsets);#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)	printf_unfiltered ("\n%s not compiled with -g, debugging support is limited.\n",		 objfile->name);      printf_unfiltered ("You should compile with -g2 or -g3 for best debugging support.\n");      gdb_flush (gdb_stdout);    }#endif}/* Local utilities *//* Map of FDR indexes to partial symtabs */struct pst_map{  struct partial_symtab *pst;	/* the psymtab proper */  long n_globals;		/* exported globals (external symbols) */  long globals_offset;		/* 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;  int maxsyms;			/* Max symbols in this block. */  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 voidpush_parse_stack (){  struct parse_stack *new;  /* Reuse frames if possible */  if (top_stack && top_stack->prev)    new = top_stack->prev;  else    new = (struct parse_stack *) xzalloc (sizeof (struct parse_stack));  /* Initialize new frame with previous content */  if (top_stack)    {      register struct parse_stack *prev = new->prev;      *new = *top_stack;      top_stack->prev = new;      new->prev = prev;      new->next = top_stack;    }  top_stack = new;}/* Exit a lexical context */static voidpop_parse_stack (){  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, and used   to be in the sym_private field.  I took it out when I split   mdebugread from mipsread, because this might not be the only type   of symbols read from an object file.  Instead, 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 (fh, sh)     FDR *fh;     char *sh;{  int f_idx = fh - debug_info->fdr;  register 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;}