/* Read coff symbol tables and convert to internal format, for GDB.
   Copyright (C) 1987-2022 Free Software Foundation, Inc.
   Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu).

   This file is part of GDB.

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

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

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

#include "defs.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "demangle.h"
#include "breakpoint.h"

#include "bfd.h"
#include "gdbsupport/gdb_obstack.h"
#include <ctype.h>

#include "coff/internal.h"	/* Internal format of COFF symbols in BFD */
#include "libcoff.h"		/* FIXME secret internal data from BFD */
#include "objfiles.h"
#include "buildsym-legacy.h"
#include "stabsread.h"
#include "complaints.h"
#include "target.h"
#include "block.h"
#include "dictionary.h"
#include "dwarf2/public.h"

#include "coff-pe-read.h"

#include "psymtab.h"
#include "build-id.h"

/* The objfile we are currently reading.  */

static struct objfile *coffread_objfile;

struct coff_symfile_info
  {
    file_ptr min_lineno_offset = 0;	/* Where in file lowest line#s are.  */
    file_ptr max_lineno_offset = 0;	/* 1+last byte of line#s in file.  */

    CORE_ADDR textaddr = 0;		/* Addr of .text section.  */
    unsigned int textsize = 0;	/* Size of .text section.  */
    std::vector<asection *> *stabsects;	/* .stab sections.  */
    asection *stabstrsect = nullptr;	/* Section pointer for .stab section.  */
    char *stabstrdata = nullptr;
  };

/* Key for COFF-associated data.  */

static const struct objfile_key<coff_symfile_info> coff_objfile_data_key;

/* Translate an external name string into a user-visible name.  */
#define	EXTERNAL_NAME(string, abfd) \
	(string[0] == bfd_get_symbol_leading_char (abfd) \
	? string + 1 : string)

/* To be an sdb debug type, type must have at least a basic or primary
   derived type.  Using this rather than checking against T_NULL is
   said to prevent core dumps if we try to operate on Michael Bloom
   dbx-in-coff file.  */

#define SDB_TYPE(type) (BTYPE(type) | (type & N_TMASK))

/* Core address of start and end of text of current source file.
   This comes from a ".text" symbol where x_nlinno > 0.  */

static CORE_ADDR current_source_start_addr;
static CORE_ADDR current_source_end_addr;

/* The addresses of the symbol table stream and number of symbols
   of the object file we are reading (as copied into core).  */

static bfd *nlist_bfd_global;
static int nlist_nsyms_global;


/* Pointers to scratch storage, used for reading raw symbols and
   auxents.  */

static char *temp_sym;
static char *temp_aux;

/* Local variables that hold the shift and mask values for the
   COFF file that we are currently reading.  These come back to us
   from BFD, and are referenced by their macro names, as well as
   internally to the BTYPE, ISPTR, ISFCN, ISARY, ISTAG, and DECREF
   macros from include/coff/internal.h .  */

static unsigned local_n_btmask;
static unsigned local_n_btshft;
static unsigned local_n_tmask;
static unsigned local_n_tshift;

#define	N_BTMASK	local_n_btmask
#define	N_BTSHFT	local_n_btshft
#define	N_TMASK		local_n_tmask
#define	N_TSHIFT	local_n_tshift

/* Local variables that hold the sizes in the file of various COFF
   structures.  (We only need to know this to read them from the file
   -- BFD will then translate the data in them, into `internal_xxx'
   structs in the right byte order, alignment, etc.)  */

static unsigned local_linesz;
static unsigned local_symesz;
static unsigned local_auxesz;

/* This is set if this is a PE format file.  */

static int pe_file;

/* Chain of typedefs of pointers to empty struct/union types.
   They are chained thru the SYMBOL_VALUE_CHAIN.  */

static struct symbol *opaque_type_chain[HASHSIZE];

/* Simplified internal version of coff symbol table information.  */

struct coff_symbol
  {
    char *c_name;
    int c_symnum;		/* Symbol number of this entry.  */
    int c_naux;			/* 0 if syment only, 1 if syment +
				   auxent, etc.  */
    CORE_ADDR c_value;
    int c_sclass;
    int c_secnum;
    unsigned int c_type;
  };

/* Vector of types defined so far, indexed by their type numbers.  */

static struct type **type_vector;

/* Number of elements allocated for type_vector currently.  */

static int type_vector_length;

/* Initial size of type vector.  Is realloc'd larger if needed, and
   realloc'd down to the size actually used, when completed.  */

#define INITIAL_TYPE_VECTOR_LENGTH 160

static char *linetab = NULL;
static file_ptr linetab_offset;
static file_ptr linetab_size;

static char *stringtab = NULL;

extern void stabsread_clear_cache (void);

static struct type *coff_read_struct_type (int, int, int,
					   struct objfile *);

static struct type *decode_base_type (struct coff_symbol *,
				      unsigned int,
				      union internal_auxent *,
				      struct objfile *);

static struct type *decode_type (struct coff_symbol *, unsigned int,
				 union internal_auxent *,
				 struct objfile *);

static struct type *decode_function_type (struct coff_symbol *,
					  unsigned int,
					  union internal_auxent *,
					  struct objfile *);

static struct type *coff_read_enum_type (int, int, int,
					 struct objfile *);

static struct symbol *process_coff_symbol (struct coff_symbol *,
					   union internal_auxent *,
					   struct objfile *);

static void patch_opaque_types (struct symtab *);

static void enter_linenos (file_ptr, int, int, struct objfile *);

static int init_lineno (bfd *, file_ptr, file_ptr, gdb::unique_xmalloc_ptr<char> *);

static char *getsymname (struct internal_syment *);

static const char *coff_getfilename (union internal_auxent *);

static int init_stringtab (bfd *, file_ptr, gdb::unique_xmalloc_ptr<char> *);

static void read_one_sym (struct coff_symbol *,
			  struct internal_syment *,
			  union internal_auxent *);

static void coff_symtab_read (minimal_symbol_reader &,
			      file_ptr, unsigned int, struct objfile *);

/* We are called once per section from coff_symfile_read.  We
   need to examine each section we are passed, check to see
   if it is something we are interested in processing, and
   if so, stash away some access information for the section.

   FIXME: The section names should not be hardwired strings (what
   should they be?  I don't think most object file formats have enough
   section flags to specify what kind of debug section it is
   -kingdon).  */

static void
coff_locate_sections (bfd *abfd, asection *sectp, void *csip)
{
  struct coff_symfile_info *csi;
  const char *name;

  csi = (struct coff_symfile_info *) csip;
  name = bfd_section_name (sectp);
  if (strcmp (name, ".text") == 0)
    {
      csi->textaddr = bfd_section_vma (sectp);
      csi->textsize += bfd_section_size (sectp);
    }
  else if (startswith (name, ".text"))
    {
      csi->textsize += bfd_section_size (sectp);
    }
  else if (strcmp (name, ".stabstr") == 0)
    {
      csi->stabstrsect = sectp;
    }
  else if (startswith (name, ".stab"))
    {
      const char *s;

      /* We can have multiple .stab sections if linked with
	 --split-by-reloc.  */
      for (s = name + sizeof ".stab" - 1; *s != '\0'; s++)
	if (!isdigit (*s))
	  break;
      if (*s == '\0')
	csi->stabsects->push_back (sectp);
    }
}

/* Return the section_offsets* that CS points to.  */
static int cs_to_section (struct coff_symbol *, struct objfile *);

struct find_targ_sec_arg
  {
    int targ_index;
    asection **resultp;
  };

static void
find_targ_sec (bfd *abfd, asection *sect, void *obj)
{
  struct find_targ_sec_arg *args = (struct find_targ_sec_arg *) obj;

  if (sect->target_index == args->targ_index)
    *args->resultp = sect;
}

/* Return the bfd_section that CS points to.  */
static struct bfd_section*
cs_to_bfd_section (struct coff_symbol *cs, struct objfile *objfile)
{
  asection *sect = NULL;
  struct find_targ_sec_arg args;

  args.targ_index = cs->c_secnum;
  args.resultp = &sect;
  bfd_map_over_sections (objfile->obfd, find_targ_sec, &args);
  return sect;
}

/* Return the section number (SECT_OFF_*) that CS points to.  */
static int
cs_to_section (struct coff_symbol *cs, struct objfile *objfile)
{
  asection *sect = cs_to_bfd_section (cs, objfile);

  if (sect == NULL)
    return SECT_OFF_TEXT (objfile);
  return gdb_bfd_section_index (objfile->obfd, sect);
}

/* Return the address of the section of a COFF symbol.  */

static CORE_ADDR cs_section_address (struct coff_symbol *, bfd *);

