119370Spst/* Read coff symbol tables and convert to internal format, for GDB.
298948Sobrien   Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
3130809Smarcel   1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
498948Sobrien   Free Software Foundation, Inc.
519370Spst   Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu).
619370Spst
798948Sobrien   This file is part of GDB.
819370Spst
998948Sobrien   This program is free software; you can redistribute it and/or modify
1098948Sobrien   it under the terms of the GNU General Public License as published by
1198948Sobrien   the Free Software Foundation; either version 2 of the License, or
1298948Sobrien   (at your option) any later version.
1319370Spst
1498948Sobrien   This program is distributed in the hope that it will be useful,
1598948Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1698948Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1798948Sobrien   GNU General Public License for more details.
1819370Spst
1998948Sobrien   You should have received a copy of the GNU General Public License
2098948Sobrien   along with this program; if not, write to the Free Software
2198948Sobrien   Foundation, Inc., 59 Temple Place - Suite 330,
2298948Sobrien   Boston, MA 02111-1307, USA.  */
2319370Spst
2419370Spst#include "defs.h"
2519370Spst#include "symtab.h"
2619370Spst#include "gdbtypes.h"
2746283Sdfr#include "demangle.h"
2819370Spst#include "breakpoint.h"
2919370Spst
3019370Spst#include "bfd.h"
31130809Smarcel#include "gdb_obstack.h"
3219370Spst
3319370Spst#include "gdb_string.h"
3419370Spst#include <ctype.h>
3519370Spst
3619370Spst#include "coff/internal.h"	/* Internal format of COFF symbols in BFD */
3719370Spst#include "libcoff.h"		/* FIXME secret internal data from BFD */
3819370Spst#include "objfiles.h"
3919370Spst#include "buildsym.h"
4019370Spst#include "gdb-stabs.h"
4119370Spst#include "stabsread.h"
4219370Spst#include "complaints.h"
4319370Spst#include "target.h"
4498948Sobrien#include "gdb_assert.h"
45130809Smarcel#include "block.h"
46130809Smarcel#include "dictionary.h"
4719370Spst
48130809Smarcel#include "coff-pe-read.h"
49130809Smarcel
5098948Sobrienextern void _initialize_coffread (void);
5119370Spst
5298948Sobrienstruct coff_symfile_info
5398948Sobrien  {
5498948Sobrien    file_ptr min_lineno_offset;	/* Where in file lowest line#s are */
5598948Sobrien    file_ptr max_lineno_offset;	/* 1+last byte of line#s in file */
5619370Spst
5798948Sobrien    CORE_ADDR textaddr;		/* Addr of .text section. */
5898948Sobrien    unsigned int textsize;	/* Size of .text section. */
5998948Sobrien    struct stab_section_list *stabsects;	/* .stab sections.  */
6098948Sobrien    asection *stabstrsect;	/* Section pointer for .stab section */
6198948Sobrien    char *stabstrdata;
6298948Sobrien  };
6398948Sobrien
6419370Spst/* Translate an external name string into a user-visible name.  */
6519370Spst#define	EXTERNAL_NAME(string, abfd) \
6619370Spst	(string[0] == bfd_get_symbol_leading_char(abfd)? string+1: string)
6719370Spst
6819370Spst/* To be an sdb debug type, type must have at least a basic or primary
6919370Spst   derived type.  Using this rather than checking against T_NULL is
7019370Spst   said to prevent core dumps if we try to operate on Michael Bloom
7119370Spst   dbx-in-coff file.  */
7219370Spst
7319370Spst#define SDB_TYPE(type) (BTYPE(type) | (type & N_TMASK))
7419370Spst
7519370Spst/* Core address of start and end of text of current source file.
7619370Spst   This comes from a ".text" symbol where x_nlinno > 0.  */
7719370Spst
7819370Spststatic CORE_ADDR current_source_start_addr;
7919370Spststatic CORE_ADDR current_source_end_addr;
8019370Spst
8119370Spst/* The addresses of the symbol table stream and number of symbols
8219370Spst   of the object file we are reading (as copied into core).  */
8319370Spst
8419370Spststatic bfd *nlist_bfd_global;
8519370Spststatic int nlist_nsyms_global;
8619370Spst
8719370Spst
8819370Spst/* Pointers to scratch storage, used for reading raw symbols and auxents.  */
8919370Spst
9019370Spststatic char *temp_sym;
9119370Spststatic char *temp_aux;
9219370Spst
9319370Spst/* Local variables that hold the shift and mask values for the
9419370Spst   COFF file that we are currently reading.  These come back to us
9519370Spst   from BFD, and are referenced by their macro names, as well as
9619370Spst   internally to the BTYPE, ISPTR, ISFCN, ISARY, ISTAG, and DECREF
9719370Spst   macros from include/coff/internal.h .  */
9819370Spst
9998948Sobrienstatic unsigned local_n_btmask;
10098948Sobrienstatic unsigned local_n_btshft;
10198948Sobrienstatic unsigned local_n_tmask;
10298948Sobrienstatic unsigned local_n_tshift;
10319370Spst
10419370Spst#define	N_BTMASK	local_n_btmask
10519370Spst#define	N_BTSHFT	local_n_btshft
10619370Spst#define	N_TMASK		local_n_tmask
10719370Spst#define	N_TSHIFT	local_n_tshift
10898948Sobrien
10919370Spst/* Local variables that hold the sizes in the file of various COFF structures.
11019370Spst   (We only need to know this to read them from the file -- BFD will then
11119370Spst   translate the data in them, into `internal_xxx' structs in the right
11219370Spst   byte order, alignment, etc.)  */
11319370Spst
11498948Sobrienstatic unsigned local_linesz;
11598948Sobrienstatic unsigned local_symesz;
11698948Sobrienstatic unsigned local_auxesz;
11719370Spst
11846283Sdfr/* This is set if this is a PE format file.  */
11946283Sdfr
12046283Sdfrstatic int pe_file;
12146283Sdfr
12219370Spst/* Chain of typedefs of pointers to empty struct/union types.
12319370Spst   They are chained thru the SYMBOL_VALUE_CHAIN.  */
12419370Spst
12519370Spststatic struct symbol *opaque_type_chain[HASHSIZE];
12619370Spst
12719370Spst/* Simplified internal version of coff symbol table information */
12819370Spst
12998948Sobrienstruct coff_symbol
13098948Sobrien  {
13198948Sobrien    char *c_name;
13298948Sobrien    int c_symnum;		/* symbol number of this entry */
13398948Sobrien    int c_naux;			/* 0 if syment only, 1 if syment + auxent, etc */
13498948Sobrien    long c_value;
13598948Sobrien    int c_sclass;
13698948Sobrien    int c_secnum;
13798948Sobrien    unsigned int c_type;
13898948Sobrien  };
13919370Spst
14098948Sobrienextern void stabsread_clear_cache (void);
14119370Spst
14298948Sobrienstatic struct type *coff_read_struct_type (int, int, int);
14319370Spst
14498948Sobrienstatic struct type *decode_base_type (struct coff_symbol *,
14598948Sobrien				      unsigned int, union internal_auxent *);
14619370Spst
14798948Sobrienstatic struct type *decode_type (struct coff_symbol *, unsigned int,
14898948Sobrien				 union internal_auxent *);
14919370Spst
15098948Sobrienstatic struct type *decode_function_type (struct coff_symbol *,
15198948Sobrien					  unsigned int,
15298948Sobrien					  union internal_auxent *);
15319370Spst
15498948Sobrienstatic struct type *coff_read_enum_type (int, int, int);
15519370Spst
15698948Sobrienstatic struct symbol *process_coff_symbol (struct coff_symbol *,
15798948Sobrien					   union internal_auxent *,
15898948Sobrien					   struct objfile *);
15919370Spst
16098948Sobrienstatic void patch_opaque_types (struct symtab *);
16119370Spst
16298948Sobrienstatic void enter_linenos (long, int, int, struct objfile *);
16319370Spst
16498948Sobrienstatic void free_linetab (void);
16519370Spst
16698948Sobrienstatic void free_linetab_cleanup (void *ignore);
16719370Spst
16898948Sobrienstatic int init_lineno (bfd *, long, int);
16919370Spst
17098948Sobrienstatic char *getsymname (struct internal_syment *);
17119370Spst
17298948Sobrienstatic char *coff_getfilename (union internal_auxent *);
17319370Spst
17498948Sobrienstatic void free_stringtab (void);
17519370Spst
17698948Sobrienstatic void free_stringtab_cleanup (void *ignore);
17719370Spst
17898948Sobrienstatic int init_stringtab (bfd *, long);
17919370Spst
18098948Sobrienstatic void read_one_sym (struct coff_symbol *,
18198948Sobrien			  struct internal_syment *, union internal_auxent *);
18219370Spst
18398948Sobrienstatic void coff_symtab_read (long, unsigned int, struct objfile *);
18419370Spst
18519370Spst/* We are called once per section from coff_symfile_read.  We
18619370Spst   need to examine each section we are passed, check to see
18719370Spst   if it is something we are interested in processing, and
18819370Spst   if so, stash away some access information for the section.
18919370Spst
19019370Spst   FIXME: The section names should not be hardwired strings (what
19119370Spst   should they be?  I don't think most object file formats have enough
19219370Spst   section flags to specify what kind of debug section it is
19319370Spst   -kingdon).  */
19419370Spst
19519370Spststatic void
19698948Sobriencoff_locate_sections (bfd *abfd, asection *sectp, void *csip)
19719370Spst{
198130809Smarcel  struct coff_symfile_info *csi;
19919370Spst  const char *name;
20019370Spst
20119370Spst  csi = (struct coff_symfile_info *) csip;
20219370Spst  name = bfd_get_section_name (abfd, sectp);
203130809Smarcel  if (DEPRECATED_STREQ (name, ".text"))
20419370Spst    {
20519370Spst      csi->textaddr = bfd_section_vma (abfd, sectp);
20619370Spst      csi->textsize += bfd_section_size (abfd, sectp);
20719370Spst    }
20819370Spst  else if (strncmp (name, ".text", sizeof ".text" - 1) == 0)
20919370Spst    {
21019370Spst      csi->textsize += bfd_section_size (abfd, sectp);
21119370Spst    }
212130809Smarcel  else if (DEPRECATED_STREQ (name, ".stabstr"))
21319370Spst    {
21419370Spst      csi->stabstrsect = sectp;
21519370Spst    }
21619370Spst  else if (strncmp (name, ".stab", sizeof ".stab" - 1) == 0)
21719370Spst    {
21819370Spst      const char *s;
21919370Spst
22019370Spst      /* We can have multiple .stab sections if linked with
22119370Spst         --split-by-reloc.  */
22219370Spst      for (s = name + sizeof ".stab" - 1; *s != '\0'; s++)
22398948Sobrien	if (!isdigit (*s))
22419370Spst	  break;
22519370Spst      if (*s == '\0')
22619370Spst	{
22719370Spst	  struct stab_section_list *n, **pn;
22819370Spst
22919370Spst	  n = ((struct stab_section_list *)
23019370Spst	       xmalloc (sizeof (struct stab_section_list)));
23119370Spst	  n->section = sectp;
23219370Spst	  n->next = NULL;
23319370Spst	  for (pn = &csi->stabsects; *pn != NULL; pn = &(*pn)->next)
23419370Spst	    ;
23519370Spst	  *pn = n;
23619370Spst
23719370Spst	  /* This will be run after coffstab_build_psymtabs is called
23898948Sobrien	     in coff_symfile_read, at which point we no longer need
23998948Sobrien	     the information.  */
24098948Sobrien	  make_cleanup (xfree, n);
24119370Spst	}
24219370Spst    }
24319370Spst}
24419370Spst
24519370Spst/* Return the section_offsets* that CS points to.  */
24698948Sobrienstatic int cs_to_section (struct coff_symbol *, struct objfile *);
24719370Spst
24898948Sobrienstruct find_targ_sec_arg
24998948Sobrien  {
25098948Sobrien    int targ_index;
25198948Sobrien    asection **resultp;
25298948Sobrien  };
25319370Spst
25498948Sobrienstatic void
25598948Sobrienfind_targ_sec (bfd *abfd, asection *sect, void *obj)
25619370Spst{
25798948Sobrien  struct find_targ_sec_arg *args = (struct find_targ_sec_arg *) obj;
25819370Spst  if (sect->target_index == args->targ_index)
25946283Sdfr    *args->resultp = sect;
26019370Spst}
26119370Spst
26219370Spst/* Return the section number (SECT_OFF_*) that CS points to.  */
26319370Spststatic int
26498948Sobriencs_to_section (struct coff_symbol *cs, struct objfile *objfile)
26519370Spst{
26646283Sdfr  asection *sect = NULL;
26746283Sdfr  struct find_targ_sec_arg args;
26898948Sobrien  int off = SECT_OFF_TEXT (objfile);
26946283Sdfr
27019370Spst  args.targ_index = cs->c_secnum;
27146283Sdfr  args.resultp = &sect;
27219370Spst  bfd_map_over_sections (objfile->obfd, find_targ_sec, &args);
27346283Sdfr  if (sect != NULL)
27446283Sdfr    {
27546283Sdfr      /* This is the section.  Figure out what SECT_OFF_* code it is.  */
27646283Sdfr      if (bfd_get_section_flags (abfd, sect) & SEC_CODE)
27798948Sobrien	off = SECT_OFF_TEXT (objfile);
27846283Sdfr      else if (bfd_get_section_flags (abfd, sect) & SEC_LOAD)
27998948Sobrien	off = SECT_OFF_DATA (objfile);
28046283Sdfr      else
28198948Sobrien	/* Just return the bfd section index. */
28298948Sobrien	off = sect->index;
28346283Sdfr    }
28419370Spst  return off;
28519370Spst}
28619370Spst
28746283Sdfr/* Return the address of the section of a COFF symbol.  */
28846283Sdfr
28998948Sobrienstatic CORE_ADDR cs_section_address (struct coff_symbol *, bfd *);
29046283Sdfr
29146283Sdfrstatic CORE_ADDR
29298948Sobriencs_section_address (struct coff_symbol *cs, bfd *abfd)
29346283Sdfr{
29446283Sdfr  asection *sect = NULL;
29546283Sdfr  struct find_targ_sec_arg args;
29646283Sdfr  CORE_ADDR addr = 0;
29746283Sdfr
29846283Sdfr  args.targ_index = cs->c_secnum;
29946283Sdfr  args.resultp = &sect;
30046283Sdfr  bfd_map_over_sections (abfd, find_targ_sec, &args);
30146283Sdfr  if (sect != NULL)
30246283Sdfr    addr = bfd_get_section_vma (objfile->obfd, sect);
30346283Sdfr  return addr;
30446283Sdfr}
30546283Sdfr
30619370Spst/* Look up a coff type-number index.  Return the address of the slot
30719370Spst   where the type for that index is stored.
30819370Spst   The type-number is in INDEX.
30919370Spst
31019370Spst   This can be used for finding the type associated with that index
31119370Spst   or for associating a new type with the index.  */
31219370Spst
31319370Spststatic struct type **
314130809Smarcelcoff_lookup_type (int index)
31519370Spst{
31619370Spst  if (index >= type_vector_length)
31719370Spst    {
31819370Spst      int old_vector_length = type_vector_length;
31919370Spst
32019370Spst      type_vector_length *= 2;
32198948Sobrien      if (index /* is still */  >= type_vector_length)
32219370Spst	type_vector_length = index * 2;
32319370Spst
32419370Spst      type_vector = (struct type **)
32519370Spst	xrealloc ((char *) type_vector,
32619370Spst		  type_vector_length * sizeof (struct type *));
32719370Spst      memset (&type_vector[old_vector_length], 0,
32898948Sobrien	 (type_vector_length - old_vector_length) * sizeof (struct type *));
32919370Spst    }
33019370Spst  return &type_vector[index];
33119370Spst}
33219370Spst
33319370Spst/* Make sure there is a type allocated for type number index
33419370Spst   and return the type object.
33519370Spst   This can create an empty (zeroed) type object.  */
33619370Spst
33719370Spststatic struct type *
33898948Sobriencoff_alloc_type (int index)
33919370Spst{
340130809Smarcel  struct type **type_addr = coff_lookup_type (index);
341130809Smarcel  struct type *type = *type_addr;
34219370Spst
34319370Spst  /* If we are referring to a type not known at all yet,
34419370Spst     allocate an empty type for it.
34519370Spst     We will fill it in later if we find out how.  */
34619370Spst  if (type == NULL)
34719370Spst    {
34819370Spst      type = alloc_type (current_objfile);
34919370Spst      *type_addr = type;
35019370Spst    }
35119370Spst  return type;
35219370Spst}
35319370Spst
35419370Spst/* Start a new symtab for a new source file.
35519370Spst   This is called when a COFF ".file" symbol is seen;
35619370Spst   it indicates the start of data for one original source file.  */
35719370Spst
35819370Spststatic void
35998948Sobriencoff_start_symtab (char *name)
36019370Spst{
36119370Spst  start_symtab (
36298948Sobrien  /* We fill in the filename later.  start_symtab puts
36398948Sobrien     this pointer into last_source_file and we put it in
36498948Sobrien     subfiles->name, which end_symtab frees; that's why
36598948Sobrien     it must be malloc'd.  */
36698948Sobrien		 savestring (name, strlen (name)),
36798948Sobrien  /* We never know the directory name for COFF.  */
36898948Sobrien		 NULL,
36998948Sobrien  /* The start address is irrelevant, since we set
37098948Sobrien     last_source_start_addr in coff_end_symtab.  */
37198948Sobrien		 0);
37246283Sdfr  record_debugformat ("COFF");
37319370Spst}
37419370Spst
37519370Spst/* Save the vital information from when starting to read a file,
37619370Spst   for use when closing off the current file.
37719370Spst   NAME is the file name the symbols came from, START_ADDR is the first
37819370Spst   text address for the file, and SIZE is the number of bytes of text.  */
37919370Spst
38019370Spststatic void
38198948Sobriencomplete_symtab (char *name, CORE_ADDR start_addr, unsigned int size)
38219370Spst{
38319370Spst  if (last_source_file != NULL)
38498948Sobrien    xfree (last_source_file);
38519370Spst  last_source_file = savestring (name, strlen (name));
38619370Spst  current_source_start_addr = start_addr;
38719370Spst  current_source_end_addr = start_addr + size;
38819370Spst
38998948Sobrien  if (current_objfile->ei.entry_point >= current_source_start_addr &&
39098948Sobrien      current_objfile->ei.entry_point < current_source_end_addr)
39119370Spst    {
392130809Smarcel      current_objfile->ei.deprecated_entry_file_lowpc = current_source_start_addr;
393130809Smarcel      current_objfile->ei.deprecated_entry_file_highpc = current_source_end_addr;
39419370Spst    }
39519370Spst}
39619370Spst
39719370Spst/* Finish the symbol definitions for one main source file,
39819370Spst   close off all the lexical contexts for that file
39919370Spst   (creating struct block's for them), then make the
40019370Spst   struct symtab for that file and put it in the list of all such. */
40119370Spst
40219370Spststatic void
40398948Sobriencoff_end_symtab (struct objfile *objfile)
40419370Spst{
40519370Spst  struct symtab *symtab;
40619370Spst
40719370Spst  last_source_start_addr = current_source_start_addr;
40819370Spst
40998948Sobrien  symtab = end_symtab (current_source_end_addr, objfile, SECT_OFF_TEXT (objfile));
41019370Spst
41119370Spst  if (symtab != NULL)
41219370Spst    free_named_symtabs (symtab->filename);
41319370Spst
41419370Spst  /* Reinitialize for beginning of new file. */
41519370Spst  last_source_file = NULL;
41619370Spst}
41719370Spst
41819370Spststatic void
41998948Sobrienrecord_minimal_symbol (char *name, CORE_ADDR address,
42098948Sobrien		       enum minimal_symbol_type type, struct objfile *objfile)
42119370Spst{
42219370Spst  /* We don't want TDESC entry points in the minimal symbol table */
42398948Sobrien  if (name[0] == '@')
42498948Sobrien    return;
42519370Spst
42646283Sdfr  prim_record_minimal_symbol (name, address, type, objfile);
42719370Spst}
42819370Spst
42919370Spst/* coff_symfile_init ()
43019370Spst   is the coff-specific initialization routine for reading symbols.
43119370Spst   It is passed a struct objfile which contains, among other things,
43219370Spst   the BFD for the file whose symbols are being read, and a slot for
43319370Spst   a pointer to "private data" which we fill with cookies and other
43419370Spst   treats for coff_symfile_read ().
43519370Spst
43619370Spst   We will only be called if this is a COFF or COFF-like file.
43719370Spst   BFD handles figuring out the format of the file, and code in symtab.c
43819370Spst   uses BFD's determination to vector to us.
43919370Spst
44019370Spst   The ultimate result is a new symtab (or, FIXME, eventually a psymtab).  */
44119370Spst
44219370Spststatic void
44398948Sobriencoff_symfile_init (struct objfile *objfile)
44419370Spst{
44519370Spst  /* Allocate struct to keep track of stab reading. */
44646283Sdfr  objfile->sym_stab_info = (struct dbx_symfile_info *)
44719370Spst    xmmalloc (objfile->md, sizeof (struct dbx_symfile_info));
44819370Spst
44998948Sobrien  memset (objfile->sym_stab_info, 0,
45098948Sobrien	  sizeof (struct dbx_symfile_info));
45119370Spst
45219370Spst  /* Allocate struct to keep track of the symfile */
45319370Spst  objfile->sym_private = xmmalloc (objfile->md,
45419370Spst				   sizeof (struct coff_symfile_info));
45519370Spst
45619370Spst  memset (objfile->sym_private, 0, sizeof (struct coff_symfile_info));
45719370Spst
45819370Spst  /* COFF objects may be reordered, so set OBJF_REORDERED.  If we
45919370Spst     find this causes a significant slowdown in gdb then we could
46019370Spst     set it in the debug symbol readers only when necessary.  */
46119370Spst  objfile->flags |= OBJF_REORDERED;
46219370Spst
46319370Spst  init_entry_point_info (objfile);
46419370Spst}
46519370Spst
46619370Spst/* This function is called for every section; it finds the outer limits
46719370Spst   of the line table (minimum and maximum file offset) so that the
46819370Spst   mainline code can read the whole thing for efficiency.  */
46919370Spst
47019370Spststatic void
471130809Smarcelfind_linenos (bfd *abfd, struct bfd_section *asect, void *vpinfo)
47219370Spst{
47319370Spst  struct coff_symfile_info *info;
47419370Spst  int size, count;
47519370Spst  file_ptr offset, maxoff;
47619370Spst
47719370Spst/* WARNING WILL ROBINSON!  ACCESSING BFD-PRIVATE DATA HERE!  FIXME!  */
47819370Spst  count = asect->lineno_count;
47919370Spst/* End of warning */
48019370Spst
48119370Spst  if (count == 0)
48219370Spst    return;
48319370Spst  size = count * local_linesz;
48419370Spst
48598948Sobrien  info = (struct coff_symfile_info *) vpinfo;
48619370Spst/* WARNING WILL ROBINSON!  ACCESSING BFD-PRIVATE DATA HERE!  FIXME!  */
48719370Spst  offset = asect->line_filepos;
48819370Spst/* End of warning */
48919370Spst
49019370Spst  if (offset < info->min_lineno_offset || info->min_lineno_offset == 0)
49119370Spst    info->min_lineno_offset = offset;
49219370Spst
49319370Spst  maxoff = offset + size;
49419370Spst  if (maxoff > info->max_lineno_offset)
49519370Spst    info->max_lineno_offset = maxoff;
49619370Spst}
49719370Spst
49819370Spst
49919370Spst/* The BFD for this file -- only good while we're actively reading
50019370Spst   symbols into a psymtab or a symtab.  */
50119370Spst
50219370Spststatic bfd *symfile_bfd;
50319370Spst
50419370Spst/* Read a symbol file, after initialization by coff_symfile_init.  */
50519370Spst
50619370Spststatic void
50798948Sobriencoff_symfile_read (struct objfile *objfile, int mainline)
50819370Spst{
50919370Spst  struct coff_symfile_info *info;
51019370Spst  struct dbx_symfile_info *dbxinfo;
51119370Spst  bfd *abfd = objfile->obfd;
51219370Spst  coff_data_type *cdata = coff_data (abfd);
51319370Spst  char *name = bfd_get_filename (abfd);
514130809Smarcel  int val;
51598948Sobrien  unsigned int num_symbols;
51619370Spst  int symtab_offset;
51719370Spst  int stringtab_offset;
518130809Smarcel  struct cleanup *back_to, *cleanup_minimal_symbols;
51919370Spst  int stabstrsize;
52098948Sobrien  int len;
52198948Sobrien  char * target;
52298948Sobrien
52398948Sobrien  info = (struct coff_symfile_info *) objfile->sym_private;
52446283Sdfr  dbxinfo = objfile->sym_stab_info;
52598948Sobrien  symfile_bfd = abfd;		/* Kludge for swap routines */
52619370Spst
52719370Spst/* WARNING WILL ROBINSON!  ACCESSING BFD-PRIVATE DATA HERE!  FIXME!  */
52898948Sobrien  num_symbols = bfd_get_symcount (abfd);	/* How many syms */
52998948Sobrien  symtab_offset = cdata->sym_filepos;	/* Symbol table file offset */
53098948Sobrien  stringtab_offset = symtab_offset +	/* String table file offset */
53198948Sobrien    num_symbols * cdata->local_symesz;
53219370Spst
53319370Spst  /* Set a few file-statics that give us specific information about
53419370Spst     the particular COFF file format we're reading.  */
53519370Spst  local_n_btmask = cdata->local_n_btmask;
53619370Spst  local_n_btshft = cdata->local_n_btshft;
53798948Sobrien  local_n_tmask = cdata->local_n_tmask;
53819370Spst  local_n_tshift = cdata->local_n_tshift;
53998948Sobrien  local_linesz = cdata->local_linesz;
54098948Sobrien  local_symesz = cdata->local_symesz;
54198948Sobrien  local_auxesz = cdata->local_auxesz;
54219370Spst
54319370Spst  /* Allocate space for raw symbol and aux entries, based on their
54419370Spst     space requirements as reported by BFD.  */
54519370Spst  temp_sym = (char *) xmalloc
54698948Sobrien    (cdata->local_symesz + cdata->local_auxesz);
54719370Spst  temp_aux = temp_sym + cdata->local_symesz;
54898948Sobrien  back_to = make_cleanup (free_current_contents, &temp_sym);
54946283Sdfr
55046283Sdfr  /* We need to know whether this is a PE file, because in PE files,
55146283Sdfr     unlike standard COFF files, symbol values are stored as offsets
55246283Sdfr     from the section address, rather than as absolute addresses.
55346283Sdfr     FIXME: We should use BFD to read the symbol table, and thus avoid
55446283Sdfr     this problem.  */
55598948Sobrien  pe_file =
55698948Sobrien    strncmp (bfd_get_target (objfile->obfd), "pe", 2) == 0
55798948Sobrien    || strncmp (bfd_get_target (objfile->obfd), "epoc-pe", 7) == 0;
55846283Sdfr
55919370Spst/* End of warning */
56019370Spst
56119370Spst  info->min_lineno_offset = 0;
56219370Spst  info->max_lineno_offset = 0;
56319370Spst
564130809Smarcel  /* Only read line number information if we have symbols.
56519370Spst
566130809Smarcel     On Windows NT, some of the system's DLL's have sections with
567130809Smarcel     PointerToLinenumbers fields that are non-zero, but point at
568130809Smarcel     random places within the image file.  (In the case I found,
569130809Smarcel     KERNEL32.DLL's .text section has a line number info pointer that
570130809Smarcel     points into the middle of the string `lib\\i386\kernel32.dll'.)
571130809Smarcel
572130809Smarcel     However, these DLL's also have no symbols.  The line number
573130809Smarcel     tables are meaningless without symbols.  And in fact, GDB never
574130809Smarcel     uses the line number information unless there are symbols.  So we
575130809Smarcel     can avoid spurious error messages (and maybe run a little
576130809Smarcel     faster!) by not even reading the line number table unless we have
577130809Smarcel     symbols.  */
578130809Smarcel  if (num_symbols > 0)
579130809Smarcel    {
580130809Smarcel      /* Read the line number table, all at once.  */
581130809Smarcel      bfd_map_over_sections (abfd, find_linenos, (void *) info);
582130809Smarcel
583130809Smarcel      make_cleanup (free_linetab_cleanup, 0 /*ignore*/);
584130809Smarcel      val = init_lineno (abfd, info->min_lineno_offset,
585130809Smarcel                         info->max_lineno_offset - info->min_lineno_offset);
586130809Smarcel      if (val < 0)
587130809Smarcel        error ("\"%s\": error reading line numbers\n", name);
588130809Smarcel    }
589130809Smarcel
59019370Spst  /* Now read the string table, all at once.  */
59119370Spst
59298948Sobrien  make_cleanup (free_stringtab_cleanup, 0 /*ignore*/);
59319370Spst  val = init_stringtab (abfd, stringtab_offset);
59419370Spst  if (val < 0)
59519370Spst    error ("\"%s\": can't get string table", name);
59619370Spst
59719370Spst  init_minimal_symbol_collection ();
598130809Smarcel  cleanup_minimal_symbols = make_cleanup_discard_minimal_symbols ();
59919370Spst
60019370Spst  /* Now that the executable file is positioned at symbol table,
60119370Spst     process it and define symbols accordingly.  */
60219370Spst
60398948Sobrien  coff_symtab_read ((long) symtab_offset, num_symbols, objfile);
60419370Spst
60519370Spst  /* Install any minimal symbols that have been collected as the current
60619370Spst     minimal symbols for this objfile.  */
60719370Spst
60819370Spst  install_minimal_symbols (objfile);
60919370Spst
610130809Smarcel  /* Free the installed minimal symbol data.  */
611130809Smarcel  do_cleanups (cleanup_minimal_symbols);
612130809Smarcel
61398948Sobrien  bfd_map_over_sections (abfd, coff_locate_sections, (void *) info);
61419370Spst
61519370Spst  if (info->stabsects)
61619370Spst    {
61798948Sobrien      if (!info->stabstrsect)
61898948Sobrien	{
61998948Sobrien	  error (("The debugging information in `%s' is corrupted.\n"
62098948Sobrien		  "The file has a `.stabs' section, but no `.stabstr' "
62198948Sobrien		  "section."),
62298948Sobrien		 name);
62398948Sobrien	}
62498948Sobrien
62519370Spst      /* FIXME: dubious.  Why can't we use something normal like
62698948Sobrien         bfd_get_section_contents?  */
62719370Spst      bfd_seek (abfd, abfd->where, 0);
62819370Spst
62919370Spst      stabstrsize = bfd_section_size (abfd, info->stabstrsect);
63019370Spst
63119370Spst      coffstab_build_psymtabs (objfile,
63219370Spst			       mainline,
63319370Spst			       info->textaddr, info->textsize,
63419370Spst			       info->stabsects,
63519370Spst			       info->stabstrsect->filepos, stabstrsize);
63619370Spst    }
63798948Sobrien  if (dwarf2_has_info (abfd))
63898948Sobrien    {
63998948Sobrien      /* DWARF2 sections.  */
64098948Sobrien      dwarf2_build_psymtabs (objfile, mainline);
64198948Sobrien    }
64219370Spst
64319370Spst  do_cleanups (back_to);
64419370Spst}
64519370Spst
64619370Spststatic void
64798948Sobriencoff_new_init (struct objfile *ignore)
64819370Spst{
64919370Spst}
65019370Spst
65119370Spst/* Perform any local cleanups required when we are done with a particular
65219370Spst   objfile.  I.E, we are in the process of discarding all symbol information
65319370Spst   for an objfile, freeing up all memory held for it, and unlinking the
65419370Spst   objfile struct from the global list of known objfiles. */
65519370Spst
65619370Spststatic void
65798948Sobriencoff_symfile_finish (struct objfile *objfile)
65819370Spst{
65998948Sobrien  if (objfile->sym_private != NULL)
66019370Spst    {
66198948Sobrien      xmfree (objfile->md, objfile->sym_private);
66219370Spst    }
66398948Sobrien
66498948Sobrien  /* Let stabs reader clean up */
66598948Sobrien  stabsread_clear_cache ();
66619370Spst}
66798948Sobrien
66819370Spst
66919370Spst/* Given pointers to a symbol table in coff style exec file,
67019370Spst   analyze them and create struct symtab's describing the symbols.
67119370Spst   NSYMS is the number of symbols in the symbol table.
67219370Spst   We read them one at a time using read_one_sym ().  */
67319370Spst
67419370Spststatic void
67598948Sobriencoff_symtab_read (long symtab_offset, unsigned int nsyms,
67698948Sobrien		  struct objfile *objfile)
67719370Spst{
678130809Smarcel  struct context_stack *new;
67919370Spst  struct coff_symbol coff_symbol;
680130809Smarcel  struct coff_symbol *cs = &coff_symbol;
68119370Spst  static struct internal_syment main_sym;
68219370Spst  static union internal_auxent main_aux;
68319370Spst  struct coff_symbol fcn_cs_saved;
68419370Spst  static struct internal_syment fcn_sym_saved;
68519370Spst  static union internal_auxent fcn_aux_saved;
68619370Spst  struct symtab *s;
68719370Spst  /* A .file is open.  */
68819370Spst  int in_source_file = 0;
68919370Spst  int next_file_symnum = -1;
69019370Spst  /* Name of the current file.  */
69119370Spst  char *filestring = "";
69219370Spst  int depth = 0;
69319370Spst  int fcn_first_line = 0;
69498948Sobrien  CORE_ADDR fcn_first_line_addr = 0;
69519370Spst  int fcn_last_line = 0;
69619370Spst  int fcn_start_addr = 0;
69719370Spst  long fcn_line_ptr = 0;
69819370Spst  int val;
69919370Spst  CORE_ADDR tmpaddr;
70019370Spst
70119370Spst  /* Work around a stdio bug in SunOS4.1.1 (this makes me nervous....
70219370Spst     it's hard to know I've really worked around it.  The fix should be
70319370Spst     harmless, anyway).  The symptom of the bug is that the first
70419370Spst     fread (in read_one_sym), will (in my example) actually get data
70519370Spst     from file offset 268, when the fseek was to 264 (and ftell shows
70619370Spst     264).  This causes all hell to break loose.  I was unable to
70719370Spst     reproduce this on a short test program which operated on the same
70819370Spst     file, performing (I think) the same sequence of operations.
70919370Spst
71019370Spst     It stopped happening when I put in this (former) rewind().
71119370Spst
71219370Spst     FIXME: Find out if this has been reported to Sun, whether it has
71319370Spst     been fixed in a later release, etc.  */
71419370Spst
71519370Spst  bfd_seek (objfile->obfd, 0, 0);
71619370Spst
71719370Spst  /* Position to read the symbol table. */
71819370Spst  val = bfd_seek (objfile->obfd, (long) symtab_offset, 0);
71919370Spst  if (val < 0)
72019370Spst    perror_with_name (objfile->name);
72119370Spst
72219370Spst  current_objfile = objfile;
72319370Spst  nlist_bfd_global = objfile->obfd;
72419370Spst  nlist_nsyms_global = nsyms;
72519370Spst  last_source_file = NULL;
72619370Spst  memset (opaque_type_chain, 0, sizeof opaque_type_chain);
72719370Spst
72898948Sobrien  if (type_vector)		/* Get rid of previous one */
72998948Sobrien    xfree (type_vector);
73019370Spst  type_vector_length = 160;
73119370Spst  type_vector = (struct type **)
73219370Spst    xmalloc (type_vector_length * sizeof (struct type *));
73319370Spst  memset (type_vector, 0, type_vector_length * sizeof (struct type *));
73419370Spst
73546283Sdfr  coff_start_symtab ("");
73619370Spst
73719370Spst  symnum = 0;
73819370Spst  while (symnum < nsyms)
73919370Spst    {
74019370Spst      QUIT;			/* Make this command interruptable.  */
74119370Spst
74219370Spst      read_one_sym (cs, &main_sym, &main_aux);
74319370Spst
74419370Spst      if (cs->c_symnum == next_file_symnum && cs->c_sclass != C_FILE)
74519370Spst	{
74619370Spst	  if (last_source_file)
74719370Spst	    coff_end_symtab (objfile);
74819370Spst
74946283Sdfr	  coff_start_symtab ("_globals_");
75019370Spst	  complete_symtab ("_globals_", 0, 0);
75119370Spst	  /* done with all files, everything from here on out is globals */
75219370Spst	}
75319370Spst
75419370Spst      /* Special case for file with type declarations only, no text.  */
75519370Spst      if (!last_source_file && SDB_TYPE (cs->c_type)
75619370Spst	  && cs->c_secnum == N_DEBUG)
75719370Spst	complete_symtab (filestring, 0, 0);
75819370Spst
75919370Spst      /* Typedefs should not be treated as symbol definitions.  */
76019370Spst      if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF)
76119370Spst	{
76219370Spst	  /* Record all functions -- external and static -- in minsyms. */
76398948Sobrien	  tmpaddr = cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
76419370Spst	  record_minimal_symbol (cs->c_name, tmpaddr, mst_text, objfile);
76519370Spst
76619370Spst	  fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
76719370Spst	  fcn_start_addr = tmpaddr;
76819370Spst	  fcn_cs_saved = *cs;
76919370Spst	  fcn_sym_saved = main_sym;
77019370Spst	  fcn_aux_saved = main_aux;
77119370Spst	  continue;
77219370Spst	}
77319370Spst
77419370Spst      switch (cs->c_sclass)
77519370Spst	{
77698948Sobrien	case C_EFCN:
77798948Sobrien	case C_EXTDEF:
77898948Sobrien	case C_ULABEL:
77998948Sobrien	case C_USTATIC:
78098948Sobrien	case C_LINE:
78198948Sobrien	case C_ALIAS:
78298948Sobrien	case C_HIDDEN:
783130809Smarcel	  complaint (&symfile_complaints, "Bad n_sclass for symbol %s",
784130809Smarcel		     cs->c_name);
78598948Sobrien	  break;
78619370Spst
78798948Sobrien	case C_FILE:
78898948Sobrien	  /* c_value field contains symnum of next .file entry in table
78998948Sobrien	     or symnum of first global after last .file.  */
79098948Sobrien	  next_file_symnum = cs->c_value;
79198948Sobrien	  if (cs->c_naux > 0)
79298948Sobrien	    filestring = coff_getfilename (&main_aux);
79398948Sobrien	  else
79498948Sobrien	    filestring = "";
79519370Spst
79698948Sobrien	  /* Complete symbol table for last object file
79798948Sobrien	     containing debugging information.  */
79898948Sobrien	  if (last_source_file)
79998948Sobrien	    {
80098948Sobrien	      coff_end_symtab (objfile);
80198948Sobrien	      coff_start_symtab (filestring);
80298948Sobrien	    }
80398948Sobrien	  in_source_file = 1;
80498948Sobrien	  break;
80519370Spst
80646283Sdfr	  /* C_LABEL is used for labels and static functions.  Including
80746283Sdfr	     it here allows gdb to see static functions when no debug
80846283Sdfr	     info is available.  */
80998948Sobrien	case C_LABEL:
81098948Sobrien	  /* However, labels within a function can make weird backtraces,
81198948Sobrien	     so filter them out (from phdm@macqel.be). */
81298948Sobrien	  if (within_function)
81398948Sobrien	    break;
81498948Sobrien	case C_STAT:
81598948Sobrien	case C_THUMBLABEL:
81698948Sobrien	case C_THUMBSTAT:
81798948Sobrien	case C_THUMBSTATFUNC:
81898948Sobrien	  if (cs->c_name[0] == '.')
81998948Sobrien	    {
820130809Smarcel	      if (DEPRECATED_STREQ (cs->c_name, ".text"))
82198948Sobrien		{
82219370Spst		  /* FIXME:  don't wire in ".text" as section name
82319370Spst		     or symbol name! */
82419370Spst		  /* Check for in_source_file deals with case of
82519370Spst		     a file with debugging symbols
82619370Spst		     followed by a later file with no symbols.  */
82719370Spst		  if (in_source_file)
82819370Spst		    complete_symtab (filestring,
82998948Sobrien		    cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)),
83019370Spst				     main_aux.x_scn.x_scnlen);
83119370Spst		  in_source_file = 0;
83219370Spst		}
83398948Sobrien	      /* flush rest of '.' symbols */
83419370Spst	      break;
83519370Spst	    }
83698948Sobrien	  else if (!SDB_TYPE (cs->c_type)
83798948Sobrien		   && cs->c_name[0] == 'L'
83898948Sobrien		   && (strncmp (cs->c_name, "LI%", 3) == 0
83998948Sobrien		       || strncmp (cs->c_name, "LF%", 3) == 0
84098948Sobrien		       || strncmp (cs->c_name, "LC%", 3) == 0
84198948Sobrien		       || strncmp (cs->c_name, "LP%", 3) == 0
84298948Sobrien		       || strncmp (cs->c_name, "LPB%", 4) == 0
84398948Sobrien		       || strncmp (cs->c_name, "LBB%", 4) == 0
84498948Sobrien		       || strncmp (cs->c_name, "LBE%", 4) == 0
84598948Sobrien		       || strncmp (cs->c_name, "LPBX%", 5) == 0))
84698948Sobrien	    /* At least on a 3b1, gcc generates swbeg and string labels
84798948Sobrien	       that look like this.  Ignore them.  */
84819370Spst	    break;
84998948Sobrien	  /* fall in for static symbols that don't start with '.' */
85098948Sobrien	case C_THUMBEXT:
85198948Sobrien	case C_THUMBEXTFUNC:
85298948Sobrien	case C_EXT:
85398948Sobrien	  {
85498948Sobrien	    /* Record it in the minimal symbols regardless of
85598948Sobrien	       SDB_TYPE.  This parallels what we do for other debug
85698948Sobrien	       formats, and probably is needed to make
85798948Sobrien	       print_address_symbolic work right without the (now
85898948Sobrien	       gone) "set fast-symbolic-addr off" kludge.  */
85919370Spst
86098948Sobrien	    enum minimal_symbol_type ms_type;
86198948Sobrien	    int sec;
86219370Spst
86398948Sobrien	    if (cs->c_secnum == N_UNDEF)
86419370Spst	      {
86598948Sobrien		/* This is a common symbol.  See if the target
86698948Sobrien		   environment knows where it has been relocated to.  */
86798948Sobrien		CORE_ADDR reladdr;
86898948Sobrien		if (target_lookup_symbol (cs->c_name, &reladdr))
86998948Sobrien		  {
87098948Sobrien		    /* Error in lookup; ignore symbol.  */
87119370Spst		    break;
87219370Spst		  }
87398948Sobrien		tmpaddr = reladdr;
87498948Sobrien		/* The address has already been relocated; make sure that
87598948Sobrien		   objfile_relocate doesn't relocate it again.  */
87698948Sobrien		sec = -2;
87798948Sobrien		ms_type = cs->c_sclass == C_EXT
87898948Sobrien		  || cs->c_sclass == C_THUMBEXT ?
87998948Sobrien		  mst_bss : mst_file_bss;
88098948Sobrien	      }
881130809Smarcel 	    else if (cs->c_secnum == N_ABS)
882130809Smarcel 	      {
883130809Smarcel 		/* Use the correct minimal symbol type (and don't
884130809Smarcel 		   relocate) for absolute values. */
885130809Smarcel 		ms_type = mst_abs;
886130809Smarcel 		sec = cs_to_section (cs, objfile);
887130809Smarcel 		tmpaddr = cs->c_value;
888130809Smarcel 	      }
88998948Sobrien	    else
89098948Sobrien	      {
89198948Sobrien		sec = cs_to_section (cs, objfile);
89298948Sobrien		tmpaddr = cs->c_value;
893130809Smarcel 		/* Statics in a PE file also get relocated */
894130809Smarcel 		if (cs->c_sclass == C_EXT
895130809Smarcel 		    || cs->c_sclass == C_THUMBEXTFUNC
896130809Smarcel 		    || cs->c_sclass == C_THUMBEXT
897130809Smarcel 		    || (pe_file && (cs->c_sclass == C_STAT)))
89898948Sobrien		  tmpaddr += ANOFFSET (objfile->section_offsets, sec);
89919370Spst
90098948Sobrien		if (sec == SECT_OFF_TEXT (objfile))
90119370Spst		  {
90298948Sobrien		    ms_type =
90398948Sobrien		      cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC
90498948Sobrien		      || cs->c_sclass == C_THUMBEXT ?
90598948Sobrien		      mst_text : mst_file_text;
90698948Sobrien		    tmpaddr = SMASH_TEXT_ADDRESS (tmpaddr);
90719370Spst		  }
90898948Sobrien		else if (sec == SECT_OFF_DATA (objfile))
90919370Spst		  {
91098948Sobrien		    ms_type =
91198948Sobrien		      cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT ?
91298948Sobrien		      mst_data : mst_file_data;
91319370Spst		  }
91498948Sobrien		else if (sec == SECT_OFF_BSS (objfile))
91519370Spst		  {
91698948Sobrien		    ms_type =
91798948Sobrien		      cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT ?
91898948Sobrien		      mst_data : mst_file_data;
91919370Spst		  }
92098948Sobrien		else
92198948Sobrien		  ms_type = mst_unknown;
92298948Sobrien	      }
92398948Sobrien
92498948Sobrien	    if (cs->c_name[0] != '@' /* Skip tdesc symbols */ )
92598948Sobrien	      {
92698948Sobrien		struct minimal_symbol *msym;
92798948Sobrien		msym = prim_record_minimal_symbol_and_info
928130809Smarcel		  (cs->c_name, tmpaddr, ms_type, NULL,
92998948Sobrien		   sec, NULL, objfile);
93098948Sobrien		if (msym)
93198948Sobrien		  COFF_MAKE_MSYMBOL_SPECIAL (cs->c_sclass, msym);
93298948Sobrien	      }
93398948Sobrien	    if (SDB_TYPE (cs->c_type))
93498948Sobrien	      {
93598948Sobrien		struct symbol *sym;
93698948Sobrien		sym = process_coff_symbol
93798948Sobrien		  (cs, &main_aux, objfile);
93898948Sobrien		SYMBOL_VALUE (sym) = tmpaddr;
93998948Sobrien		SYMBOL_SECTION (sym) = sec;
94098948Sobrien	      }
94198948Sobrien	  }
94298948Sobrien	  break;
94398948Sobrien
94498948Sobrien	case C_FCN:
945130809Smarcel	  if (DEPRECATED_STREQ (cs->c_name, ".bf"))
94698948Sobrien	    {
94798948Sobrien	      within_function = 1;
94898948Sobrien
94998948Sobrien	      /* value contains address of first non-init type code */
95098948Sobrien	      /* main_aux.x_sym.x_misc.x_lnsz.x_lnno
95198948Sobrien	         contains line number of '{' } */
95298948Sobrien	      if (cs->c_naux != 1)
953130809Smarcel		complaint (&symfile_complaints,
954130809Smarcel			   "`.bf' symbol %d has no aux entry", cs->c_symnum);
95598948Sobrien	      fcn_first_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;
95698948Sobrien	      fcn_first_line_addr = cs->c_value;
95798948Sobrien
95898948Sobrien	      /* Might want to check that locals are 0 and
95998948Sobrien	         context_stack_depth is zero, and complain if not.  */
96098948Sobrien
96198948Sobrien	      depth = 0;
96298948Sobrien	      new = push_context (depth, fcn_start_addr);
96398948Sobrien	      fcn_cs_saved.c_name = getsymname (&fcn_sym_saved);
96498948Sobrien	      new->name =
96598948Sobrien		process_coff_symbol (&fcn_cs_saved, &fcn_aux_saved, objfile);
96698948Sobrien	    }
967130809Smarcel	  else if (DEPRECATED_STREQ (cs->c_name, ".ef"))
96898948Sobrien	    {
96998948Sobrien	      if (!within_function)
97098948Sobrien		error ("Bad coff function information\n");
97198948Sobrien	      /* the value of .ef is the address of epilogue code;
97298948Sobrien	         not useful for gdb.  */
97398948Sobrien	      /* { main_aux.x_sym.x_misc.x_lnsz.x_lnno
97498948Sobrien	         contains number of lines to '}' */
97598948Sobrien
97698948Sobrien	      if (context_stack_depth <= 0)
97798948Sobrien		{		/* We attempted to pop an empty context stack */
978130809Smarcel		  complaint (&symfile_complaints,
979130809Smarcel			     "`.ef' symbol without matching `.bf' symbol ignored starting at symnum %d",
980130809Smarcel			     cs->c_symnum);
98198948Sobrien		  within_function = 0;
98298948Sobrien		  break;
98398948Sobrien		}
98498948Sobrien
98598948Sobrien	      new = pop_context ();
98698948Sobrien	      /* Stack must be empty now.  */
98798948Sobrien	      if (context_stack_depth > 0 || new == NULL)
98898948Sobrien		{
989130809Smarcel		  complaint (&symfile_complaints,
990130809Smarcel			     "Unmatched .ef symbol(s) ignored starting at symnum %d",
991130809Smarcel			     cs->c_symnum);
99298948Sobrien		  within_function = 0;
99398948Sobrien		  break;
99498948Sobrien		}
99598948Sobrien	      if (cs->c_naux != 1)
99698948Sobrien		{
997130809Smarcel		  complaint (&symfile_complaints,
998130809Smarcel			     "`.ef' symbol %d has no aux entry", cs->c_symnum);
99998948Sobrien		  fcn_last_line = 0x7FFFFFFF;
100098948Sobrien		}
100198948Sobrien	      else
100298948Sobrien		{
100398948Sobrien		  fcn_last_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;
100498948Sobrien		}
100598948Sobrien	      /* fcn_first_line is the line number of the opening '{'.
100698948Sobrien	         Do not record it - because it would affect gdb's idea
100798948Sobrien	         of the line number of the first statement of the function -
100898948Sobrien	         except for one-line functions, for which it is also the line
100998948Sobrien	         number of all the statements and of the closing '}', and
101098948Sobrien	         for which we do not have any other statement-line-number. */
101198948Sobrien	      if (fcn_last_line == 1)
101298948Sobrien		record_line (current_subfile, fcn_first_line,
101398948Sobrien			     fcn_first_line_addr);
101498948Sobrien	      else
101519370Spst		enter_linenos (fcn_line_ptr, fcn_first_line, fcn_last_line,
101698948Sobrien			       objfile);
101719370Spst
101898948Sobrien	      finish_block (new->name, &local_symbols, new->old_blocks,
101998948Sobrien			    new->start_addr,
102019370Spst#if defined (FUNCTION_EPILOGUE_SIZE)
102198948Sobrien	      /* This macro should be defined only on
102298948Sobrien	         machines where the
102398948Sobrien	         fcn_aux_saved.x_sym.x_misc.x_fsize
102498948Sobrien	         field is always zero.
102598948Sobrien	         So use the .bf record information that
102698948Sobrien	         points to the epilogue and add the size
102798948Sobrien	         of the epilogue.  */
102898948Sobrien			    cs->c_value
102998948Sobrien			    + FUNCTION_EPILOGUE_SIZE
103098948Sobrien			    + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)),
103119370Spst#else
103298948Sobrien			    fcn_cs_saved.c_value
103398948Sobrien			    + fcn_aux_saved.x_sym.x_misc.x_fsize
103498948Sobrien			    + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)),
103519370Spst#endif
103698948Sobrien			    objfile
103798948Sobrien		);
103898948Sobrien	      within_function = 0;
103998948Sobrien	    }
104098948Sobrien	  break;
104119370Spst
104298948Sobrien	case C_BLOCK:
1043130809Smarcel	  if (DEPRECATED_STREQ (cs->c_name, ".bb"))
104498948Sobrien	    {
104598948Sobrien	      tmpaddr = cs->c_value;
104698948Sobrien	      tmpaddr += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
104798948Sobrien	      push_context (++depth, tmpaddr);
104898948Sobrien	    }
1049130809Smarcel	  else if (DEPRECATED_STREQ (cs->c_name, ".eb"))
105098948Sobrien	    {
105198948Sobrien	      if (context_stack_depth <= 0)
105298948Sobrien		{		/* We attempted to pop an empty context stack */
1053130809Smarcel		  complaint (&symfile_complaints,
1054130809Smarcel			     "`.eb' symbol without matching `.bb' symbol ignored starting at symnum %d",
1055130809Smarcel			     cs->c_symnum);
105698948Sobrien		  break;
105798948Sobrien		}
105819370Spst
105998948Sobrien	      new = pop_context ();
106098948Sobrien	      if (depth-- != new->depth)
106198948Sobrien		{
1062130809Smarcel		  complaint (&symfile_complaints,
1063130809Smarcel			     "Mismatched .eb symbol ignored starting at symnum %d",
1064130809Smarcel			     symnum);
106598948Sobrien		  break;
106698948Sobrien		}
106798948Sobrien	      if (local_symbols && context_stack_depth > 0)
106898948Sobrien		{
106998948Sobrien		  tmpaddr =
107098948Sobrien		    cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
107198948Sobrien		  /* Make a block for the local symbols within.  */
107298948Sobrien		  finish_block (0, &local_symbols, new->old_blocks,
107398948Sobrien				new->start_addr, tmpaddr, objfile);
107498948Sobrien		}
107598948Sobrien	      /* Now pop locals of block just finished.  */
107698948Sobrien	      local_symbols = new->locals;
107798948Sobrien	    }
107898948Sobrien	  break;
107919370Spst
108098948Sobrien	default:
108198948Sobrien	  process_coff_symbol (cs, &main_aux, objfile);
108298948Sobrien	  break;
108319370Spst	}
108419370Spst    }
108519370Spst
1086130809Smarcel  if ((nsyms == 0) && (pe_file))
1087130809Smarcel    {
1088130809Smarcel      /* We've got no debugging symbols, but it's is a portable
1089130809Smarcel	 executable, so try to read the export table */
1090130809Smarcel      read_pe_exported_syms (objfile);
1091130809Smarcel    }
1092130809Smarcel
109319370Spst  if (last_source_file)
109419370Spst    coff_end_symtab (objfile);
109519370Spst
109619370Spst  /* Patch up any opaque types (references to types that are not defined
109719370Spst     in the file where they are referenced, e.g. "struct foo *bar").  */
109819370Spst  ALL_OBJFILE_SYMTABS (objfile, s)
109919370Spst    patch_opaque_types (s);
110019370Spst
110119370Spst  current_objfile = NULL;
110219370Spst}
110319370Spst
110419370Spst/* Routines for reading headers and symbols from executable.  */
110519370Spst
110619370Spst/* Read the next symbol, swap it, and return it in both internal_syment
110719370Spst   form, and coff_symbol form.  Also return its first auxent, if any,
110819370Spst   in internal_auxent form, and skip any other auxents.  */
110919370Spst
111019370Spststatic void
1111130809Smarcelread_one_sym (struct coff_symbol *cs,
1112130809Smarcel	      struct internal_syment *sym,
1113130809Smarcel	      union internal_auxent *aux)
111419370Spst{
111519370Spst  int i;
111619370Spst
111719370Spst  cs->c_symnum = symnum;
111898948Sobrien  bfd_bread (temp_sym, local_symesz, nlist_bfd_global);
111998948Sobrien  bfd_coff_swap_sym_in (symfile_bfd, temp_sym, (char *) sym);
112019370Spst  cs->c_naux = sym->n_numaux & 0xff;
112119370Spst  if (cs->c_naux >= 1)
112219370Spst    {
112398948Sobrien      bfd_bread (temp_aux, local_auxesz, nlist_bfd_global);
112498948Sobrien      bfd_coff_swap_aux_in (symfile_bfd, temp_aux, sym->n_type, sym->n_sclass,
112598948Sobrien			    0, cs->c_naux, (char *) aux);
112698948Sobrien      /* If more than one aux entry, read past it (only the first aux
112798948Sobrien         is important). */
112898948Sobrien      for (i = 1; i < cs->c_naux; i++)
112998948Sobrien	bfd_bread (temp_aux, local_auxesz, nlist_bfd_global);
113019370Spst    }
113119370Spst  cs->c_name = getsymname (sym);
113219370Spst  cs->c_value = sym->n_value;
113319370Spst  cs->c_sclass = (sym->n_sclass & 0xff);
113419370Spst  cs->c_secnum = sym->n_scnum;
113519370Spst  cs->c_type = (unsigned) sym->n_type;
113619370Spst  if (!SDB_TYPE (cs->c_type))
113719370Spst    cs->c_type = 0;
113819370Spst
113946283Sdfr#if 0
114046283Sdfr  if (cs->c_sclass & 128)
114198948Sobrien    printf ("thumb symbol %s, class 0x%x\n", cs->c_name, cs->c_sclass);
114246283Sdfr#endif
114346283Sdfr
114419370Spst  symnum += 1 + cs->c_naux;
114546283Sdfr
114646283Sdfr  /* The PE file format stores symbol values as offsets within the
114746283Sdfr     section, rather than as absolute addresses.  We correct that
114846283Sdfr     here, if the symbol has an appropriate storage class.  FIXME: We
114946283Sdfr     should use BFD to read the symbols, rather than duplicating the
115046283Sdfr     work here.  */
115146283Sdfr  if (pe_file)
115246283Sdfr    {
115346283Sdfr      switch (cs->c_sclass)
115446283Sdfr	{
115546283Sdfr	case C_EXT:
115646283Sdfr	case C_THUMBEXT:
115746283Sdfr	case C_THUMBEXTFUNC:
115846283Sdfr	case C_SECTION:
115946283Sdfr	case C_NT_WEAK:
116046283Sdfr	case C_STAT:
116146283Sdfr	case C_THUMBSTAT:
116246283Sdfr	case C_THUMBSTATFUNC:
116346283Sdfr	case C_LABEL:
116446283Sdfr	case C_THUMBLABEL:
116546283Sdfr	case C_BLOCK:
116646283Sdfr	case C_FCN:
116746283Sdfr	case C_EFCN:
116846283Sdfr	  if (cs->c_secnum != 0)
116946283Sdfr	    cs->c_value += cs_section_address (cs, symfile_bfd);
117046283Sdfr	  break;
117146283Sdfr	}
117246283Sdfr    }
117319370Spst}
117419370Spst
117519370Spst/* Support for string table handling */
117619370Spst
117719370Spststatic char *stringtab = NULL;
117819370Spst
117919370Spststatic int
118098948Sobrieninit_stringtab (bfd *abfd, long offset)
118119370Spst{
118219370Spst  long length;
118319370Spst  int val;
118419370Spst  unsigned char lengthbuf[4];
118519370Spst
118619370Spst  free_stringtab ();
118719370Spst
118819370Spst  /* If the file is stripped, the offset might be zero, indicating no
118919370Spst     string table.  Just return with `stringtab' set to null. */
119019370Spst  if (offset == 0)
119119370Spst    return 0;
119219370Spst
119319370Spst  if (bfd_seek (abfd, offset, 0) < 0)
119419370Spst    return -1;
119519370Spst
119698948Sobrien  val = bfd_bread ((char *) lengthbuf, sizeof lengthbuf, abfd);
119719370Spst  length = bfd_h_get_32 (symfile_bfd, lengthbuf);
119898948Sobrien
119919370Spst  /* If no string table is needed, then the file may end immediately
120019370Spst     after the symbols.  Just return with `stringtab' set to null. */
120119370Spst  if (val != sizeof lengthbuf || length < sizeof lengthbuf)
120219370Spst    return 0;
120319370Spst
120419370Spst  stringtab = (char *) xmalloc (length);
120519370Spst  /* This is in target format (probably not very useful, and not currently
120619370Spst     used), not host format.  */
120719370Spst  memcpy (stringtab, lengthbuf, sizeof lengthbuf);
120898948Sobrien  if (length == sizeof length)	/* Empty table -- just the count */
120919370Spst    return 0;
121019370Spst
121198948Sobrien  val = bfd_bread (stringtab + sizeof lengthbuf, length - sizeof lengthbuf,
121298948Sobrien		   abfd);
121319370Spst  if (val != length - sizeof lengthbuf || stringtab[length - 1] != '\0')
121419370Spst    return -1;
121519370Spst
121619370Spst  return 0;
121719370Spst}
121819370Spst
121919370Spststatic void
122098948Sobrienfree_stringtab (void)
122119370Spst{
122219370Spst  if (stringtab)
122398948Sobrien    xfree (stringtab);
122419370Spst  stringtab = NULL;
122519370Spst}
122619370Spst
122798948Sobrienstatic void
122898948Sobrienfree_stringtab_cleanup (void *ignore)
122998948Sobrien{
123098948Sobrien  free_stringtab ();
123198948Sobrien}
123298948Sobrien
123319370Spststatic char *
123498948Sobriengetsymname (struct internal_syment *symbol_entry)
123519370Spst{
123698948Sobrien  static char buffer[SYMNMLEN + 1];
123719370Spst  char *result;
123819370Spst
123919370Spst  if (symbol_entry->_n._n_n._n_zeroes == 0)
124019370Spst    {
124119370Spst      /* FIXME: Probably should be detecting corrupt symbol files by
124298948Sobrien         seeing whether offset points to within the stringtab.  */
124319370Spst      result = stringtab + symbol_entry->_n._n_n._n_offset;
124419370Spst    }
124519370Spst  else
124619370Spst    {
124719370Spst      strncpy (buffer, symbol_entry->_n._n_name, SYMNMLEN);
124819370Spst      buffer[SYMNMLEN] = '\0';
124919370Spst      result = buffer;
125019370Spst    }
125119370Spst  return result;
125219370Spst}
125319370Spst
125419370Spst/* Extract the file name from the aux entry of a C_FILE symbol.  Return
125519370Spst   only the last component of the name.  Result is in static storage and
125619370Spst   is only good for temporary use.  */
125719370Spst
125819370Spststatic char *
125998948Sobriencoff_getfilename (union internal_auxent *aux_entry)
126019370Spst{
126119370Spst  static char buffer[BUFSIZ];
1262130809Smarcel  char *temp;
126319370Spst  char *result;
126419370Spst
126519370Spst  if (aux_entry->x_file.x_n.x_zeroes == 0)
126619370Spst    strcpy (buffer, stringtab + aux_entry->x_file.x_n.x_offset);
126719370Spst  else
126819370Spst    {
126919370Spst      strncpy (buffer, aux_entry->x_file.x_fname, FILNMLEN);
127019370Spst      buffer[FILNMLEN] = '\0';
127119370Spst    }
127219370Spst  result = buffer;
127319370Spst
127419370Spst  /* FIXME: We should not be throwing away the information about what
127519370Spst     directory.  It should go into dirname of the symtab, or some such
127619370Spst     place.  */
127719370Spst  if ((temp = strrchr (result, '/')) != NULL)
127819370Spst    result = temp + 1;
127919370Spst  return (result);
128019370Spst}
128119370Spst
128219370Spst/* Support for line number handling.  */
128319370Spst
128419370Spststatic char *linetab = NULL;
128519370Spststatic long linetab_offset;
128619370Spststatic unsigned long linetab_size;
128719370Spst
128819370Spst/* Read in all the line numbers for fast lookups later.  Leave them in
128919370Spst   external (unswapped) format in memory; we'll swap them as we enter
129019370Spst   them into GDB's data structures.  */
129198948Sobrien
129219370Spststatic int
129398948Sobrieninit_lineno (bfd *abfd, long offset, int size)
129419370Spst{
129519370Spst  int val;
129619370Spst
129719370Spst  linetab_offset = offset;
129819370Spst  linetab_size = size;
129919370Spst
130098948Sobrien  free_linetab ();
130119370Spst
130219370Spst  if (size == 0)
130319370Spst    return 0;
130419370Spst
130519370Spst  if (bfd_seek (abfd, offset, 0) < 0)
130619370Spst    return -1;
130798948Sobrien
130819370Spst  /* Allocate the desired table, plus a sentinel */
130919370Spst  linetab = (char *) xmalloc (size + local_linesz);
131019370Spst
131198948Sobrien  val = bfd_bread (linetab, size, abfd);
131219370Spst  if (val != size)
131319370Spst    return -1;
131419370Spst
131519370Spst  /* Terminate it with an all-zero sentinel record */
131619370Spst  memset (linetab + size, 0, local_linesz);
131719370Spst
131819370Spst  return 0;
131919370Spst}
132019370Spst
132119370Spststatic void
132298948Sobrienfree_linetab (void)
132319370Spst{
132419370Spst  if (linetab)
132598948Sobrien    xfree (linetab);
132619370Spst  linetab = NULL;
132719370Spst}
132819370Spst
132998948Sobrienstatic void
133098948Sobrienfree_linetab_cleanup (void *ignore)
133198948Sobrien{
133298948Sobrien  free_linetab ();
133398948Sobrien}
133498948Sobrien
133519370Spst#if !defined (L_LNNO32)
133619370Spst#define L_LNNO32(lp) ((lp)->l_lnno)
133719370Spst#endif
133819370Spst
133919370Spststatic void
1340130809Smarcelenter_linenos (long file_offset, int first_line,
1341130809Smarcel	       int last_line, struct objfile *objfile)
134219370Spst{
1343130809Smarcel  char *rawptr;
134419370Spst  struct internal_lineno lptr;
134519370Spst
134619370Spst  if (!linetab)
134798948Sobrien    return;
134819370Spst  if (file_offset < linetab_offset)
134919370Spst    {
1350130809Smarcel      complaint (&symfile_complaints,
1351130809Smarcel		 "Line number pointer %ld lower than start of line numbers",
1352130809Smarcel		 file_offset);
135319370Spst      if (file_offset > linetab_size)	/* Too big to be an offset? */
135419370Spst	return;
135598948Sobrien      file_offset += linetab_offset;	/* Try reading at that linetab offset */
135619370Spst    }
135798948Sobrien
135819370Spst  rawptr = &linetab[file_offset - linetab_offset];
135919370Spst
136019370Spst  /* skip first line entry for each function */
136119370Spst  rawptr += local_linesz;
136219370Spst  /* line numbers start at one for the first line of the function */
136319370Spst  first_line--;
136419370Spst
1365130809Smarcel  /* If the line number table is full (e.g. 64K lines in COFF debug
1366130809Smarcel     info), the next function's L_LNNO32 might not be zero, so don't
1367130809Smarcel     overstep the table's end in any case.  */
1368130809Smarcel  while (rawptr <= &linetab[0] + linetab_size)
136998948Sobrien    {
137098948Sobrien      bfd_coff_swap_lineno_in (symfile_bfd, rawptr, &lptr);
137198948Sobrien      rawptr += local_linesz;
1372130809Smarcel      /* The next function, or the sentinel, will have L_LNNO32 zero;
1373130809Smarcel	 we exit. */
137498948Sobrien      if (L_LNNO32 (&lptr) && L_LNNO32 (&lptr) <= last_line)
137598948Sobrien	record_line (current_subfile, first_line + L_LNNO32 (&lptr),
137698948Sobrien		     lptr.l_addr.l_paddr
137798948Sobrien		     + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)));
137898948Sobrien      else
137998948Sobrien	break;
138098948Sobrien    }
138119370Spst}
138219370Spst
138319370Spststatic void
138498948Sobrienpatch_type (struct type *type, struct type *real_type)
138519370Spst{
1386130809Smarcel  struct type *target = TYPE_TARGET_TYPE (type);
1387130809Smarcel  struct type *real_target = TYPE_TARGET_TYPE (real_type);
138819370Spst  int field_size = TYPE_NFIELDS (real_target) * sizeof (struct field);
138919370Spst
139019370Spst  TYPE_LENGTH (target) = TYPE_LENGTH (real_target);
139119370Spst  TYPE_NFIELDS (target) = TYPE_NFIELDS (real_target);
139219370Spst  TYPE_FIELDS (target) = (struct field *) TYPE_ALLOC (target, field_size);
139319370Spst
139419370Spst  memcpy (TYPE_FIELDS (target), TYPE_FIELDS (real_target), field_size);
139519370Spst
139619370Spst  if (TYPE_NAME (real_target))
139719370Spst    {
139819370Spst      if (TYPE_NAME (target))
139998948Sobrien	xfree (TYPE_NAME (target));
140019370Spst      TYPE_NAME (target) = concat (TYPE_NAME (real_target), NULL);
140119370Spst    }
140219370Spst}
140319370Spst
140419370Spst/* Patch up all appropriate typedef symbols in the opaque_type_chains
140519370Spst   so that they can be used to print out opaque data structures properly.  */
140619370Spst
140719370Spststatic void
140898948Sobrienpatch_opaque_types (struct symtab *s)
140919370Spst{
1410130809Smarcel  struct block *b;
1411130809Smarcel  struct dict_iterator iter;
1412130809Smarcel  struct symbol *real_sym;
141398948Sobrien
141419370Spst  /* Go through the per-file symbols only */
141519370Spst  b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
1416130809Smarcel  ALL_BLOCK_SYMBOLS (b, iter, real_sym)
141719370Spst    {
141819370Spst      /* Find completed typedefs to use to fix opaque ones.
141998948Sobrien         Remove syms from the chain when their types are stored,
142098948Sobrien         but search the whole chain, as there may be several syms
142198948Sobrien         from different files with the same name.  */
142219370Spst      if (SYMBOL_CLASS (real_sym) == LOC_TYPEDEF &&
1423130809Smarcel	  SYMBOL_DOMAIN (real_sym) == VAR_DOMAIN &&
142419370Spst	  TYPE_CODE (SYMBOL_TYPE (real_sym)) == TYPE_CODE_PTR &&
142519370Spst	  TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (real_sym))) != 0)
142619370Spst	{
1427130809Smarcel	  char *name = DEPRECATED_SYMBOL_NAME (real_sym);
1428130809Smarcel	  int hash = hashname (name);
1429130809Smarcel	  struct symbol *sym, *prev;
143098948Sobrien
143119370Spst	  prev = 0;
143219370Spst	  for (sym = opaque_type_chain[hash]; sym;)
143319370Spst	    {
1434130809Smarcel	      if (name[0] == DEPRECATED_SYMBOL_NAME (sym)[0] &&
1435130809Smarcel		  strcmp (name + 1, DEPRECATED_SYMBOL_NAME (sym) + 1) == 0)
143619370Spst		{
143719370Spst		  if (prev)
143819370Spst		    {
143919370Spst		      SYMBOL_VALUE_CHAIN (prev) = SYMBOL_VALUE_CHAIN (sym);
144019370Spst		    }
144119370Spst		  else
144219370Spst		    {
144319370Spst		      opaque_type_chain[hash] = SYMBOL_VALUE_CHAIN (sym);
144419370Spst		    }
144598948Sobrien
144619370Spst		  patch_type (SYMBOL_TYPE (sym), SYMBOL_TYPE (real_sym));
144798948Sobrien
144819370Spst		  if (prev)
144919370Spst		    {
145019370Spst		      sym = SYMBOL_VALUE_CHAIN (prev);
145119370Spst		    }
145219370Spst		  else
145319370Spst		    {
145419370Spst		      sym = opaque_type_chain[hash];
145519370Spst		    }
145619370Spst		}
145719370Spst	      else
145819370Spst		{
145919370Spst		  prev = sym;
146019370Spst		  sym = SYMBOL_VALUE_CHAIN (sym);
146119370Spst		}
146219370Spst	    }
146319370Spst	}
146419370Spst    }
146519370Spst}
146619370Spst
146719370Spststatic struct symbol *
1468130809Smarcelprocess_coff_symbol (struct coff_symbol *cs,
1469130809Smarcel		     union internal_auxent *aux,
147098948Sobrien		     struct objfile *objfile)
147119370Spst{
1472130809Smarcel  struct symbol *sym
1473130809Smarcel  = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
147498948Sobrien				     sizeof (struct symbol));
147519370Spst  char *name;
147619370Spst
147719370Spst  memset (sym, 0, sizeof (struct symbol));
147819370Spst  name = cs->c_name;
147919370Spst  name = EXTERNAL_NAME (name, objfile->obfd);
148046283Sdfr  SYMBOL_LANGUAGE (sym) = language_auto;
1481130809Smarcel  SYMBOL_SET_NAMES (sym, name, strlen (name), objfile);
148219370Spst
148319370Spst  /* default assumptions */
148419370Spst  SYMBOL_VALUE (sym) = cs->c_value;
1485130809Smarcel  SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
148619370Spst  SYMBOL_SECTION (sym) = cs_to_section (cs, objfile);
148719370Spst
148819370Spst  if (ISFCN (cs->c_type))
148919370Spst    {
149098948Sobrien      SYMBOL_VALUE (sym) += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
149198948Sobrien      SYMBOL_TYPE (sym) =
149298948Sobrien	lookup_function_type (decode_function_type (cs, cs->c_type, aux));
149319370Spst
149419370Spst      SYMBOL_CLASS (sym) = LOC_BLOCK;
149546283Sdfr      if (cs->c_sclass == C_STAT || cs->c_sclass == C_THUMBSTAT
149646283Sdfr	  || cs->c_sclass == C_THUMBSTATFUNC)
149719370Spst	add_symbol_to_list (sym, &file_symbols);
149846283Sdfr      else if (cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT
149946283Sdfr	       || cs->c_sclass == C_THUMBEXTFUNC)
150019370Spst	add_symbol_to_list (sym, &global_symbols);
150119370Spst    }
150219370Spst  else
150319370Spst    {
150419370Spst      SYMBOL_TYPE (sym) = decode_type (cs, cs->c_type, aux);
150519370Spst      switch (cs->c_sclass)
150619370Spst	{
150798948Sobrien	case C_NULL:
150898948Sobrien	  break;
150919370Spst
151098948Sobrien	case C_AUTO:
151198948Sobrien	  SYMBOL_CLASS (sym) = LOC_LOCAL;
151298948Sobrien	  add_symbol_to_list (sym, &local_symbols);
151398948Sobrien	  break;
151419370Spst
151598948Sobrien	case C_THUMBEXT:
151698948Sobrien	case C_THUMBEXTFUNC:
151798948Sobrien	case C_EXT:
151898948Sobrien	  SYMBOL_CLASS (sym) = LOC_STATIC;
151998948Sobrien	  SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;
152098948Sobrien	  SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
152198948Sobrien	  add_symbol_to_list (sym, &global_symbols);
152298948Sobrien	  break;
152319370Spst
152498948Sobrien	case C_THUMBSTAT:
152598948Sobrien	case C_THUMBSTATFUNC:
152698948Sobrien	case C_STAT:
152798948Sobrien	  SYMBOL_CLASS (sym) = LOC_STATIC;
152898948Sobrien	  SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;
152998948Sobrien	  SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
153098948Sobrien	  if (within_function)
153198948Sobrien	    {
153219370Spst	      /* Static symbol of local scope */
153319370Spst	      add_symbol_to_list (sym, &local_symbols);
153419370Spst	    }
153598948Sobrien	  else
153698948Sobrien	    {
153719370Spst	      /* Static symbol at top level of file */
153819370Spst	      add_symbol_to_list (sym, &file_symbols);
153919370Spst	    }
154098948Sobrien	  break;
154119370Spst
154219370Spst#ifdef C_GLBLREG		/* AMD coff */
154398948Sobrien	case C_GLBLREG:
154419370Spst#endif
154598948Sobrien	case C_REG:
154698948Sobrien	  SYMBOL_CLASS (sym) = LOC_REGISTER;
154798948Sobrien	  SYMBOL_VALUE (sym) = SDB_REG_TO_REGNUM (cs->c_value);
154898948Sobrien	  add_symbol_to_list (sym, &local_symbols);
154998948Sobrien	  break;
155019370Spst
155198948Sobrien	case C_THUMBLABEL:
155298948Sobrien	case C_LABEL:
155398948Sobrien	  break;
155419370Spst
155598948Sobrien	case C_ARG:
155698948Sobrien	  SYMBOL_CLASS (sym) = LOC_ARG;
155798948Sobrien	  add_symbol_to_list (sym, &local_symbols);
155819370Spst#if !defined (BELIEVE_PCC_PROMOTION)
155998948Sobrien	  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
156098948Sobrien	    {
156198948Sobrien	      /* If PCC says a parameter is a short or a char,
156298948Sobrien	         aligned on an int boundary, realign it to the
156398948Sobrien	         "little end" of the int.  */
156498948Sobrien	      struct type *temptype;
156598948Sobrien	      temptype = lookup_fundamental_type (current_objfile,
156698948Sobrien						  FT_INTEGER);
156798948Sobrien	      if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype)
156898948Sobrien		  && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT
156998948Sobrien		  && 0 == SYMBOL_VALUE (sym) % TYPE_LENGTH (temptype))
157098948Sobrien		{
157198948Sobrien		  SYMBOL_VALUE (sym) +=
157298948Sobrien		    TYPE_LENGTH (temptype)
157398948Sobrien		    - TYPE_LENGTH (SYMBOL_TYPE (sym));
157498948Sobrien		}
157598948Sobrien	    }
157619370Spst#endif
157798948Sobrien	  break;
157819370Spst
157998948Sobrien	case C_REGPARM:
158098948Sobrien	  SYMBOL_CLASS (sym) = LOC_REGPARM;
158198948Sobrien	  SYMBOL_VALUE (sym) = SDB_REG_TO_REGNUM (cs->c_value);
158298948Sobrien	  add_symbol_to_list (sym, &local_symbols);
158319370Spst#if !defined (BELIEVE_PCC_PROMOTION)
158498948Sobrien	  /* FIXME:  This should retain the current type, since it's just
158598948Sobrien	     a register value.  gnu@adobe, 26Feb93 */
158698948Sobrien	  {
158798948Sobrien	    /* If PCC says a parameter is a short or a char,
158898948Sobrien	       it is really an int.  */
158998948Sobrien	    struct type *temptype;
159098948Sobrien	    temptype =
159198948Sobrien	      lookup_fundamental_type (current_objfile, FT_INTEGER);
159298948Sobrien	    if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype)
159398948Sobrien		&& TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT)
159419370Spst	      {
159598948Sobrien		SYMBOL_TYPE (sym) =
159698948Sobrien		  (TYPE_UNSIGNED (SYMBOL_TYPE (sym))
159798948Sobrien		   ? lookup_fundamental_type (current_objfile,
159898948Sobrien					      FT_UNSIGNED_INTEGER)
159998948Sobrien		   : temptype);
160019370Spst	      }
160198948Sobrien	  }
160219370Spst#endif
160398948Sobrien	  break;
160419370Spst
160598948Sobrien	case C_TPDEF:
160698948Sobrien	  SYMBOL_CLASS (sym) = LOC_TYPEDEF;
1607130809Smarcel	  SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
160819370Spst
160998948Sobrien	  /* If type has no name, give it one */
161098948Sobrien	  if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
161198948Sobrien	    {
161298948Sobrien	      if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR
161398948Sobrien		  || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FUNC)
161498948Sobrien		{
161598948Sobrien		  /* If we are giving a name to a type such as "pointer to
161698948Sobrien		     foo" or "function returning foo", we better not set
161798948Sobrien		     the TYPE_NAME.  If the program contains "typedef char
161898948Sobrien		     *caddr_t;", we don't want all variables of type char
161998948Sobrien		     * to print as caddr_t.  This is not just a
162098948Sobrien		     consequence of GDB's type management; CC and GCC (at
162198948Sobrien		     least through version 2.4) both output variables of
162298948Sobrien		     either type char * or caddr_t with the type
162398948Sobrien		     refering to the C_TPDEF symbol for caddr_t.  If a future
162498948Sobrien		     compiler cleans this up it GDB is not ready for it
162598948Sobrien		     yet, but if it becomes ready we somehow need to
162698948Sobrien		     disable this check (without breaking the PCC/GCC2.4
162798948Sobrien		     case).
162819370Spst
162998948Sobrien		     Sigh.
163098948Sobrien
163198948Sobrien		     Fortunately, this check seems not to be necessary
163298948Sobrien		     for anything except pointers or functions.  */
163398948Sobrien		  ;
163498948Sobrien		}
163598948Sobrien	      else
163698948Sobrien		TYPE_NAME (SYMBOL_TYPE (sym)) =
1637130809Smarcel		  concat (DEPRECATED_SYMBOL_NAME (sym), NULL);
163898948Sobrien	    }
163919370Spst
164098948Sobrien	  /* Keep track of any type which points to empty structured type,
164198948Sobrien	     so it can be filled from a definition from another file.  A
164298948Sobrien	     simple forward reference (TYPE_CODE_UNDEF) is not an
164398948Sobrien	     empty structured type, though; the forward references
164498948Sobrien	     work themselves out via the magic of coff_lookup_type.  */
164598948Sobrien	  if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR &&
164698948Sobrien	      TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) == 0 &&
164798948Sobrien	      TYPE_CODE (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) !=
164898948Sobrien	      TYPE_CODE_UNDEF)
164998948Sobrien	    {
1650130809Smarcel	      int i = hashname (DEPRECATED_SYMBOL_NAME (sym));
165119370Spst
165298948Sobrien	      SYMBOL_VALUE_CHAIN (sym) = opaque_type_chain[i];
165398948Sobrien	      opaque_type_chain[i] = sym;
165498948Sobrien	    }
165598948Sobrien	  add_symbol_to_list (sym, &file_symbols);
165698948Sobrien	  break;
165719370Spst
165898948Sobrien	case C_STRTAG:
165998948Sobrien	case C_UNTAG:
166098948Sobrien	case C_ENTAG:
166198948Sobrien	  SYMBOL_CLASS (sym) = LOC_TYPEDEF;
1662130809Smarcel	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
166319370Spst
166498948Sobrien	  /* Some compilers try to be helpful by inventing "fake"
166598948Sobrien	     names for anonymous enums, structures, and unions, like
166698948Sobrien	     "~0fake" or ".0fake".  Thanks, but no thanks... */
166798948Sobrien	  if (TYPE_TAG_NAME (SYMBOL_TYPE (sym)) == 0)
1668130809Smarcel	    if (DEPRECATED_SYMBOL_NAME (sym) != NULL
1669130809Smarcel		&& *DEPRECATED_SYMBOL_NAME (sym) != '~'
1670130809Smarcel		&& *DEPRECATED_SYMBOL_NAME (sym) != '.')
167198948Sobrien	      TYPE_TAG_NAME (SYMBOL_TYPE (sym)) =
1672130809Smarcel		concat (DEPRECATED_SYMBOL_NAME (sym), NULL);
167319370Spst
167498948Sobrien	  add_symbol_to_list (sym, &file_symbols);
167598948Sobrien	  break;
167619370Spst
167798948Sobrien	default:
167898948Sobrien	  break;
167919370Spst	}
168019370Spst    }
168119370Spst  return sym;
168219370Spst}
168319370Spst
168419370Spst/* Decode a coff type specifier;  return the type that is meant.  */
168519370Spst
168619370Spststatic struct type *
1687130809Smarceldecode_type (struct coff_symbol *cs, unsigned int c_type,
1688130809Smarcel	     union internal_auxent *aux)
168919370Spst{
1690130809Smarcel  struct type *type = 0;
169119370Spst  unsigned int new_c_type;
169219370Spst
169319370Spst  if (c_type & ~N_BTMASK)
169419370Spst    {
169519370Spst      new_c_type = DECREF (c_type);
169619370Spst      if (ISPTR (c_type))
169719370Spst	{
169819370Spst	  type = decode_type (cs, new_c_type, aux);
169919370Spst	  type = lookup_pointer_type (type);
170019370Spst	}
170119370Spst      else if (ISFCN (c_type))
170219370Spst	{
170319370Spst	  type = decode_type (cs, new_c_type, aux);
170419370Spst	  type = lookup_function_type (type);
170519370Spst	}
170619370Spst      else if (ISARY (c_type))
170719370Spst	{
170819370Spst	  int i, n;
1709130809Smarcel	  unsigned short *dim;
171019370Spst	  struct type *base_type, *index_type, *range_type;
171119370Spst
171219370Spst	  /* Define an array type.  */
171319370Spst	  /* auxent refers to array, not base type */
171419370Spst	  if (aux->x_sym.x_tagndx.l == 0)
171519370Spst	    cs->c_naux = 0;
171619370Spst
171719370Spst	  /* shift the indices down */
171819370Spst	  dim = &aux->x_sym.x_fcnary.x_ary.x_dimen[0];
171919370Spst	  i = 1;
172019370Spst	  n = dim[0];
172119370Spst	  for (i = 0; *dim && i < DIMNUM - 1; i++, dim++)
172219370Spst	    *dim = *(dim + 1);
172319370Spst	  *dim = 0;
172419370Spst
172519370Spst	  base_type = decode_type (cs, new_c_type, aux);
172619370Spst	  index_type = lookup_fundamental_type (current_objfile, FT_INTEGER);
172719370Spst	  range_type =
172819370Spst	    create_range_type ((struct type *) NULL, index_type, 0, n - 1);
172919370Spst	  type =
173019370Spst	    create_array_type ((struct type *) NULL, base_type, range_type);
173119370Spst	}
173219370Spst      return type;
173319370Spst    }
173419370Spst
173519370Spst  /* Reference to existing type.  This only occurs with the
173619370Spst     struct, union, and enum types.  EPI a29k coff
173719370Spst     fakes us out by producing aux entries with a nonzero
173819370Spst     x_tagndx for definitions of structs, unions, and enums, so we
173919370Spst     have to check the c_sclass field.  SCO 3.2v4 cc gets confused
174019370Spst     with pointers to pointers to defined structs, and generates
174119370Spst     negative x_tagndx fields.  */
174219370Spst  if (cs->c_naux > 0 && aux->x_sym.x_tagndx.l != 0)
174319370Spst    {
174419370Spst      if (cs->c_sclass != C_STRTAG
174519370Spst	  && cs->c_sclass != C_UNTAG
174619370Spst	  && cs->c_sclass != C_ENTAG
174719370Spst	  && aux->x_sym.x_tagndx.l >= 0)
174819370Spst	{
174919370Spst	  type = coff_alloc_type (aux->x_sym.x_tagndx.l);
175019370Spst	  return type;
175119370Spst	}
175219370Spst      else
175319370Spst	{
1754130809Smarcel	  complaint (&symfile_complaints,
1755130809Smarcel		     "Symbol table entry for %s has bad tagndx value",
1756130809Smarcel		     cs->c_name);
175719370Spst	  /* And fall through to decode_base_type... */
175819370Spst	}
175919370Spst    }
176019370Spst
176119370Spst  return decode_base_type (cs, BTYPE (c_type), aux);
176219370Spst}
176319370Spst
176419370Spst/* Decode a coff type specifier for function definition;
176519370Spst   return the type that the function returns.  */
176619370Spst
176719370Spststatic struct type *
1768130809Smarceldecode_function_type (struct coff_symbol *cs, unsigned int c_type,
1769130809Smarcel		      union internal_auxent *aux)
177019370Spst{
177119370Spst  if (aux->x_sym.x_tagndx.l == 0)
177298948Sobrien    cs->c_naux = 0;		/* auxent refers to function, not base type */
177319370Spst
177419370Spst  return decode_type (cs, DECREF (c_type), aux);
177519370Spst}
177619370Spst
177719370Spst/* basic C types */
177819370Spst
177919370Spststatic struct type *
1780130809Smarceldecode_base_type (struct coff_symbol *cs, unsigned int c_type,
1781130809Smarcel		  union internal_auxent *aux)
178219370Spst{
178319370Spst  struct type *type;
178419370Spst
178519370Spst  switch (c_type)
178619370Spst    {
178798948Sobrien    case T_NULL:
178898948Sobrien      /* shows up with "void (*foo)();" structure members */
178998948Sobrien      return lookup_fundamental_type (current_objfile, FT_VOID);
179019370Spst
179119370Spst#ifdef T_VOID
179298948Sobrien    case T_VOID:
179398948Sobrien      /* Intel 960 COFF has this symbol and meaning.  */
179498948Sobrien      return lookup_fundamental_type (current_objfile, FT_VOID);
179519370Spst#endif
179619370Spst
179798948Sobrien    case T_CHAR:
179898948Sobrien      return lookup_fundamental_type (current_objfile, FT_CHAR);
179919370Spst
180098948Sobrien    case T_SHORT:
180198948Sobrien      return lookup_fundamental_type (current_objfile, FT_SHORT);
180219370Spst
180398948Sobrien    case T_INT:
180498948Sobrien      return lookup_fundamental_type (current_objfile, FT_INTEGER);
180519370Spst
180698948Sobrien    case T_LONG:
180798948Sobrien      if (cs->c_sclass == C_FIELD
180898948Sobrien	  && aux->x_sym.x_misc.x_lnsz.x_size > TARGET_LONG_BIT)
180998948Sobrien	return lookup_fundamental_type (current_objfile, FT_LONG_LONG);
181098948Sobrien      else
181198948Sobrien	return lookup_fundamental_type (current_objfile, FT_LONG);
181219370Spst
181398948Sobrien    case T_FLOAT:
181498948Sobrien      return lookup_fundamental_type (current_objfile, FT_FLOAT);
181519370Spst
181698948Sobrien    case T_DOUBLE:
181798948Sobrien      return lookup_fundamental_type (current_objfile, FT_DBL_PREC_FLOAT);
181819370Spst
181998948Sobrien    case T_LNGDBL:
182098948Sobrien      return lookup_fundamental_type (current_objfile, FT_EXT_PREC_FLOAT);
182119370Spst
182298948Sobrien    case T_STRUCT:
182398948Sobrien      if (cs->c_naux != 1)
182498948Sobrien	{
182598948Sobrien	  /* anonymous structure type */
182698948Sobrien	  type = coff_alloc_type (cs->c_symnum);
182798948Sobrien	  TYPE_CODE (type) = TYPE_CODE_STRUCT;
182898948Sobrien	  TYPE_NAME (type) = NULL;
182998948Sobrien	  /* This used to set the tag to "<opaque>".  But I think setting it
183098948Sobrien	     to NULL is right, and the printing code can print it as
183198948Sobrien	     "struct {...}".  */
183298948Sobrien	  TYPE_TAG_NAME (type) = NULL;
183398948Sobrien	  INIT_CPLUS_SPECIFIC (type);
183498948Sobrien	  TYPE_LENGTH (type) = 0;
183598948Sobrien	  TYPE_FIELDS (type) = 0;
183698948Sobrien	  TYPE_NFIELDS (type) = 0;
183798948Sobrien	}
183898948Sobrien      else
183998948Sobrien	{
184098948Sobrien	  type = coff_read_struct_type (cs->c_symnum,
184198948Sobrien					aux->x_sym.x_misc.x_lnsz.x_size,
184298948Sobrien				      aux->x_sym.x_fcnary.x_fcn.x_endndx.l);
184398948Sobrien	}
184498948Sobrien      return type;
184519370Spst
184698948Sobrien    case T_UNION:
184798948Sobrien      if (cs->c_naux != 1)
184898948Sobrien	{
184998948Sobrien	  /* anonymous union type */
185098948Sobrien	  type = coff_alloc_type (cs->c_symnum);
185198948Sobrien	  TYPE_NAME (type) = NULL;
185298948Sobrien	  /* This used to set the tag to "<opaque>".  But I think setting it
185398948Sobrien	     to NULL is right, and the printing code can print it as
185498948Sobrien	     "union {...}".  */
185598948Sobrien	  TYPE_TAG_NAME (type) = NULL;
185698948Sobrien	  INIT_CPLUS_SPECIFIC (type);
185798948Sobrien	  TYPE_LENGTH (type) = 0;
185898948Sobrien	  TYPE_FIELDS (type) = 0;
185998948Sobrien	  TYPE_NFIELDS (type) = 0;
186098948Sobrien	}
186198948Sobrien      else
186298948Sobrien	{
186398948Sobrien	  type = coff_read_struct_type (cs->c_symnum,
186419370Spst					aux->x_sym.x_misc.x_lnsz.x_size,
186598948Sobrien				      aux->x_sym.x_fcnary.x_fcn.x_endndx.l);
186698948Sobrien	}
186798948Sobrien      TYPE_CODE (type) = TYPE_CODE_UNION;
186898948Sobrien      return type;
186919370Spst
187098948Sobrien    case T_ENUM:
187198948Sobrien      if (cs->c_naux != 1)
187298948Sobrien	{
187398948Sobrien	  /* anonymous enum type */
187498948Sobrien	  type = coff_alloc_type (cs->c_symnum);
187598948Sobrien	  TYPE_CODE (type) = TYPE_CODE_ENUM;
187698948Sobrien	  TYPE_NAME (type) = NULL;
187798948Sobrien	  /* This used to set the tag to "<opaque>".  But I think setting it
187898948Sobrien	     to NULL is right, and the printing code can print it as
187998948Sobrien	     "enum {...}".  */
188098948Sobrien	  TYPE_TAG_NAME (type) = NULL;
188198948Sobrien	  TYPE_LENGTH (type) = 0;
188298948Sobrien	  TYPE_FIELDS (type) = 0;
188398948Sobrien	  TYPE_NFIELDS (type) = 0;
188498948Sobrien	}
188598948Sobrien      else
188698948Sobrien	{
188798948Sobrien	  type = coff_read_enum_type (cs->c_symnum,
188898948Sobrien				      aux->x_sym.x_misc.x_lnsz.x_size,
188998948Sobrien				      aux->x_sym.x_fcnary.x_fcn.x_endndx.l);
189098948Sobrien	}
189198948Sobrien      return type;
189219370Spst
189398948Sobrien    case T_MOE:
189498948Sobrien      /* shouldn't show up here */
189598948Sobrien      break;
189619370Spst
189798948Sobrien    case T_UCHAR:
189898948Sobrien      return lookup_fundamental_type (current_objfile, FT_UNSIGNED_CHAR);
189919370Spst
190098948Sobrien    case T_USHORT:
190198948Sobrien      return lookup_fundamental_type (current_objfile, FT_UNSIGNED_SHORT);
190219370Spst
190398948Sobrien    case T_UINT:
190498948Sobrien      return lookup_fundamental_type (current_objfile, FT_UNSIGNED_INTEGER);
190598948Sobrien
190698948Sobrien    case T_ULONG:
190798948Sobrien      if (cs->c_sclass == C_FIELD
190898948Sobrien	  && aux->x_sym.x_misc.x_lnsz.x_size > TARGET_LONG_BIT)
190998948Sobrien	return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG_LONG);
191098948Sobrien      else
191198948Sobrien	return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG);
191219370Spst    }
1913130809Smarcel  complaint (&symfile_complaints, "Unexpected type for symbol %s", cs->c_name);
191419370Spst  return lookup_fundamental_type (current_objfile, FT_VOID);
191519370Spst}
191619370Spst
191719370Spst/* This page contains subroutines of read_type.  */
191819370Spst
191919370Spst/* Read the description of a structure (or union type) and return an
192019370Spst   object describing the type.  */
192119370Spst
192219370Spststatic struct type *
192398948Sobriencoff_read_struct_type (int index, int length, int lastsym)
192419370Spst{
192519370Spst  struct nextfield
192619370Spst    {
192719370Spst      struct nextfield *next;
192819370Spst      struct field field;
192919370Spst    };
193019370Spst
1931130809Smarcel  struct type *type;
1932130809Smarcel  struct nextfield *list = 0;
193319370Spst  struct nextfield *new;
193419370Spst  int nfields = 0;
1935130809Smarcel  int n;
193619370Spst  char *name;
193719370Spst  struct coff_symbol member_sym;
1938130809Smarcel  struct coff_symbol *ms = &member_sym;
193919370Spst  struct internal_syment sub_sym;
194019370Spst  union internal_auxent sub_aux;
194119370Spst  int done = 0;
194219370Spst
194319370Spst  type = coff_alloc_type (index);
194419370Spst  TYPE_CODE (type) = TYPE_CODE_STRUCT;
194598948Sobrien  INIT_CPLUS_SPECIFIC (type);
194619370Spst  TYPE_LENGTH (type) = length;
194719370Spst
194819370Spst  while (!done && symnum < lastsym && symnum < nlist_nsyms_global)
194919370Spst    {
195019370Spst      read_one_sym (ms, &sub_sym, &sub_aux);
195119370Spst      name = ms->c_name;
195219370Spst      name = EXTERNAL_NAME (name, current_objfile->obfd);
195319370Spst
195419370Spst      switch (ms->c_sclass)
195519370Spst	{
195698948Sobrien	case C_MOS:
195798948Sobrien	case C_MOU:
195819370Spst
195998948Sobrien	  /* Get space to record the next field's data.  */
196098948Sobrien	  new = (struct nextfield *) alloca (sizeof (struct nextfield));
196198948Sobrien	  new->next = list;
196298948Sobrien	  list = new;
196319370Spst
196498948Sobrien	  /* Save the data.  */
196598948Sobrien	  list->field.name =
196698948Sobrien	    obsavestring (name,
196798948Sobrien			  strlen (name),
1968130809Smarcel			  &current_objfile->objfile_obstack);
196998948Sobrien	  FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux);
197098948Sobrien	  FIELD_BITPOS (list->field) = 8 * ms->c_value;
197198948Sobrien	  FIELD_BITSIZE (list->field) = 0;
1972130809Smarcel	  FIELD_STATIC_KIND (list->field) = 0;
197398948Sobrien	  nfields++;
197498948Sobrien	  break;
197519370Spst
197698948Sobrien	case C_FIELD:
197719370Spst
197898948Sobrien	  /* Get space to record the next field's data.  */
197998948Sobrien	  new = (struct nextfield *) alloca (sizeof (struct nextfield));
198098948Sobrien	  new->next = list;
198198948Sobrien	  list = new;
198219370Spst
198398948Sobrien	  /* Save the data.  */
198498948Sobrien	  list->field.name =
198598948Sobrien	    obsavestring (name,
198698948Sobrien			  strlen (name),
1987130809Smarcel			  &current_objfile->objfile_obstack);
198898948Sobrien	  FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux);
198998948Sobrien	  FIELD_BITPOS (list->field) = ms->c_value;
199098948Sobrien	  FIELD_BITSIZE (list->field) = sub_aux.x_sym.x_misc.x_lnsz.x_size;
1991130809Smarcel	  FIELD_STATIC_KIND (list->field) = 0;
199298948Sobrien	  nfields++;
199398948Sobrien	  break;
199419370Spst
199598948Sobrien	case C_EOS:
199698948Sobrien	  done = 1;
199798948Sobrien	  break;
199819370Spst	}
199919370Spst    }
200019370Spst  /* Now create the vector of fields, and record how big it is.  */
200119370Spst
200219370Spst  TYPE_NFIELDS (type) = nfields;
200319370Spst  TYPE_FIELDS (type) = (struct field *)
200419370Spst    TYPE_ALLOC (type, sizeof (struct field) * nfields);
200519370Spst
200619370Spst  /* Copy the saved-up fields into the field vector.  */
200719370Spst
200819370Spst  for (n = nfields; list; list = list->next)
200919370Spst    TYPE_FIELD (type, --n) = list->field;
201019370Spst
201119370Spst  return type;
201219370Spst}
201319370Spst
201419370Spst/* Read a definition of an enumeration type,
201519370Spst   and create and return a suitable type object.
201619370Spst   Also defines the symbols that represent the values of the type.  */
201719370Spst
201819370Spststatic struct type *
201998948Sobriencoff_read_enum_type (int index, int length, int lastsym)
202019370Spst{
2021130809Smarcel  struct symbol *sym;
2022130809Smarcel  struct type *type;
202319370Spst  int nsyms = 0;
202419370Spst  int done = 0;
202519370Spst  struct pending **symlist;
202619370Spst  struct coff_symbol member_sym;
2027130809Smarcel  struct coff_symbol *ms = &member_sym;
202819370Spst  struct internal_syment sub_sym;
202919370Spst  union internal_auxent sub_aux;
203019370Spst  struct pending *osyms, *syms;
203119370Spst  int o_nsyms;
2032130809Smarcel  int n;
203319370Spst  char *name;
203446283Sdfr  int unsigned_enum = 1;
203519370Spst
203619370Spst  type = coff_alloc_type (index);
203719370Spst  if (within_function)
203819370Spst    symlist = &local_symbols;
203919370Spst  else
204019370Spst    symlist = &file_symbols;
204119370Spst  osyms = *symlist;
204219370Spst  o_nsyms = osyms ? osyms->nsyms : 0;
204319370Spst
204419370Spst  while (!done && symnum < lastsym && symnum < nlist_nsyms_global)
204519370Spst    {
204619370Spst      read_one_sym (ms, &sub_sym, &sub_aux);
204719370Spst      name = ms->c_name;
204819370Spst      name = EXTERNAL_NAME (name, current_objfile->obfd);
204919370Spst
205019370Spst      switch (ms->c_sclass)
205119370Spst	{
205298948Sobrien	case C_MOE:
205398948Sobrien	  sym = (struct symbol *) obstack_alloc
2054130809Smarcel	    (&current_objfile->objfile_obstack,
205598948Sobrien	     sizeof (struct symbol));
205698948Sobrien	  memset (sym, 0, sizeof (struct symbol));
205719370Spst
2058130809Smarcel	  DEPRECATED_SYMBOL_NAME (sym) =
205998948Sobrien	    obsavestring (name, strlen (name),
2060130809Smarcel			  &current_objfile->objfile_obstack);
206198948Sobrien	  SYMBOL_CLASS (sym) = LOC_CONST;
2062130809Smarcel	  SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
206398948Sobrien	  SYMBOL_VALUE (sym) = ms->c_value;
206498948Sobrien	  add_symbol_to_list (sym, symlist);
206598948Sobrien	  nsyms++;
206698948Sobrien	  break;
206719370Spst
206898948Sobrien	case C_EOS:
206998948Sobrien	  /* Sometimes the linker (on 386/ix 2.0.2 at least) screws
207098948Sobrien	     up the count of how many symbols to read.  So stop
207198948Sobrien	     on .eos.  */
207298948Sobrien	  done = 1;
207398948Sobrien	  break;
207419370Spst	}
207519370Spst    }
207619370Spst
207719370Spst  /* Now fill in the fields of the type-structure.  */
207819370Spst
207919370Spst  if (length > 0)
208019370Spst    TYPE_LENGTH (type) = length;
208119370Spst  else
208298948Sobrien    TYPE_LENGTH (type) = TARGET_INT_BIT / TARGET_CHAR_BIT;	/* Assume ints */
208319370Spst  TYPE_CODE (type) = TYPE_CODE_ENUM;
208419370Spst  TYPE_NFIELDS (type) = nsyms;
208519370Spst  TYPE_FIELDS (type) = (struct field *)
208619370Spst    TYPE_ALLOC (type, sizeof (struct field) * nsyms);
208719370Spst
208819370Spst  /* Find the symbols for the values and put them into the type.
208919370Spst     The symbols can be found in the symlist that we put them on
209019370Spst     to cause them to be defined.  osyms contains the old value
209119370Spst     of that symlist; everything up to there was defined by us.  */
209219370Spst  /* Note that we preserve the order of the enum constants, so
209319370Spst     that in something like "enum {FOO, LAST_THING=FOO}" we print
209419370Spst     FOO, not LAST_THING.  */
209519370Spst
209619370Spst  for (syms = *symlist, n = 0; syms; syms = syms->next)
209719370Spst    {
209819370Spst      int j = 0;
209919370Spst
210019370Spst      if (syms == osyms)
210119370Spst	j = o_nsyms;
210298948Sobrien      for (; j < syms->nsyms; j++, n++)
210319370Spst	{
210419370Spst	  struct symbol *xsym = syms->symbol[j];
210519370Spst	  SYMBOL_TYPE (xsym) = type;
2106130809Smarcel	  TYPE_FIELD_NAME (type, n) = DEPRECATED_SYMBOL_NAME (xsym);
210719370Spst	  TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym);
210846283Sdfr	  if (SYMBOL_VALUE (xsym) < 0)
210946283Sdfr	    unsigned_enum = 0;
211019370Spst	  TYPE_FIELD_BITSIZE (type, n) = 0;
2111130809Smarcel	  TYPE_FIELD_STATIC_KIND (type, n) = 0;
211219370Spst	}
211319370Spst      if (syms == osyms)
211419370Spst	break;
211519370Spst    }
211619370Spst
211746283Sdfr  if (unsigned_enum)
211846283Sdfr    TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
211946283Sdfr
212019370Spst  return type;
212119370Spst}
212219370Spst
212319370Spst/* Register our ability to parse symbols for coff BFD files. */
212419370Spst
212519370Spststatic struct sym_fns coff_sym_fns =
212619370Spst{
212719370Spst  bfd_target_coff_flavour,
212898948Sobrien  coff_new_init,		/* sym_new_init: init anything gbl to entire symtab */
212998948Sobrien  coff_symfile_init,		/* sym_init: read initial info, setup for sym_read() */
213098948Sobrien  coff_symfile_read,		/* sym_read: read a symbol file into symtab */
213198948Sobrien  coff_symfile_finish,		/* sym_finish: finished with file, cleanup */
213298948Sobrien  default_symfile_offsets,	/* sym_offsets:  xlate external to internal form */
213398948Sobrien  NULL				/* next: pointer to next struct sym_fns */
213419370Spst};
213519370Spst
213619370Spstvoid
213798948Sobrien_initialize_coffread (void)
213819370Spst{
213919370Spst  add_symtab_fns (&coff_sym_fns);
214019370Spst}
2141