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

   Copyright (C) 1986-2016 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 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/>.  */

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

#include "defs.h"
#include "bfd.h"
#include "symtab.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/internal.h"
#include "elf/mips.h"

#include "psymtab.h"

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).  */

static void
mipscoff_new_init (struct objfile *ignore)
{
  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 symfile_flags)
{
  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);
  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 table.  */
  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)
{
  struct alphacoff_dynsecinfo *si;

  si = (struct alphacoff_dynsecinfo *) sip;

  if (strcmp (sectp->name, ".dynsym") == 0)
    si->sym_sect = sectp;
  else if (strcmp (sectp->name, ".dynstr") == 0)
    si->str_sect = sectp;
  else if (strcmp (sectp->name, ".dynamic") == 0)
    si->dyninfo_sect = sectp;
  else if (strcmp (sectp->name, ".got") == 0)
      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 (si.sym_sect);
  str_secsize = bfd_get_section_size (si.str_sect);
  dyninfo_secsize = bfd_get_section_size (si.dyninfo_sect);
  got_secsize = bfd_get_section_size (si.got_sect);
  sym_secptr = (char *) xmalloc (sym_secsize);
  cleanups = make_cleanup (xfree, sym_secptr);
  str_secptr = (char *) xmalloc (str_secsize);
  make_cleanup (xfree, str_secptr);
  dyninfo_secptr = (char *) xmalloc (dyninfo_secsize);
  make_cleanup (xfree, dyninfo_secptr);
  got_secptr = (char *) xmalloc (got_secsize);
  make_cleanup (xfree, got_secptr);

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

  /* Find the number of local GOT entries and the index for 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)
    {
      do_cleanups (cleanups);
      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);
      if (sym_shndx >= (SHN_LORESERVE & 0xffff))
	sym_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
      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;
	    }
	  else if (sym_shndx == SHN_MIPS_DATA)
	    {
	      if (isglobal)
		ms_type = mst_data;
	      else
		ms_type = mst_file_data;
	    }
	  else if (sym_shndx == SHN_MIPS_ACOMMON)
	    {
	      if (isglobal)
		ms_type = mst_bss;
	      else
		ms_type = mst_file_bss;
	    }
	  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 const struct sym_fns ecoff_sym_fns =
{
  mipscoff_new_init,		/* init anything gbl to entire symtab */
  mipscoff_symfile_init,	/* read initial info, setup for sym_read() */
  mipscoff_symfile_read,	/* read a symbol file into symtab */
  NULL,				/* sym_read_psymbols */
  mipscoff_symfile_finish,	/* finished with file, cleanup */
  default_symfile_offsets,	/* dummy FIXME til implem sym reloc */
  default_symfile_segments,	/* Get segment information from a file.  */
  NULL,
  default_symfile_relocate,	/* Relocate a debug section.  */
  NULL,				/* sym_probe_fns */
  &psym_functions
};

/* Provide a prototype to silence -Wmissing-prototypes.  */
void _initialize_mipsread (void);

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