static CORE_ADDR
cs_section_address (struct coff_symbol *cs, bfd *abfd)
{
  asection *sect = NULL;
  struct find_targ_sec_arg args;
  CORE_ADDR addr = 0;

  args.targ_index = cs->c_secnum;
  args.resultp = &sect;
  bfd_map_over_sections (abfd, find_targ_sec, &args);
  if (sect != NULL)
    addr = bfd_section_vma (sect);
  return addr;
}

/* Look up a coff type-number index.  Return the address of the slot
   where the type for that index is stored.
   The type-number is in INDEX. 

   This can be used for finding the type associated with that index
   or for associating a new type with the index.  */

static struct type **
coff_lookup_type (int index)
{
  if (index >= type_vector_length)
    {
      int old_vector_length = type_vector_length;

      type_vector_length *= 2;
      if (index /* is still */  >= type_vector_length)
	type_vector_length = index * 2;

      type_vector = (struct type **)
	xrealloc ((char *) type_vector,
		  type_vector_length * sizeof (struct type *));
      memset (&type_vector[old_vector_length], 0,
	 (type_vector_length - old_vector_length) * sizeof (struct type *));
    }
  return &type_vector[index];
}

/* Make sure there is a type allocated for type number index
   and return the type object.
   This can create an empty (zeroed) type object.  */

static struct type *
coff_alloc_type (int index)
{
  struct type **type_addr = coff_lookup_type (index);
  struct type *type = *type_addr;

  /* If we are referring to a type not known at all yet,
     allocate an empty type for it.
     We will fill it in later if we find out how.  */
  if (type == NULL)
    {
      type = alloc_type (coffread_objfile);
      *type_addr = type;
    }
  return type;
}

/* Start a new symtab for a new source file.
   This is called when a COFF ".file" symbol is seen;
   it indicates the start of data for one original source file.  */

static void
coff_start_symtab (struct objfile *objfile, const char *name)
{
  within_function = 0;
  start_symtab (objfile,
		name,
  /* We never know the directory name for COFF.  */
		 NULL,
  /* The start address is irrelevant, since we call
     set_last_source_start_addr in coff_end_symtab.  */
		 0,
  /* Let buildsym.c deduce the language for this symtab.  */
		 language_unknown);
  record_debugformat ("COFF");
}

/* Save the vital information from when starting to read a file,
   for use when closing off the current file.
   NAME is the file name the symbols came from, START_ADDR is the
   first text address for the file, and SIZE is the number of bytes of
   text.  */

static void
complete_symtab (const char *name, CORE_ADDR start_addr, unsigned int size)
{
  set_last_source_file (name);
  current_source_start_addr = start_addr;
  current_source_end_addr = start_addr + size;
}

/* Finish the symbol definitions for one main source file, close off
   all the lexical contexts for that file (creating struct block's for
   them), then make the struct symtab for that file and put it in the
   list of all such.  */

static void
coff_end_symtab (struct objfile *objfile)
{
  set_last_source_start_addr (current_source_start_addr);

  end_symtab (current_source_end_addr, SECT_OFF_TEXT (objfile));

  /* Reinitialize for beginning of new file.  */
  set_last_source_file (NULL);
}

/* The linker sometimes generates some non-function symbols inside
   functions referencing variables imported from another DLL.
   Return nonzero if the given symbol corresponds to one of them.  */

static int
is_import_fixup_symbol (struct coff_symbol *cs,
			enum minimal_symbol_type type)
{
  /* The following is a bit of a heuristic using the characteristics
     of these fixup symbols, but should work well in practice...  */
  int i;

  /* Must be a non-static text symbol.  */
  if (type != mst_text)
    return 0;

  /* Must be a non-function symbol.  */
  if (ISFCN (cs->c_type))
    return 0;

  /* The name must start with "__fu<digits>__".  */
  if (!startswith (cs->c_name, "__fu"))
    return 0;
  if (! isdigit (cs->c_name[4]))
    return 0;
  for (i = 5; cs->c_name[i] != '\0' && isdigit (cs->c_name[i]); i++)
    /* Nothing, just incrementing index past all digits.  */;
  if (cs->c_name[i] != '_' || cs->c_name[i + 1] != '_')
    return 0;

  return 1;
}

static struct minimal_symbol *
record_minimal_symbol (minimal_symbol_reader &reader,
		       struct coff_symbol *cs, CORE_ADDR address,
		       enum minimal_symbol_type type, int section, 
		       struct objfile *objfile)
{
  /* We don't want TDESC entry points in the minimal symbol table.  */
  if (cs->c_name[0] == '@')
    return NULL;

  if (is_import_fixup_symbol (cs, type))
    {
      /* Because the value of these symbols is within a function code
	 range, these symbols interfere with the symbol-from-address
	 reverse lookup; this manifests itself in backtraces, or any
	 other commands that prints symbolic addresses.  Just pretend
	 these symbols do not exist.  */
      return NULL;
    }

  return reader.record_full (cs->c_name, true, address, type, section);
}

/* coff_symfile_init ()
   is the coff-specific initialization routine for reading symbols.
   It is passed a struct objfile which contains, among other things,
   the BFD for the file whose symbols are being read, and a slot for
   a pointer to "private data" which we fill with cookies and other
   treats for coff_symfile_read ().

   We will only be called if this is a COFF or COFF-like file.  BFD
   handles figuring out the format of the file, and code in symtab.c
   uses BFD's determination to vector to us.

   The ultimate result is a new symtab (or, FIXME, eventually a
   psymtab).  */

static void
coff_symfile_init (struct objfile *objfile)
{
  /* Allocate struct to keep track of the symfile.  */
  coff_objfile_data_key.emplace (objfile);

  /* COFF objects may be reordered, so set OBJF_REORDERED.  If we
     find this causes a significant slowdown in gdb then we could
     set it in the debug symbol readers only when necessary.  */
  objfile->flags |= OBJF_REORDERED;
}

/* This function is called for every section; it finds the outer
   limits of the line table (minimum and maximum file offset) so that
   the mainline code can read the whole thing for efficiency.  */

static void
find_linenos (bfd *abfd, struct bfd_section *asect, void *vpinfo)
{
  struct coff_symfile_info *info;
  int size, count;
  file_ptr offset, maxoff;

  /* WARNING WILL ROBINSON!  ACCESSING BFD-PRIVATE DATA HERE!  FIXME!  */
  count = asect->lineno_count;
  /* End of warning.  */

  if (count == 0)
    return;
  size = count * local_linesz;

  info = (struct coff_symfile_info *) vpinfo;
  /* WARNING WILL ROBINSON!  ACCESSING BFD-PRIVATE DATA HERE!  FIXME!  */
  offset = asect->line_filepos;
  /* End of warning.  */

  if (offset < info->min_lineno_offset || info->min_lineno_offset == 0)
    info->min_lineno_offset = offset;

  maxoff = offset + size;
  if (maxoff > info->max_lineno_offset)
    info->max_lineno_offset = maxoff;
}


/* The BFD for this file -- only good while we're actively reading
   symbols into a psymtab or a symtab.  */

static bfd *symfile_bfd;

/* Read a symbol file, after initialization by coff_symfile_init.  */

