/* Read a symbol table in MIPS' format (Third-Eye).
   Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
   1998, 1999, 2000, 2001
   Free Software Foundation, Inc.
   Contributed by Alessandro Forin (af@cs.cmu.edu) at CMU.  Major work
   by Per Bothner, John Gilmore and Ian Lance Taylor at Cygnus Support.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 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, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

/* Read symbols from an ECOFF file.  Most of the work is done in
   mdebugread.c.  */

#include "defs.h"
#include "gdb_string.h"
#include "bfd.h"
#include "symtab.h"
#include "symfile.h"
#include "objfiles.h"
#include "buildsym.h"
#include "stabsread.h"

#include "coff/sym.h"
#include "coff/internal.h"
#include "coff/ecoff.h"
#include "libcoff.h"		/* Private BFD COFF information.  */
#include "libecoff.h"		/* Private BFD ECOFF information.  */
#include "elf/common.h"
#include "elf/mips.h"

extern void _initialize_mipsread (void);

static void mipscoff_new_init (struct objfile *);

static void mipscoff_symfile_init (struct objfile *);

static void mipscoff_symfile_read (struct objfile *, int);

static void mipscoff_symfile_finish (struct objfile *);

static void
read_alphacoff_dynamic_symtab (struct section_offsets *,
			       struct objfile *objfile);

/* Initialize anything that needs initializing when a completely new
   symbol file is specified (not just adding some symbols from another
   file, e.g. a shared library).  */

extern CORE_ADDR sigtramp_address;

static void
mipscoff_new_init (struct objfile *ignore)
{
  sigtramp_address = 0;
  stabsread_new_init ();
  buildsym_new_init ();
}

/* Initialize to read a symbol file (nothing to do).  */

static void
mipscoff_symfile_init (struct objfile *objfile)
{
}

/* Read a symbol file from a file.  */

static void
mipscoff_symfile_read (struct objfile *objfile, int mainline)
{
  bfd *abfd = objfile->obfd;
  struct cleanup *back_to;

  init_minimal_symbol_collection ();
  back_to = make_cleanup_discard_minimal_symbols ();

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

  if (!((*ecoff_backend (abfd)->debug_swap.read_debug_info)
	(abfd, (asection *) NULL, &ecoff_data (abfd)->debug_info)))
    error ("Error reading symbol table: %s", bfd_errmsg (bfd_get_error ()));

  mdebug_build_psymtabs (objfile, &ecoff_backend (abfd)->debug_swap,
			 &ecoff_data (abfd)->debug_info);

  /* Add alpha coff dynamic symbols.  */

  read_alphacoff_dynamic_symtab (objfile->section_offsets, objfile);

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

  install_minimal_symbols (objfile);

  /* If the entry_file bounds are still unknown after processing the
     partial symbols, then try to set them from the minimal symbols
     surrounding the entry_point.  */

  if (mainline
      && objfile->ei.entry_point != INVALID_ENTRY_POINT
      && objfile->ei.entry_file_lowpc == INVALID_ENTRY_LOWPC)
    {
      struct minimal_symbol *m;

      m = lookup_minimal_symbol_by_pc (objfile->ei.entry_point);
      if (m && SYMBOL_NAME (m + 1))
	{
	  objfile->ei.entry_file_lowpc = SYMBOL_VALUE_ADDRESS (m);
	  objfile->ei.entry_file_highpc = SYMBOL_VALUE_ADDRESS (m + 1);
	}
    }

  do_cleanups (back_to);
}

/* Perform any local cleanups required when we are done with a
   particular objfile.  */

static void
mipscoff_symfile_finish (struct objfile *objfile)
{
}

/* Alpha OSF/1 encapsulates the dynamic symbols in ELF format in a
   standard coff section.  The ELF format for the symbols differs from
   the format defined in elf/external.h. It seems that a normal ELF 32 bit
   format is used, and the representation only changes because longs are
   64 bit on the alpha. In addition, the handling of text/data section
   indices for symbols is different from the ELF ABI.
   As the BFD linker currently does not support dynamic linking on the alpha,
   there seems to be no reason to pollute BFD with another mixture of object
   file formats for now.  */

/* Format of an alpha external ELF symbol.  */

typedef struct
{
  unsigned char st_name[4];	/* Symbol name, index in string tbl */
  unsigned char st_pad[4];	/* Pad to long word boundary */
  unsigned char st_value[8];	/* Value of the symbol */
  unsigned char st_size[4];	/* Associated symbol size */
  unsigned char st_info[1];	/* Type and binding attributes */
  unsigned char st_other[1];	/* No defined meaning, 0 */
  unsigned char st_shndx[2];	/* Associated section index */
}
Elfalpha_External_Sym;

/* Format of an alpha external ELF dynamic info structure.  */

