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

   Copyright (C) 1986-2018 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 "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 (minimal_symbol_reader &,
			       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 ();
}

/* 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, symfile_add_flags symfile_flags)
{
  bfd *abfd = objfile->obfd;

  minimal_symbol_reader reader (objfile);

  /* 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 (reader, objfile, &ecoff_backend (abfd)->debug_swap,
			 &ecoff_data (abfd)->debug_info);

  /* Add alpha coff dynamic symbols.  */

  read_alphacoff_dynamic_symtab (reader, objfile->section_offsets, objfile);

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

  reader.install ();
}

/* 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 (minimal_symbol_reader &reader,
			       struct section_offsets *section_offsets,
			       struct objfile *objfile)
{
  bfd *abfd = objfile->obfd;
  struct alphacoff_dynsecinfo si;
  int sym_count;
  int i;
  int stripped;
  Elfalpha_External_Sym *x_symp;
  gdb_byte *dyninfo_p;
  gdb_byte *dyninfo_end;
  int got_entry_size = 8;
  int dt_mips_local_gotno = -1;
  int dt_mips_gotsym = -1;

  /* 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;

  gdb::byte_vector sym_sec (bfd_get_section_size (si.sym_sect));
  gdb::byte_vector str_sec (bfd_get_section_size (si.str_sect));
  gdb::byte_vector dyninfo_sec (bfd_get_section_size (si.dyninfo_sect));
  gdb::byte_vector got_sec (bfd_get_section_size (si.got_sect));

  if (!bfd_get_section_contents (abfd, si.sym_sect, sym_sec.data (),
				 (file_ptr) 0, sym_sec.size ()))
    return;
  if (!bfd_get_section_contents (abfd, si.str_sect, str_sec.data (),
				 (file_ptr) 0, str_sec.size ()))
    return;
  if (!bfd_get_section_contents (abfd, si.dyninfo_sect, dyninfo_sec.data (),
				 (file_ptr) 0, dyninfo_sec.size ()))
    return;
  if (!bfd_get_section_contents (abfd, si.got_sect, got_sec.data (),
				 (file_ptr) 0, got_sec.size ()))
    return;

  /* Find the number of local GOT entries and the index for the
     first dynamic symbol in the GOT.  */
  for ((dyninfo_p = dyninfo_sec.data (),
	dyninfo_end = dyninfo_p + dyninfo_sec.size ());
       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_sec.size () / 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_sec.data () + 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_sec.size ())
	continue;
      name = (char *) (str_sec.data () + 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_sec.size ())
		continue;
	      sym_value =
		bfd_h_get_64 (abfd,
			      (bfd_byte *) (got_sec.data ()
					    + 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;
	    }
	}

      reader.record (name, sym_value, ms_type);
    }
}

/* 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
};

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