static void
coff_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
{
  struct coff_symfile_info *info;
  bfd *abfd = objfile->obfd;
  coff_data_type *cdata = coff_data (abfd);
  const char *filename = bfd_get_filename (abfd);
  int val;
  unsigned int num_symbols;
  file_ptr symtab_offset;
  file_ptr stringtab_offset;
  unsigned int stabstrsize;
  
  info = coff_objfile_data_key.get (objfile);
  symfile_bfd = abfd;		/* Kludge for swap routines.  */

  std::vector<asection *> stabsects;
  scoped_restore restore_stabsects
    = make_scoped_restore (&info->stabsects, &stabsects);

/* WARNING WILL ROBINSON!  ACCESSING BFD-PRIVATE DATA HERE!  FIXME!  */
  num_symbols = bfd_get_symcount (abfd);	/* How many syms */
  symtab_offset = cdata->sym_filepos;	/* Symbol table file offset */
  stringtab_offset = symtab_offset +	/* String table file offset */
    num_symbols * cdata->local_symesz;

  /* Set a few file-statics that give us specific information about
     the particular COFF file format we're reading.  */
  local_n_btmask = cdata->local_n_btmask;
  local_n_btshft = cdata->local_n_btshft;
  local_n_tmask = cdata->local_n_tmask;
  local_n_tshift = cdata->local_n_tshift;
  local_linesz = cdata->local_linesz;
  local_symesz = cdata->local_symesz;
  local_auxesz = cdata->local_auxesz;

  /* Allocate space for raw symbol and aux entries, based on their
     space requirements as reported by BFD.  */
  gdb::def_vector<char> temp_storage (cdata->local_symesz
				      + cdata->local_auxesz);
  temp_sym = temp_storage.data ();
  temp_aux = temp_sym + cdata->local_symesz;

  /* We need to know whether this is a PE file, because in PE files,
     unlike standard COFF files, symbol values are stored as offsets
     from the section address, rather than as absolute addresses.
     FIXME: We should use BFD to read the symbol table, and thus avoid
     this problem.  */
  pe_file =
    startswith (bfd_get_target (objfile->obfd), "pe")
    || startswith (bfd_get_target (objfile->obfd), "epoc-pe");

  /* End of warning.  */

  info->min_lineno_offset = 0;
  info->max_lineno_offset = 0;

  /* Only read line number information if we have symbols.

     On Windows NT, some of the system's DLL's have sections with
     PointerToLinenumbers fields that are non-zero, but point at
     random places within the image file.  (In the case I found,
     KERNEL32.DLL's .text section has a line number info pointer that
     points into the middle of the string `lib\\i386\kernel32.dll'.)

     However, these DLL's also have no symbols.  The line number
     tables are meaningless without symbols.  And in fact, GDB never
     uses the line number information unless there are symbols.  So we
     can avoid spurious error messages (and maybe run a little
     faster!) by not even reading the line number table unless we have
     symbols.  */
  scoped_restore restore_linetab = make_scoped_restore (&linetab);
  gdb::unique_xmalloc_ptr<char> linetab_storage;
  if (num_symbols > 0)
    {
      /* Read the line number table, all at once.  */
      bfd_map_over_sections (abfd, find_linenos, (void *) info);

      val = init_lineno (abfd, info->min_lineno_offset,
			 info->max_lineno_offset - info->min_lineno_offset,
			 &linetab_storage);
      if (val < 0)
	error (_("\"%s\": error reading line numbers."), filename);
    }

  /* Now read the string table, all at once.  */

  scoped_restore restore_stringtab = make_scoped_restore (&stringtab);
  gdb::unique_xmalloc_ptr<char> stringtab_storage;
  val = init_stringtab (abfd, stringtab_offset, &stringtab_storage);
  if (val < 0)
    error (_("\"%s\": can't get string table"), filename);

  minimal_symbol_reader reader (objfile);

  /* Now that the executable file is positioned at symbol table,
     process it and define symbols accordingly.  */

  coff_symtab_read (reader, (long) symtab_offset, num_symbols, objfile);

  /* Install any minimal symbols that have been collected as the
     current minimal symbols for this objfile.  */

  reader.install ();

  if (pe_file)
    {
      for (minimal_symbol *msym : objfile->msymbols ())
	{
	  const char *name = msym->linkage_name ();

	  /* If the minimal symbols whose name are prefixed by "__imp_"
	     or "_imp_", get rid of the prefix, and search the minimal
	     symbol in OBJFILE.  Note that 'maintenance print msymbols'
	     shows that type of these "_imp_XXXX" symbols is mst_data.  */
	  if (MSYMBOL_TYPE (msym) == mst_data)
	    {
	      const char *name1 = NULL;

	      if (startswith (name, "_imp_"))
		name1 = name + 5;
	      else if (startswith (name, "__imp_"))
		name1 = name + 6;
	      if (name1 != NULL)
		{
		  int lead = bfd_get_symbol_leading_char (objfile->obfd);
		  struct bound_minimal_symbol found;

		  if (lead != '\0' && *name1 == lead)
		    name1 += 1;

		  found = lookup_minimal_symbol (name1, NULL, objfile);

		  /* If found, there are symbols named "_imp_foo" and "foo"
		     respectively in OBJFILE.  Set the type of symbol "foo"
		     as 'mst_solib_trampoline'.  */
		  if (found.minsym != NULL
		      && MSYMBOL_TYPE (found.minsym) == mst_text)
		    MSYMBOL_TYPE (found.minsym) = mst_solib_trampoline;
		}
	    }
	}
    }

  if (!(objfile->flags & OBJF_READNEVER))
    bfd_map_over_sections (abfd, coff_locate_sections, (void *) info);

  if (!info->stabsects->empty())
    {
      if (!info->stabstrsect)
	{
	  error (_("The debugging information in `%s' is corrupted.\nThe "
		   "file has a `.stabs' section, but no `.stabstr' section."),
		 filename);
	}

      /* FIXME: dubious.  Why can't we use something normal like
	 bfd_get_section_contents?  */
      bfd_seek (abfd, abfd->where, 0);

      stabstrsize = bfd_section_size (info->stabstrsect);

      coffstab_build_psymtabs (objfile,
			       info->textaddr, info->textsize,
			       *info->stabsects,
			       info->stabstrsect->filepos, stabstrsize);
    }
  if (dwarf2_has_info (objfile, NULL))
    {
      /* DWARF2 sections.  */
      dwarf2_build_psymtabs (objfile);
    }

  dwarf2_build_frame_info (objfile);

  /* Try to add separate debug file if no symbols table found.   */
  if (!objfile->has_partial_symbols ())
    {
      std::string debugfile = find_separate_debug_file_by_buildid (objfile);

      if (debugfile.empty ())
	debugfile = find_separate_debug_file_by_debuglink (objfile);

      if (!debugfile.empty ())
	{
	  gdb_bfd_ref_ptr debug_bfd (symfile_bfd_open (debugfile.c_str ()));

	  symbol_file_add_separate (debug_bfd.get (), debugfile.c_str (),
				    symfile_flags, objfile);
	}
    }
}

static void
coff_new_init (struct objfile *ignore)
{
}

/* Perform any local cleanups required when we are done with a
   particular objfile.  I.E, we are in the process of discarding all
   symbol information for an objfile, freeing up all memory held for
   it, and unlinking the objfile struct from the global list of known
   objfiles.  */

static void
coff_symfile_finish (struct objfile *objfile)
{
  /* Let stabs reader clean up.  */
  stabsread_clear_cache ();
}


/* Given pointers to a symbol table in coff style exec file,
   analyze them and create struct symtab's describing the symbols.
   NSYMS is the number of symbols in the symbol table.
   We read them one at a time using read_one_sym ().  */

static void
coff_symtab_read (minimal_symbol_reader &reader,
		  file_ptr symtab_offset, unsigned int nsyms,
		  struct objfile *objfile)
{
  struct gdbarch *gdbarch = objfile->arch ();
  struct context_stack *newobj = nullptr;
  struct coff_symbol coff_symbol;
  struct coff_symbol *cs = &coff_symbol;
  static struct internal_syment main_sym;
  static union internal_auxent main_aux;
  struct coff_symbol fcn_cs_saved;
  static struct internal_syment fcn_sym_saved;
  static union internal_auxent fcn_aux_saved;
  /* A .file is open.  */
  int in_source_file = 0;
  int next_file_symnum = -1;
  /* Name of the current file.  */
  const char *filestring = "";
  int depth = 0;
  int fcn_first_line = 0;
  CORE_ADDR fcn_first_line_addr = 0;
  int fcn_last_line = 0;
  int fcn_start_addr = 0;
  long fcn_line_ptr = 0;
  int val;
  CORE_ADDR tmpaddr;
  struct minimal_symbol *msym;

  scoped_free_pendings free_pending;

  /* Work around a stdio bug in SunOS4.1.1 (this makes me nervous....
     it's hard to know I've really worked around it.  The fix should
     be harmless, anyway).  The symptom of the bug is that the first
     fread (in read_one_sym), will (in my example) actually get data
     from file offset 268, when the fseek was to 264 (and ftell shows
     264).  This causes all hell to break loose.  I was unable to
     reproduce this on a short test program which operated on the same
     file, performing (I think) the same sequence of operations.

     It stopped happening when I put in this (former) rewind().

     FIXME: Find out if this has been reported to Sun, whether it has
     been fixed in a later release, etc.  */

  bfd_seek (objfile->obfd, 0, 0);

  /* Position to read the symbol table.  */
  val = bfd_seek (objfile->obfd, symtab_offset, 0);
  if (val < 0)
    perror_with_name (objfile_name (objfile));

  coffread_objfile = objfile;
  nlist_bfd_global = objfile->obfd;
  nlist_nsyms_global = nsyms;
  set_last_source_file (NULL);
  memset (opaque_type_chain, 0, sizeof opaque_type_chain);

  if (type_vector)		/* Get rid of previous one.  */
    xfree (type_vector);
  type_vector_length = INITIAL_TYPE_VECTOR_LENGTH;
  type_vector = XCNEWVEC (struct type *, type_vector_length);

  coff_start_symtab (objfile, "");