typedef struct
  {
    unsigned char d_tag[4];	/* Tag */
    unsigned char d_pad[4];	/* Pad to long word boundary */
    union
      {
	unsigned char d_ptr[8];	/* Pointer value */
	unsigned char d_val[4];	/* Integer value */
      }
    d_un;
  }
Elfalpha_External_Dyn;

/* Struct to obtain the section pointers for alpha dynamic symbol info.  */

struct alphacoff_dynsecinfo
  {
    asection *sym_sect;		/* Section pointer for .dynsym section */
    asection *str_sect;		/* Section pointer for .dynstr section */
    asection *dyninfo_sect;	/* Section pointer for .dynamic section */
    asection *got_sect;		/* Section pointer for .got section */
  };

/* We are called once per section from read_alphacoff_dynamic_symtab.
   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.  */

static void
alphacoff_locate_sections (bfd *ignore_abfd, asection *sectp, void *sip)
{
  register struct alphacoff_dynsecinfo *si;

  si = (struct alphacoff_dynsecinfo *) sip;

  if (STREQ (sectp->name, ".dynsym"))
    {
      si->sym_sect = sectp;
    }
  else if (STREQ (sectp->name, ".dynstr"))
    {
      si->str_sect = sectp;
    }
  else if (STREQ (sectp->name, ".dynamic"))
    {
      si->dyninfo_sect = sectp;
    }
  else if (STREQ (sectp->name, ".got"))
    {
      si->got_sect = sectp;
    }
}

/* Scan an alpha dynamic symbol table for symbols of interest and
   add them to the minimal symbol table.  */

static void
read_alphacoff_dynamic_symtab (struct section_offsets *section_offsets,
			       struct objfile *objfile)
{
  bfd *abfd = objfile->obfd;
  struct alphacoff_dynsecinfo si;
  char *sym_secptr;
  char *str_secptr;
  char *dyninfo_secptr;
  char *got_secptr;
  bfd_size_type sym_secsize;
  bfd_size_type str_secsize;
  bfd_size_type dyninfo_secsize;
  bfd_size_type got_secsize;
  int sym_count;
  int i;
  int stripped;
  Elfalpha_External_Sym *x_symp;
  char *dyninfo_p;
  char *dyninfo_end;
  int got_entry_size = 8;
  int dt_mips_local_gotno = -1;
  int dt_mips_gotsym = -1;
  struct cleanup *cleanups;


  /* We currently only know how to handle alpha dynamic symbols.  */
  if (bfd_get_arch (abfd) != bfd_arch_alpha)
    return;

  /* Locate the dynamic symbols sections and read them in.  */
  memset ((char *) &si, 0, sizeof (si));
  bfd_map_over_sections (abfd, alphacoff_locate_sections, (void *) & si);
  if (si.sym_sect == NULL
      || si.str_sect == NULL
      || si.dyninfo_sect == NULL
      || si.got_sect == NULL)
    return;

  sym_secsize = bfd_get_section_size_before_reloc (si.sym_sect);
  str_secsize = bfd_get_section_size_before_reloc (si.str_sect);
  dyninfo_secsize = bfd_get_section_size_before_reloc (si.dyninfo_sect);
  got_secsize = bfd_get_section_size_before_reloc (si.got_sect);
  sym_secptr = xmalloc (sym_secsize);
  cleanups = make_cleanup (free, sym_secptr);
  str_secptr = xmalloc (str_secsize);
  make_cleanup (free, str_secptr);
  dyninfo_secptr = xmalloc (dyninfo_secsize);
  make_cleanup (free, dyninfo_secptr);
  got_secptr = xmalloc (got_secsize);
  make_cleanup (free, got_secptr);

  if (!bfd_get_section_contents (abfd, si.sym_sect, sym_secptr,
				 (file_ptr) 0, sym_secsize))
    return;
  if (!bfd_get_section_contents (abfd, si.str_sect, str_secptr,
				 (file_ptr) 0, str_secsize))
    return;
  if (!bfd_get_section_contents (abfd, si.dyninfo_sect, dyninfo_secptr,
				 (file_ptr) 0, dyninfo_secsize))
    return;
  if (!bfd_get_section_contents (abfd, si.got_sect, got_secptr,
				 (file_ptr) 0, got_secsize))
    return;