  symnum = 0;
  while (symnum < nsyms)
    {
      QUIT;			/* Make this command interruptable.  */

      read_one_sym (cs, &main_sym, &main_aux);

      if (cs->c_symnum == next_file_symnum && cs->c_sclass != C_FILE)
	{
	  if (get_last_source_file ())
	    coff_end_symtab (objfile);

	  coff_start_symtab (objfile, "_globals_");
	  /* coff_start_symtab will set the language of this symtab to
	     language_unknown, since such a ``file name'' is not
	     recognized.  Override that with the minimal language to
	     allow printing values in this symtab.  */
	  get_current_subfile ()->language = language_minimal;
	  complete_symtab ("_globals_", 0, 0);
	  /* Done with all files, everything from here on out is
	     globals.  */
	}

      /* Special case for file with type declarations only, no
	 text.  */
      if (!get_last_source_file () && SDB_TYPE (cs->c_type)
	  && cs->c_secnum == N_DEBUG)
	complete_symtab (filestring, 0, 0);

      /* Typedefs should not be treated as symbol definitions.  */
      if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF)
	{
	  /* Record all functions -- external and static -- in
	     minsyms.  */
	  int section = cs_to_section (cs, objfile);

	  tmpaddr = cs->c_value;
	  /* Don't record unresolved symbols.  */
	  if (!(cs->c_secnum <= 0 && cs->c_value == 0))
	    record_minimal_symbol (reader, cs, tmpaddr, mst_text,
				   section, objfile);

	  fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
	  fcn_start_addr = tmpaddr;
	  fcn_cs_saved = *cs;
	  fcn_sym_saved = main_sym;
	  fcn_aux_saved = main_aux;
	  continue;
	}

      switch (cs->c_sclass)
	{
	case C_EFCN:
	case C_EXTDEF:
	case C_ULABEL:
	case C_USTATIC:
	case C_LINE:
	case C_ALIAS:
	case C_HIDDEN:
	  complaint (_("Bad n_sclass for symbol %s"),
		     cs->c_name);
	  break;

	case C_FILE:
	  /* c_value field contains symnum of next .file entry in
	     table or symnum of first global after last .file.  */
	  next_file_symnum = cs->c_value;
	  if (cs->c_naux > 0)
	    filestring = coff_getfilename (&main_aux);
	  else
	    filestring = "";

	  /* Complete symbol table for last object file
	     containing debugging information.  */
	  if (get_last_source_file ())
	    {
	      coff_end_symtab (objfile);
	      coff_start_symtab (objfile, filestring);
	    }
	  in_source_file = 1;
	  break;

	  /* C_LABEL is used for labels and static functions.
	     Including it here allows gdb to see static functions when
	     no debug info is available.  */
	case C_LABEL:
	  /* However, labels within a function can make weird
	     backtraces, so filter them out (from phdm@macqel.be).  */
	  if (within_function)
	    break;
	  /* Fall through.  */
	case C_STAT:
	case C_THUMBLABEL:
	case C_THUMBSTAT:
	case C_THUMBSTATFUNC:
	  if (cs->c_name[0] == '.')
	    {
	      if (strcmp (cs->c_name, ".text") == 0)
		{
		  /* FIXME: don't wire in ".text" as section name or
		     symbol name!  */
		  /* Check for in_source_file deals with case of a
		     file with debugging symbols followed by a later
		     file with no symbols.  */
		  if (in_source_file)
		    complete_symtab (filestring,
				     (cs->c_value
				      + objfile->text_section_offset ()),
				     main_aux.x_scn.x_scnlen);
		  in_source_file = 0;
		}
	      /* Flush rest of '.' symbols.  */
	      break;
	    }
	  else if (!SDB_TYPE (cs->c_type)
		   && cs->c_name[0] == 'L'
		   && (startswith (cs->c_name, "LI%")
		       || startswith (cs->c_name, "LF%")
		       || startswith (cs->c_name, "LC%")
		       || startswith (cs->c_name, "LP%")
		       || startswith (cs->c_name, "LPB%")
		       || startswith (cs->c_name, "LBB%")
		       || startswith (cs->c_name, "LBE%")
		       || startswith (cs->c_name, "LPBX%")))
	    /* At least on a 3b1, gcc generates swbeg and string labels
	       that look like this.  Ignore them.  */
	    break;
	  /* For static symbols that don't start with '.'...  */
	  /* Fall through.  */
	case C_THUMBEXT:
	case C_THUMBEXTFUNC:
	case C_EXT:
	  {
	    /* Record it in the minimal symbols regardless of
	       SDB_TYPE.  This parallels what we do for other debug
	       formats, and probably is needed to make
	       print_address_symbolic work right without the (now
	       gone) "set fast-symbolic-addr off" kludge.  */

	    enum minimal_symbol_type ms_type;
	    int sec;
	    CORE_ADDR offset = 0;

	    if (cs->c_secnum == N_UNDEF)
	      {
		/* This is a common symbol.  We used to rely on
		   the target to tell us whether it knows where
		   the symbol has been relocated to, but none of
		   the target implementations actually provided
		   that operation.  So we just ignore the symbol,
		   the same way we would do if we had a target-side
		   symbol lookup which returned no match.  */
		break;
	      }
	    else if (cs->c_secnum == N_ABS)
	      {
		/* Use the correct minimal symbol type (and don't
		   relocate) for absolute values.  */
		ms_type = mst_abs;
		sec = cs_to_section (cs, objfile);
		tmpaddr = cs->c_value;
	      }
	    else
	      {
		asection *bfd_section = cs_to_bfd_section (cs, objfile);

		sec = cs_to_section (cs, objfile);
		tmpaddr = cs->c_value;
		/* Statics in a PE file also get relocated.  */
		if (cs->c_sclass == C_EXT
		    || cs->c_sclass == C_THUMBEXTFUNC
		    || cs->c_sclass == C_THUMBEXT
		    || (pe_file && (cs->c_sclass == C_STAT)))
		  offset = objfile->section_offsets[sec];

		if (bfd_section->flags & SEC_CODE)
		  {
		    ms_type =
		      cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC
		      || cs->c_sclass == C_THUMBEXT ?
		      mst_text : mst_file_text;
		    tmpaddr = gdbarch_addr_bits_remove (gdbarch, tmpaddr);
		  }
		else if (bfd_section->flags & SEC_ALLOC
			 && bfd_section->flags & SEC_LOAD)
		  {
		    ms_type =
		      cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT
		      ? mst_data : mst_file_data;
		  }
		else if (bfd_section->flags & SEC_ALLOC)
		  {
		    ms_type =
		      cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT
		      ? mst_bss : mst_file_bss;
		  }
		else
		  ms_type = mst_unknown;
	      }

	    msym = record_minimal_symbol (reader, cs, tmpaddr, ms_type,
					  sec, objfile);
	    if (msym)
	      gdbarch_coff_make_msymbol_special (gdbarch,
						 cs->c_sclass, msym);

	    if (SDB_TYPE (cs->c_type))
	      {
		struct symbol *sym;

		sym = process_coff_symbol
		  (cs, &main_aux, objfile);
		SYMBOL_VALUE (sym) = tmpaddr + offset;
		sym->set_section_index (sec);
	      }
	  }
	  break;

	case C_FCN:
	  if (strcmp (cs->c_name, ".bf") == 0)
	    {
	      within_function = 1;

	      /* Value contains address of first non-init type
		 code.  */
	      /* main_aux.x_sym.x_misc.x_lnsz.x_lnno
		 contains line number of '{' }.  */
	      if (cs->c_naux != 1)
		complaint (_("`.bf' symbol %d has no aux entry"),
			   cs->c_symnum);
	      fcn_first_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;
	      fcn_first_line_addr = cs->c_value;

	      /* Might want to check that locals are 0 and
		 context_stack_depth is zero, and complain if not.  */

	      depth = 0;
	      newobj = push_context (depth, fcn_start_addr);
	      fcn_cs_saved.c_name = getsymname (&fcn_sym_saved);
	      newobj->name =
		process_coff_symbol (&fcn_cs_saved, 
				     &fcn_aux_saved, objfile);
	    }
	  else if (strcmp (cs->c_name, ".ef") == 0)
	    {
	      if (!within_function)
		error (_("Bad coff function information."));
	      /* The value of .ef is the address of epilogue code;
		 not useful for gdb.  */
	      /* { main_aux.x_sym.x_misc.x_lnsz.x_lnno
		 contains number of lines to '}' */

	      if (outermost_context_p ())
		{	/* We attempted to pop an empty context stack.  */
		  complaint (_("`.ef' symbol without matching `.bf' "
			       "symbol ignored starting at symnum %d"),
			     cs->c_symnum);
		  within_function = 0;
		  break;
		}

	      struct context_stack cstk = pop_context ();
	      /* Stack must be empty now.  */
	      if (!outermost_context_p () || newobj == NULL)
		{
		  complaint (_("Unmatched .ef symbol(s) ignored "
			       "starting at symnum %d"),
			     cs->c_symnum);
		  within_function = 0;
		  break;
		}
	      if (cs->c_naux != 1)
		{
		  complaint (_("`.ef' symbol %d has no aux entry"),
			     cs->c_symnum);
		  fcn_last_line = 0x7FFFFFFF;
		}
	      else
		{
		  fcn_last_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;
		}
	      /* fcn_first_line is the line number of the opening '{'.
		 Do not record it - because it would affect gdb's idea
		 of the line number of the first statement of the
		 function - except for one-line functions, for which
		 it is also the line number of all the statements and
		 of the closing '}', and for which we do not have any
		 other statement-line-number.  */
	      if (fcn_last_line == 1)
		record_line (get_current_subfile (), fcn_first_line,
			     gdbarch_addr_bits_remove (gdbarch,
						       fcn_first_line_addr));
	      else
		enter_linenos (fcn_line_ptr, fcn_first_line,
			       fcn_last_line, objfile);

	      finish_block (cstk.name, cstk.old_blocks,
			    NULL, cstk.start_addr,
			    fcn_cs_saved.c_value
			    + fcn_aux_saved.x_sym.x_misc.x_fsize
			    + objfile->text_section_offset ());
	      within_function = 0;
	    }
	  break;

	case C_BLOCK:
	  if (strcmp (cs->c_name, ".bb") == 0)
	    {
	      tmpaddr = cs->c_value;
	      tmpaddr += objfile->text_section_offset ();
	      push_context (++depth, tmpaddr);
	    }
	  else if (strcmp (cs->c_name, ".eb") == 0)
	    {
	      if (outermost_context_p ())
		{	/* We attempted to pop an empty context stack.  */
		  complaint (_("`.eb' symbol without matching `.bb' "
			       "symbol ignored starting at symnum %d"),
			     cs->c_symnum);
		  break;
		}

	      struct context_stack cstk = pop_context ();
	      if (depth-- != cstk.depth)
		{
		  complaint (_("Mismatched .eb symbol ignored "
			       "starting at symnum %d"),
			     symnum);
		  break;
		}
	      if (*get_local_symbols () && !outermost_context_p ())
		{
		  tmpaddr = cs->c_value + objfile->text_section_offset ();
		  /* Make a block for the local symbols within.  */
		  finish_block (0, cstk.old_blocks, NULL,
				cstk.start_addr, tmpaddr);
		}
	      /* Now pop locals of block just finished.  */
	      *get_local_symbols () = cstk.locals;
	    }
	  break;

	default:
	  process_coff_symbol (cs, &main_aux, objfile);
	  break;
	}
    }

  if ((nsyms == 0) && (pe_file))
    {
      /* We've got no debugging symbols, but it's a portable
	 executable, so try to read the export table.  */
      read_pe_exported_syms (reader, objfile);
    }

  if (get_last_source_file ())
    coff_end_symtab (objfile);

  /* Patch up any opaque types (references to types that are not defined
     in the file where they are referenced, e.g. "struct foo *bar").  */
  {
    for (compunit_symtab *cu : objfile->compunits ())
      {
	for (symtab *s : cu->filetabs ())
	  patch_opaque_types (s);
      }
  }

  coffread_objfile = NULL;
}

/* Routines for reading headers and symbols from executable.  */

/* Read the next symbol, swap it, and return it in both
   internal_syment form, and coff_symbol form.  Also return its first
   auxent, if any, in internal_auxent form, and skip any other
   auxents.  */

static void
read_one_sym (struct coff_symbol *cs,
	      struct internal_syment *sym,
	      union internal_auxent *aux)
{
  int i;
  bfd_size_type bytes;

  cs->c_symnum = symnum;
  bytes = bfd_bread (temp_sym, local_symesz, nlist_bfd_global);
  if (bytes != local_symesz)
    error (_("%s: error reading symbols"), objfile_name (coffread_objfile));
  bfd_coff_swap_sym_in (symfile_bfd, temp_sym, (char *) sym);
  cs->c_naux = sym->n_numaux & 0xff;
  if (cs->c_naux >= 1)
    {
      bytes  = bfd_bread (temp_aux, local_auxesz, nlist_bfd_global);
      if (bytes != local_auxesz)
	error (_("%s: error reading symbols"), objfile_name (coffread_objfile));
      bfd_coff_swap_aux_in (symfile_bfd, temp_aux,
			    sym->n_type, sym->n_sclass,
			    0, cs->c_naux, (char *) aux);
      /* If more than one aux entry, read past it (only the first aux
	 is important).  */
      for (i = 1; i < cs->c_naux; i++)
	{
	  bytes = bfd_bread (temp_aux, local_auxesz, nlist_bfd_global);
	  if (bytes != local_auxesz)
	    error (_("%s: error reading symbols"),
		   objfile_name (coffread_objfile));
	}
    }
  cs->c_name = getsymname (sym);
  cs->c_value = sym->n_value;
  cs->c_sclass = (sym->n_sclass & 0xff);
  cs->c_secnum = sym->n_scnum;
  cs->c_type = (unsigned) sym->n_type;
  if (!SDB_TYPE (cs->c_type))
    cs->c_type = 0;

#if 0
  if (cs->c_sclass & 128)
    printf (_("thumb symbol %s, class 0x%x\n"), cs->c_name, cs->c_sclass);
#endif

  symnum += 1 + cs->c_naux;

  /* The PE file format stores symbol values as offsets within the
     section, rather than as absolute addresses.  We correct that
     here, if the symbol has an appropriate storage class.  FIXME: We
     should use BFD to read the symbols, rather than duplicating the
     work here.  */
  if (pe_file)
    {
      switch (cs->c_sclass)
	{
	case C_EXT:
	case C_THUMBEXT:
	case C_THUMBEXTFUNC:
	case C_SECTION:
	case C_NT_WEAK:
	case C_STAT:
	case C_THUMBSTAT:
	case C_THUMBSTATFUNC:
	case C_LABEL:
	case C_THUMBLABEL:
	case C_BLOCK:
	case C_FCN:
	case C_EFCN:
	  if (cs->c_secnum != 0)
	    cs->c_value += cs_section_address (cs, symfile_bfd);
	  break;
	}
    }
}

/* Support for string table handling.  */

static int
init_stringtab (bfd *abfd, file_ptr offset, gdb::unique_xmalloc_ptr<char> *storage)
{
  long length;
  int val;
  unsigned char lengthbuf[4];

  /* If the file is stripped, the offset might be zero, indicating no
     string table.  Just return with `stringtab' set to null.  */
  if (offset == 0)
    return 0;

  if (bfd_seek (abfd, offset, 0) < 0)
    return -1;

  val = bfd_bread ((char *) lengthbuf, sizeof lengthbuf, abfd);
  length = bfd_h_get_32 (symfile_bfd, lengthbuf);

  /* If no string table is needed, then the file may end immediately
     after the symbols.  Just return with `stringtab' set to null.  */
  if (val != sizeof lengthbuf || length < sizeof lengthbuf)
    return 0;

  storage->reset ((char *) xmalloc (length));
  stringtab = storage->get ();
  /* This is in target format (probably not very useful, and not
     currently used), not host format.  */
  memcpy (stringtab, lengthbuf, sizeof lengthbuf);
  if (length == sizeof length)	/* Empty table -- just the count.  */
    return 0;

  val = bfd_bread (stringtab + sizeof lengthbuf, 
		   length - sizeof lengthbuf, abfd);
  if (val != length - sizeof lengthbuf || stringtab[length - 1] != '\0')
    return -1;

  return 0;
}

static char *
getsymname (struct internal_syment *symbol_entry)
{
  static char buffer[SYMNMLEN + 1];
  char *result;

  if (symbol_entry->_n._n_n._n_zeroes == 0)
    {
      /* FIXME: Probably should be detecting corrupt symbol files by
	 seeing whether offset points to within the stringtab.  */
      result = stringtab + symbol_entry->_n._n_n._n_offset;
    }
  else
    {
      strncpy (buffer, symbol_entry->_n._n_name, SYMNMLEN);
      buffer[SYMNMLEN] = '\0';
      result = buffer;
    }
  return result;
}

/* Extract the file name from the aux entry of a C_FILE symbol.
   Return only the last component of the name.  Result is in static
   storage and is only good for temporary use.  */