  /* Find the number of local GOT entries and the index for the
     the first dynamic symbol in the GOT. */
  for (dyninfo_p = dyninfo_secptr, dyninfo_end = dyninfo_p + dyninfo_secsize;
       dyninfo_p < dyninfo_end;
       dyninfo_p += sizeof (Elfalpha_External_Dyn))
    {
      Elfalpha_External_Dyn *x_dynp = (Elfalpha_External_Dyn *) dyninfo_p;
      long dyn_tag;

      dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_tag);
      if (dyn_tag == DT_NULL)
	break;
      else if (dyn_tag == DT_MIPS_LOCAL_GOTNO)
	{
	  if (dt_mips_local_gotno < 0)
	    dt_mips_local_gotno
	      = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_un.d_val);
	}
      else if (dyn_tag == DT_MIPS_GOTSYM)
	{
	  if (dt_mips_gotsym < 0)
	    dt_mips_gotsym
	      = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_un.d_val);
	}
    }
  if (dt_mips_local_gotno < 0 || dt_mips_gotsym < 0)
    return;

  /* Scan all dynamic symbols and enter them into the minimal symbol table
     if appropriate.  */
  sym_count = sym_secsize / sizeof (Elfalpha_External_Sym);
  stripped = (bfd_get_symcount (abfd) == 0);

  /* Skip first symbol, which is a null dummy.  */
  for (i = 1, x_symp = (Elfalpha_External_Sym *) sym_secptr + 1;
       i < sym_count;
       i++, x_symp++)
    {
      unsigned long strx;
      char *name;
      bfd_vma sym_value;
      unsigned char sym_info;
      unsigned int sym_shndx;
      int isglobal;
      enum minimal_symbol_type ms_type;

      strx = bfd_h_get_32 (abfd, (bfd_byte *) x_symp->st_name);
      if (strx >= str_secsize)
	continue;
      name = str_secptr + strx;
      if (*name == '\0' || *name == '.')
	continue;

      sym_value = bfd_h_get_64 (abfd, (bfd_byte *) x_symp->st_value);
      sym_info = bfd_h_get_8 (abfd, (bfd_byte *) x_symp->st_info);
      sym_shndx = bfd_h_get_16 (abfd, (bfd_byte *) x_symp->st_shndx);
      isglobal = (ELF_ST_BIND (sym_info) == STB_GLOBAL);

      if (sym_shndx == SHN_UNDEF)
	{
	  /* Handle undefined functions which are defined in a shared
	     library.  */
	  if (ELF_ST_TYPE (sym_info) != STT_FUNC
	      || ELF_ST_BIND (sym_info) != STB_GLOBAL)
	    continue;

	  ms_type = mst_solib_trampoline;

	  /* If sym_value is nonzero, it points to the shared library
	     trampoline entry, which is what we are looking for.

	     If sym_value is zero, then we have to get the GOT entry
	     for the symbol.
	     If the GOT entry is nonzero, it represents the quickstart
	     address of the function and we use that as the symbol value.

	     If the GOT entry is zero, the function address has to be resolved
	     by the runtime loader before the executable is started.
	     We are unable to find any meaningful address for these
	     functions in the executable file, so we skip them.  */
	  if (sym_value == 0)
	    {
	      int got_entry_offset =
	      (i - dt_mips_gotsym + dt_mips_local_gotno) * got_entry_size;

	      if (got_entry_offset < 0 || got_entry_offset >= got_secsize)
		continue;
	      sym_value =
		bfd_h_get_64 (abfd,
			      (bfd_byte *) (got_secptr + got_entry_offset));
	      if (sym_value == 0)
		continue;
	    }
	}
      else
	{
	  /* Symbols defined in the executable itself. We only care about
	     them if this is a stripped executable, otherwise they have
	     been retrieved from the normal symbol table already.  */
	  if (!stripped)
	    continue;

	  if (sym_shndx == SHN_MIPS_TEXT)
	    {
	      if (isglobal)
		ms_type = mst_text;
	      else
		ms_type = mst_file_text;
	      sym_value += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
	    }
	  else if (sym_shndx == SHN_MIPS_DATA)
	    {
	      if (isglobal)
		ms_type = mst_data;
	      else
		ms_type = mst_file_data;
	      sym_value += ANOFFSET (section_offsets, SECT_OFF_DATA (objfile));
	    }
	  else if (sym_shndx == SHN_MIPS_ACOMMON)
	    {
	      if (isglobal)
		ms_type = mst_bss;
	      else
		ms_type = mst_file_bss;
	      sym_value += ANOFFSET (section_offsets, SECT_OFF_BSS (objfile));
	    }
	  else if (sym_shndx == SHN_ABS)
	    {
	      ms_type = mst_abs;
	    }
	  else
	    {
	      continue;
	    }
	}

      prim_record_minimal_symbol (name, sym_value, ms_type, objfile);
    }

  do_cleanups (cleanups);
}

/* Initialization */

static struct sym_fns ecoff_sym_fns =
{
  bfd_target_ecoff_flavour,
  mipscoff_new_init,		/* sym_new_init: init anything gbl to entire symtab */
  mipscoff_symfile_init,	/* sym_init: read initial info, setup for sym_read() */
  mipscoff_symfile_read,	/* sym_read: read a symbol file into symtab */
  mipscoff_symfile_finish,	/* sym_finish: finished with file, cleanup */
  default_symfile_offsets,	/* sym_offsets: dummy FIXME til implem sym reloc */
  NULL				/* next: pointer to next struct sym_fns */
};

void
_initialize_mipsread (void)
{
  add_symtab_fns (&ecoff_sym_fns);
}