static const char *
coff_getfilename (union internal_auxent *aux_entry)
{
  static char buffer[BUFSIZ];
  const char *result;

  if (aux_entry->x_file.x_n.x_n.x_zeroes == 0)
    {
      if (strlen (stringtab + aux_entry->x_file.x_n.x_n.x_offset) >= BUFSIZ)
	internal_error (__FILE__, __LINE__, _("coff file name too long"));
      strcpy (buffer, stringtab + aux_entry->x_file.x_n.x_n.x_offset);
    }
  else
    {
      strncpy (buffer, aux_entry->x_file.x_n.x_fname, FILNMLEN);
      buffer[FILNMLEN] = '\0';
    }
  result = buffer;

  /* FIXME: We should not be throwing away the information about what
     directory.  It should go into dirname of the symtab, or some such
     place.  */
  result = lbasename (result);
  return (result);
}

/* Support for line number handling.  */

/* Read in all the line numbers for fast lookups later.  Leave them in
   external (unswapped) format in memory; we'll swap them as we enter
   them into GDB's data structures.  */

static int
init_lineno (bfd *abfd, file_ptr offset, file_ptr size,
	     gdb::unique_xmalloc_ptr<char> *storage)
{
  int val;

  linetab_offset = offset;
  linetab_size = size;

  if (size == 0)
    return 0;

  if (bfd_seek (abfd, offset, 0) < 0)
    return -1;

  /* Allocate the desired table, plus a sentinel.  */
  storage->reset ((char *) xmalloc (size + local_linesz));
  linetab = storage->get ();

  val = bfd_bread (storage->get (), size, abfd);
  if (val != size)
    return -1;

  /* Terminate it with an all-zero sentinel record.  */
  memset (linetab + size, 0, local_linesz);

  return 0;
}

#if !defined (L_LNNO32)
#define L_LNNO32(lp) ((lp)->l_lnno)
#endif

static void
enter_linenos (file_ptr file_offset, int first_line,
	       int last_line, struct objfile *objfile)
{
  struct gdbarch *gdbarch = objfile->arch ();
  char *rawptr;
  struct internal_lineno lptr;

  if (!linetab)
    return;
  if (file_offset < linetab_offset)
    {
      complaint (_("Line number pointer %s lower than start of line numbers"),
		 plongest (file_offset));
      if (file_offset > linetab_size)	/* Too big to be an offset?  */
	return;
      file_offset += linetab_offset;	/* Try reading at that linetab
					   offset.  */
    }

  rawptr = &linetab[file_offset - linetab_offset];

  /* Skip first line entry for each function.  */
  rawptr += local_linesz;
  /* Line numbers start at one for the first line of the function.  */
  first_line--;

  /* If the line number table is full (e.g. 64K lines in COFF debug
     info), the next function's L_LNNO32 might not be zero, so don't
     overstep the table's end in any case.  */
  while (rawptr <= &linetab[0] + linetab_size)
    {
      bfd_coff_swap_lineno_in (symfile_bfd, rawptr, &lptr);
      rawptr += local_linesz;
      /* The next function, or the sentinel, will have L_LNNO32 zero;
	 we exit.  */
      if (L_LNNO32 (&lptr) && L_LNNO32 (&lptr) <= last_line)
	{
	  CORE_ADDR addr = lptr.l_addr.l_paddr;
	  addr += objfile->text_section_offset ();
	  record_line (get_current_subfile (),
		       first_line + L_LNNO32 (&lptr),
		       gdbarch_addr_bits_remove (gdbarch, addr));
	}
      else
	break;
    }
}

static void
patch_type (struct type *type, struct type *real_type)
{
  struct type *target = TYPE_TARGET_TYPE (type);
  struct type *real_target = TYPE_TARGET_TYPE (real_type);
  int field_size = real_target->num_fields () * sizeof (struct field);

  TYPE_LENGTH (target) = TYPE_LENGTH (real_target);
  target->set_num_fields (real_target->num_fields ());

  field *fields = (struct field *) TYPE_ALLOC (target, field_size);
  memcpy (fields, real_target->fields (), field_size);
  target->set_fields (fields);

  if (real_target->name ())
    {
      /* The previous copy of TYPE_NAME is allocated by
	 process_coff_symbol.  */
      xfree ((char *) target->name ());
      target->set_name (xstrdup (real_target->name ()));
    }
}

/* Patch up all appropriate typedef symbols in the opaque_type_chains
   so that they can be used to print out opaque data structures
   properly.  */

static void
patch_opaque_types (struct symtab *s)
{
  const struct block *b;
  struct block_iterator iter;
  struct symbol *real_sym;

  /* Go through the per-file symbols only.  */
  b = BLOCKVECTOR_BLOCK (s->blockvector (), STATIC_BLOCK);
  ALL_BLOCK_SYMBOLS (b, iter, real_sym)
    {
      /* Find completed typedefs to use to fix opaque ones.
	 Remove syms from the chain when their types are stored,
	 but search the whole chain, as there may be several syms
	 from different files with the same name.  */
      if (real_sym->aclass () == LOC_TYPEDEF
	  && real_sym->domain () == VAR_DOMAIN
	  && real_sym->type ()->code () == TYPE_CODE_PTR
	  && TYPE_LENGTH (TYPE_TARGET_TYPE (real_sym->type ())) != 0)
	{
	  const char *name = real_sym->linkage_name ();
	  int hash = hashname (name);
	  struct symbol *sym, *prev;

	  prev = 0;
	  for (sym = opaque_type_chain[hash]; sym;)
	    {
	      if (name[0] == sym->linkage_name ()[0]
		  && strcmp (name + 1, sym->linkage_name () + 1) == 0)
		{
		  if (prev)
		    {
		      SYMBOL_VALUE_CHAIN (prev) = SYMBOL_VALUE_CHAIN (sym);
		    }
		  else
		    {
		      opaque_type_chain[hash] = SYMBOL_VALUE_CHAIN (sym);
		    }

		  patch_type (sym->type (), real_sym->type ());

		  if (prev)
		    {
		      sym = SYMBOL_VALUE_CHAIN (prev);
		    }
		  else
		    {
		      sym = opaque_type_chain[hash];
		    }
		}
	      else
		{
		  prev = sym;
		  sym = SYMBOL_VALUE_CHAIN (sym);
		}
	    }
	}
    }
}

static int
coff_reg_to_regnum (struct symbol *sym, struct gdbarch *gdbarch)
{
  return gdbarch_sdb_reg_to_regnum (gdbarch, SYMBOL_VALUE (sym));
}

static const struct symbol_register_ops coff_register_funcs = {
  coff_reg_to_regnum
};

/* The "aclass" index for computed COFF symbols.  */

static int coff_register_index;

static struct symbol *
process_coff_symbol (struct coff_symbol *cs,
		     union internal_auxent *aux,
		     struct objfile *objfile)
{
  struct symbol *sym = new (&objfile->objfile_obstack) symbol;
  char *name;

  name = cs->c_name;
  name = EXTERNAL_NAME (name, objfile->obfd);
  sym->set_language (get_current_subfile ()->language,
		     &objfile->objfile_obstack);
  sym->compute_and_set_names (name, true, objfile->per_bfd);

  /* default assumptions */
  SYMBOL_VALUE (sym) = cs->c_value;
  sym->set_domain (VAR_DOMAIN);
  sym->set_section_index (cs_to_section (cs, objfile));

  if (ISFCN (cs->c_type))
    {
      SYMBOL_VALUE (sym) += objfile->text_section_offset ();
      sym->set_type
	(lookup_function_type (decode_function_type (cs, cs->c_type,
						     aux, objfile)));

      sym->set_aclass_index (LOC_BLOCK);
      if (cs->c_sclass == C_STAT || cs->c_sclass == C_THUMBSTAT
	  || cs->c_sclass == C_THUMBSTATFUNC)
	add_symbol_to_list (sym, get_file_symbols ());
      else if (cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT
	       || cs->c_sclass == C_THUMBEXTFUNC)
	add_symbol_to_list (sym, get_global_symbols ());
    }
  else
    {
      sym->set_type (decode_type (cs, cs->c_type, aux, objfile));
      switch (cs->c_sclass)
	{
	case C_NULL:
	  break;

	case C_AUTO:
	  sym->set_aclass_index (LOC_LOCAL);
	  add_symbol_to_list (sym, get_local_symbols ());
	  break;

	case C_THUMBEXT:
	case C_THUMBEXTFUNC:
	case C_EXT:
	  sym->set_aclass_index (LOC_STATIC);
	  SET_SYMBOL_VALUE_ADDRESS (sym,
				    (CORE_ADDR) cs->c_value
				    + objfile->section_offsets[SECT_OFF_TEXT (objfile)]);
	  add_symbol_to_list (sym, get_global_symbols ());
	  break;

	case C_THUMBSTAT:
	case C_THUMBSTATFUNC:
	case C_STAT:
	  sym->set_aclass_index (LOC_STATIC);
	  SET_SYMBOL_VALUE_ADDRESS (sym,
				    (CORE_ADDR) cs->c_value
				    + objfile->section_offsets[SECT_OFF_TEXT (objfile)]);
	  if (within_function)
	    {
	      /* Static symbol of local scope.  */
	      add_symbol_to_list (sym, get_local_symbols ());
	    }
	  else
	    {
	      /* Static symbol at top level of file.  */
	      add_symbol_to_list (sym, get_file_symbols ());
	    }
	  break;

#ifdef C_GLBLREG		/* AMD coff */
	case C_GLBLREG:
#endif
	case C_REG:
	  sym->set_aclass_index (coff_register_index);
	  SYMBOL_VALUE (sym) = cs->c_value;
	  add_symbol_to_list (sym, get_local_symbols ());
	  break;

	case C_THUMBLABEL:
	case C_LABEL:
	  break;

	case C_ARG:
	  sym->set_aclass_index (LOC_ARG);
	  sym->set_is_argument (1);
	  add_symbol_to_list (sym, get_local_symbols ());
	  break;

	case C_REGPARM:
	  sym->set_aclass_index (coff_register_index);
	  sym->set_is_argument (1);
	  SYMBOL_VALUE (sym) = cs->c_value;
	  add_symbol_to_list (sym, get_local_symbols ());
	  break;

	case C_TPDEF:
	  sym->set_aclass_index (LOC_TYPEDEF);
	  sym->set_domain (VAR_DOMAIN);

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

		     Sigh.

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

	  /* Keep track of any type which points to empty structured
	     type, so it can be filled from a definition from another
	     file.  A simple forward reference (TYPE_CODE_UNDEF) is
	     not an empty structured type, though; the forward
	     references work themselves out via the magic of
	     coff_lookup_type.  */
	  if (sym->type ()->code () == TYPE_CODE_PTR
	      && TYPE_LENGTH (TYPE_TARGET_TYPE (sym->type ())) == 0
	      && TYPE_TARGET_TYPE (sym->type ())->code ()
	      != TYPE_CODE_UNDEF)
	    {
	      int i = hashname (sym->linkage_name ());

	      SYMBOL_VALUE_CHAIN (sym) = opaque_type_chain[i];
	      opaque_type_chain[i] = sym;
	    }
	  add_symbol_to_list (sym, get_file_symbols ());
	  break;

	case C_STRTAG:
	case C_UNTAG:
	case C_ENTAG:
	  sym->set_aclass_index (LOC_TYPEDEF);
	  sym->set_domain (STRUCT_DOMAIN);

	  /* Some compilers try to be helpful by inventing "fake"
	     names for anonymous enums, structures, and unions, like
	     "~0fake" or ".0fake".  Thanks, but no thanks...  */
	  if (sym->type ()->name () == 0)
	    if (sym->linkage_name () != NULL
		&& *sym->linkage_name () != '~'
		&& *sym->linkage_name () != '.')
	      sym->type ()->set_name (xstrdup (sym->linkage_name ()));

	  add_symbol_to_list (sym, get_file_symbols ());
	  break;

	default:
	  break;
	}
    }
  return sym;
}

/* Decode a coff type specifier;  return the type that is meant.  */

static struct type *
decode_type (struct coff_symbol *cs, unsigned int c_type,
	     union internal_auxent *aux, struct objfile *objfile)
{
  struct type *type = 0;
  unsigned int new_c_type;

  if (c_type & ~N_BTMASK)
    {
      new_c_type = DECREF (c_type);
      if (ISPTR (c_type))
	{
	  type = decode_type (cs, new_c_type, aux, objfile);
	  type = lookup_pointer_type (type);
	}
      else if (ISFCN (c_type))
	{
	  type = decode_type (cs, new_c_type, aux, objfile);
	  type = lookup_function_type (type);
	}
      else if (ISARY (c_type))
	{
	  int i, n;
	  unsigned short *dim;
	  struct type *base_type, *index_type, *range_type;

	  /* Define an array type.  */
	  /* auxent refers to array, not base type.  */
	  if (aux->x_sym.x_tagndx.l == 0)
	    cs->c_naux = 0;

	  /* Shift the indices down.  */
	  dim = &aux->x_sym.x_fcnary.x_ary.x_dimen[0];
	  i = 1;
	  n = dim[0];
	  for (i = 0; *dim && i < DIMNUM - 1; i++, dim++)
	    *dim = *(dim + 1);
	  *dim = 0;

	  base_type = decode_type (cs, new_c_type, aux, objfile);
	  index_type = objfile_type (objfile)->builtin_int;
	  range_type
	    = create_static_range_type (NULL, index_type, 0, n - 1);
	  type =
	    create_array_type (NULL, base_type, range_type);
	}
      return type;
    }

  /* Reference to existing type.  This only occurs with the struct,
     union, and enum types.  EPI a29k coff fakes us out by producing
     aux entries with a nonzero x_tagndx for definitions of structs,
     unions, and enums, so we have to check the c_sclass field.  SCO
     3.2v4 cc gets confused with pointers to pointers to defined
     structs, and generates negative x_tagndx fields.  */
  if (cs->c_naux > 0 && aux->x_sym.x_tagndx.l != 0)
    {
      if (cs->c_sclass != C_STRTAG
	  && cs->c_sclass != C_UNTAG
	  && cs->c_sclass != C_ENTAG
	  && aux->x_sym.x_tagndx.l >= 0)
	{
	  type = coff_alloc_type (aux->x_sym.x_tagndx.l);
	  return type;
	}
      else
	{
	  complaint (_("Symbol table entry for %s has bad tagndx value"),
		     cs->c_name);
	  /* And fall through to decode_base_type...  */
	}
    }

  return decode_base_type (cs, BTYPE (c_type), aux, objfile);
}

/* Decode a coff type specifier for function definition;
   return the type that the function returns.  */

static struct type *
decode_function_type (struct coff_symbol *cs, 
		      unsigned int c_type,
		      union internal_auxent *aux, 
		      struct objfile *objfile)
{
  if (aux->x_sym.x_tagndx.l == 0)
    cs->c_naux = 0;	/* auxent refers to function, not base
			   type.  */

  return decode_type (cs, DECREF (c_type), aux, objfile);
}

/* Basic C types.  */

static struct type *
decode_base_type (struct coff_symbol *cs, 
		  unsigned int c_type,
		  union internal_auxent *aux, 
		  struct objfile *objfile)
{
  struct gdbarch *gdbarch = objfile->arch ();
  struct type *type;

  switch (c_type)
    {
    case T_NULL:
      /* Shows up with "void (*foo)();" structure members.  */
      return objfile_type (objfile)->builtin_void;

#ifdef T_VOID
    case T_VOID:
      /* Intel 960 COFF has this symbol and meaning.  */
      return objfile_type (objfile)->builtin_void;
#endif

    case T_CHAR:
      return objfile_type (objfile)->builtin_char;

    case T_SHORT:
      return objfile_type (objfile)->builtin_short;

    case T_INT:
      return objfile_type (objfile)->builtin_int;

    case T_LONG:
      if (cs->c_sclass == C_FIELD
	  && aux->x_sym.x_misc.x_lnsz.x_size
	     > gdbarch_long_bit (gdbarch))
	return objfile_type (objfile)->builtin_long_long;
      else
	return objfile_type (objfile)->builtin_long;

    case T_FLOAT:
      return objfile_type (objfile)->builtin_float;

    case T_DOUBLE:
      return objfile_type (objfile)->builtin_double;

    case T_LNGDBL:
      return objfile_type (objfile)->builtin_long_double;

    case T_STRUCT:
      if (cs->c_naux != 1)
	{
	  /* Anonymous structure type.  */
	  type = coff_alloc_type (cs->c_symnum);
	  type->set_code (TYPE_CODE_STRUCT);
	  type->set_name (NULL);
	  INIT_CPLUS_SPECIFIC (type);
	  TYPE_LENGTH (type) = 0;
	  type->set_fields (nullptr);
	  type->set_num_fields (0);
	}
      else
	{
	  type = coff_read_struct_type (cs->c_symnum,
					aux->x_sym.x_misc.x_lnsz.x_size,
					aux->x_sym.x_fcnary.x_fcn.x_endndx.l,
					objfile);
	}
      return type;

    case T_UNION:
      if (cs->c_naux != 1)
	{
	  /* Anonymous union type.  */
	  type = coff_alloc_type (cs->c_symnum);
	  type->set_name (NULL);
	  INIT_CPLUS_SPECIFIC (type);
	  TYPE_LENGTH (type) = 0;
	  type->set_fields (nullptr);
	  type->set_num_fields (0);
	}
      else
	{
	  type = coff_read_struct_type (cs->c_symnum,
					aux->x_sym.x_misc.x_lnsz.x_size,
					aux->x_sym.x_fcnary.x_fcn.x_endndx.l,
					objfile);
	}
      type->set_code (TYPE_CODE_UNION);
      return type;

    case T_ENUM:
      if (cs->c_naux != 1)
	{
	  /* Anonymous enum type.  */
	  type = coff_alloc_type (cs->c_symnum);
	  type->set_code (TYPE_CODE_ENUM);
	  type->set_name (NULL);
	  TYPE_LENGTH (type) = 0;
	  type->set_fields (nullptr);
	  type->set_num_fields (0);
	}
      else
	{
	  type = coff_read_enum_type (cs->c_symnum,
				      aux->x_sym.x_misc.x_lnsz.x_size,
				      aux->x_sym.x_fcnary.x_fcn.x_endndx.l,
				      objfile);
	}
      return type;

    case T_MOE:
      /* Shouldn't show up here.  */
      break;

    case T_UCHAR:
      return objfile_type (objfile)->builtin_unsigned_char;

    case T_USHORT:
      return objfile_type (objfile)->builtin_unsigned_short;

    case T_UINT:
      return objfile_type (objfile)->builtin_unsigned_int;

    case T_ULONG:
      if (cs->c_sclass == C_FIELD
	  && aux->x_sym.x_misc.x_lnsz.x_size
	     > gdbarch_long_bit (gdbarch))
	return objfile_type (objfile)->builtin_unsigned_long_long;
      else
	return objfile_type (objfile)->builtin_unsigned_long;
    }
  complaint (_("Unexpected type for symbol %s"), cs->c_name);
  return objfile_type (objfile)->builtin_void;
}

/* This page contains subroutines of read_type.  */

/* Read the description of a structure (or union type) and return an
   object describing the type.  */

static struct type *
coff_read_struct_type (int index, int length, int lastsym,
		       struct objfile *objfile)
{
  struct nextfield
    {
      struct nextfield *next;
      struct field field;
    };

  struct type *type;
  struct nextfield *list = 0;
  struct nextfield *newobj;
  int nfields = 0;
  int n;
  char *name;
  struct coff_symbol member_sym;
  struct coff_symbol *ms = &member_sym;
  struct internal_syment sub_sym;
  union internal_auxent sub_aux;
  int done = 0;

  type = coff_alloc_type (index);
  type->set_code (TYPE_CODE_STRUCT);
  INIT_CPLUS_SPECIFIC (type);
  TYPE_LENGTH (type) = length;

  while (!done && symnum < lastsym && symnum < nlist_nsyms_global)
    {
      read_one_sym (ms, &sub_sym, &sub_aux);
      name = ms->c_name;
      name = EXTERNAL_NAME (name, objfile->obfd);

      switch (ms->c_sclass)
	{
	case C_MOS:
	case C_MOU:

	  /* Get space to record the next field's data.  */
	  newobj = XALLOCA (struct nextfield);
	  newobj->next = list;
	  list = newobj;

	  /* Save the data.  */
	  list->field.set_name (obstack_strdup (&objfile->objfile_obstack,
						name));
	  list->field.set_type (decode_type (ms, ms->c_type, &sub_aux,
					     objfile));
	  list->field.set_loc_bitpos (8 * ms->c_value);
	  FIELD_BITSIZE (list->field) = 0;
	  nfields++;
	  break;

	case C_FIELD:

	  /* Get space to record the next field's data.  */
	  newobj = XALLOCA (struct nextfield);
	  newobj->next = list;
	  list = newobj;

	  /* Save the data.  */
	  list->field.set_name (obstack_strdup (&objfile->objfile_obstack,
						name));
	  list->field.set_type (decode_type (ms, ms->c_type, &sub_aux,
					     objfile));
	  list->field.set_loc_bitpos (ms->c_value);
	  FIELD_BITSIZE (list->field) = sub_aux.x_sym.x_misc.x_lnsz.x_size;
	  nfields++;
	  break;

	case C_EOS:
	  done = 1;
	  break;
	}
    }
  /* Now create the vector of fields, and record how big it is.  */

  type->set_num_fields (nfields);
  type->set_fields
    ((struct field *) TYPE_ALLOC (type, sizeof (struct field) * nfields));

  /* Copy the saved-up fields into the field vector.  */

  for (n = nfields; list; list = list->next)
    type->field (--n) = list->field;

  return type;
}

/* Read a definition of an enumeration type,
   and create and return a suitable type object.
   Also defines the symbols that represent the values of the type.  */

static struct type *
coff_read_enum_type (int index, int length, int lastsym,
		     struct objfile *objfile)
{
  struct gdbarch *gdbarch = objfile->arch ();
  struct symbol *sym;
  struct type *type;
  int nsyms = 0;
  int done = 0;
  struct pending **symlist;
  struct coff_symbol member_sym;
  struct coff_symbol *ms = &member_sym;
  struct internal_syment sub_sym;
  union internal_auxent sub_aux;
  struct pending *osyms, *syms;
  int o_nsyms;
  int n;
  char *name;
  int unsigned_enum = 1;

  type = coff_alloc_type (index);
  if (within_function)
    symlist = get_local_symbols ();
  else
    symlist = get_file_symbols ();
  osyms = *symlist;
  o_nsyms = osyms ? osyms->nsyms : 0;

  while (!done && symnum < lastsym && symnum < nlist_nsyms_global)
    {
      read_one_sym (ms, &sub_sym, &sub_aux);
      name = ms->c_name;
      name = EXTERNAL_NAME (name, objfile->obfd);

      switch (ms->c_sclass)
	{
	case C_MOE:
	  sym = new (&objfile->objfile_obstack) symbol;

	  name = obstack_strdup (&objfile->objfile_obstack, name);
	  sym->set_linkage_name (name);
	  sym->set_aclass_index (LOC_CONST);
	  sym->set_domain (VAR_DOMAIN);
	  SYMBOL_VALUE (sym) = ms->c_value;
	  add_symbol_to_list (sym, symlist);
	  nsyms++;
	  break;

	case C_EOS:
	  /* Sometimes the linker (on 386/ix 2.0.2 at least) screws
	     up the count of how many symbols to read.  So stop
	     on .eos.  */
	  done = 1;
	  break;
	}
    }

  /* Now fill in the fields of the type-structure.  */

  if (length > 0)
    TYPE_LENGTH (type) = length;
  else /* Assume ints.  */
    TYPE_LENGTH (type) = gdbarch_int_bit (gdbarch) / TARGET_CHAR_BIT;
  type->set_code (TYPE_CODE_ENUM);
  type->set_num_fields (nsyms);
  type->set_fields
    ((struct field *) TYPE_ALLOC (type, sizeof (struct field) * nsyms));

  /* Find the symbols for the values and put them into the type.
     The symbols can be found in the symlist that we put them on
     to cause them to be defined.  osyms contains the old value
     of that symlist; everything up to there was defined by us.  */
  /* Note that we preserve the order of the enum constants, so
     that in something like "enum {FOO, LAST_THING=FOO}" we print
     FOO, not LAST_THING.  */

  for (syms = *symlist, n = 0; syms; syms = syms->next)
    {
      int j = 0;

      if (syms == osyms)
	j = o_nsyms;
      for (; j < syms->nsyms; j++, n++)
	{
	  struct symbol *xsym = syms->symbol[j];

	  xsym->set_type (type);
	  type->field (n).set_name (xsym->linkage_name ());
	  type->field (n).set_loc_enumval (SYMBOL_VALUE (xsym));
	  if (SYMBOL_VALUE (xsym) < 0)
	    unsigned_enum = 0;
	  TYPE_FIELD_BITSIZE (type, n) = 0;
	}
      if (syms == osyms)
	break;
    }

  if (unsigned_enum)
    type->set_is_unsigned (true);

  return type;
}

/* Register our ability to parse symbols for coff BFD files.  */

static const struct sym_fns coff_sym_fns =
{
  coff_new_init,		/* sym_new_init: init anything gbl to
				   entire symtab */
  coff_symfile_init,		/* sym_init: read initial info, setup
				   for sym_read() */
  coff_symfile_read,		/* sym_read: read a symbol file into
				   symtab */
  coff_symfile_finish,		/* sym_finish: finished with file,
				   cleanup */
  default_symfile_offsets,	/* sym_offsets: xlate external to
				   internal form */
  default_symfile_segments,	/* sym_segments: Get segment
				   information from a file */
  NULL,                         /* sym_read_linetable  */

  default_symfile_relocate,	/* sym_relocate: Relocate a debug
				   section.  */
  NULL,				/* sym_probe_fns */
};

void _initialize_coffread ();
void
_initialize_coffread ()
{
  add_symtab_fns (bfd_target_coff_flavour, &coff_sym_fns);

  coff_register_index
    = register_symbol_register_impl (LOC_REGISTER, &coff_register_funcs);
}
