xref: /dflybsd-src/contrib/gdb-7/gdb/mipsread.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
15796c8dcSSimon Schubert /* Read a symbol table in MIPS' format (Third-Eye).
25796c8dcSSimon Schubert 
3*ef5ccd6cSJohn Marino    Copyright (C) 1986-2013 Free Software Foundation, Inc.
45796c8dcSSimon Schubert 
55796c8dcSSimon Schubert    Contributed by Alessandro Forin (af@cs.cmu.edu) at CMU.  Major work
65796c8dcSSimon Schubert    by Per Bothner, John Gilmore and Ian Lance Taylor at Cygnus Support.
75796c8dcSSimon Schubert 
85796c8dcSSimon Schubert    This file is part of GDB.
95796c8dcSSimon Schubert 
105796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
115796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
125796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
135796c8dcSSimon Schubert    (at your option) any later version.
145796c8dcSSimon Schubert 
155796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
165796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
175796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
185796c8dcSSimon Schubert    GNU General Public License for more details.
195796c8dcSSimon Schubert 
205796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
215796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
225796c8dcSSimon Schubert 
235796c8dcSSimon Schubert /* Read symbols from an ECOFF file.  Most of the work is done in
245796c8dcSSimon Schubert    mdebugread.c.  */
255796c8dcSSimon Schubert 
265796c8dcSSimon Schubert #include "defs.h"
275796c8dcSSimon Schubert #include "gdb_string.h"
285796c8dcSSimon Schubert #include "bfd.h"
295796c8dcSSimon Schubert #include "symtab.h"
305796c8dcSSimon Schubert #include "objfiles.h"
315796c8dcSSimon Schubert #include "buildsym.h"
325796c8dcSSimon Schubert #include "stabsread.h"
335796c8dcSSimon Schubert 
345796c8dcSSimon Schubert #include "coff/sym.h"
355796c8dcSSimon Schubert #include "coff/internal.h"
365796c8dcSSimon Schubert #include "coff/ecoff.h"
375796c8dcSSimon Schubert #include "libcoff.h"		/* Private BFD COFF information.  */
385796c8dcSSimon Schubert #include "libecoff.h"		/* Private BFD ECOFF information.  */
395796c8dcSSimon Schubert #include "elf/common.h"
405796c8dcSSimon Schubert #include "elf/internal.h"
415796c8dcSSimon Schubert #include "elf/mips.h"
425796c8dcSSimon Schubert 
43cf7f2e2dSJohn Marino #include "psymtab.h"
44cf7f2e2dSJohn Marino 
455796c8dcSSimon Schubert static void
465796c8dcSSimon Schubert read_alphacoff_dynamic_symtab (struct section_offsets *,
475796c8dcSSimon Schubert 			       struct objfile *objfile);
485796c8dcSSimon Schubert 
495796c8dcSSimon Schubert /* Initialize anything that needs initializing when a completely new
505796c8dcSSimon Schubert    symbol file is specified (not just adding some symbols from another
515796c8dcSSimon Schubert    file, e.g. a shared library).  */
525796c8dcSSimon Schubert 
535796c8dcSSimon Schubert static void
mipscoff_new_init(struct objfile * ignore)545796c8dcSSimon Schubert mipscoff_new_init (struct objfile *ignore)
555796c8dcSSimon Schubert {
565796c8dcSSimon Schubert   stabsread_new_init ();
575796c8dcSSimon Schubert   buildsym_new_init ();
585796c8dcSSimon Schubert }
595796c8dcSSimon Schubert 
605796c8dcSSimon Schubert /* Initialize to read a symbol file (nothing to do).  */
615796c8dcSSimon Schubert 
625796c8dcSSimon Schubert static void
mipscoff_symfile_init(struct objfile * objfile)635796c8dcSSimon Schubert mipscoff_symfile_init (struct objfile *objfile)
645796c8dcSSimon Schubert {
655796c8dcSSimon Schubert }
665796c8dcSSimon Schubert 
675796c8dcSSimon Schubert /* Read a symbol file from a file.  */
685796c8dcSSimon Schubert 
695796c8dcSSimon Schubert static void
mipscoff_symfile_read(struct objfile * objfile,int symfile_flags)70cf7f2e2dSJohn Marino mipscoff_symfile_read (struct objfile *objfile, int symfile_flags)
715796c8dcSSimon Schubert {
725796c8dcSSimon Schubert   bfd *abfd = objfile->obfd;
735796c8dcSSimon Schubert   struct cleanup *back_to;
745796c8dcSSimon Schubert 
755796c8dcSSimon Schubert   init_minimal_symbol_collection ();
765796c8dcSSimon Schubert   back_to = make_cleanup_discard_minimal_symbols ();
775796c8dcSSimon Schubert 
785796c8dcSSimon Schubert   /* Now that the executable file is positioned at symbol table,
795796c8dcSSimon Schubert      process it and define symbols accordingly.  */
805796c8dcSSimon Schubert 
815796c8dcSSimon Schubert   if (!((*ecoff_backend (abfd)->debug_swap.read_debug_info)
825796c8dcSSimon Schubert 	(abfd, (asection *) NULL, &ecoff_data (abfd)->debug_info)))
835796c8dcSSimon Schubert     error (_("Error reading symbol table: %s"), bfd_errmsg (bfd_get_error ()));
845796c8dcSSimon Schubert 
855796c8dcSSimon Schubert   mdebug_build_psymtabs (objfile, &ecoff_backend (abfd)->debug_swap,
865796c8dcSSimon Schubert 			 &ecoff_data (abfd)->debug_info);
875796c8dcSSimon Schubert 
885796c8dcSSimon Schubert   /* Add alpha coff dynamic symbols.  */
895796c8dcSSimon Schubert 
905796c8dcSSimon Schubert   read_alphacoff_dynamic_symtab (objfile->section_offsets, objfile);
915796c8dcSSimon Schubert 
925796c8dcSSimon Schubert   /* Install any minimal symbols that have been collected as the current
935796c8dcSSimon Schubert      minimal symbols for this objfile.  */
945796c8dcSSimon Schubert 
955796c8dcSSimon Schubert   install_minimal_symbols (objfile);
965796c8dcSSimon Schubert   do_cleanups (back_to);
975796c8dcSSimon Schubert }
985796c8dcSSimon Schubert 
995796c8dcSSimon Schubert /* Perform any local cleanups required when we are done with a
1005796c8dcSSimon Schubert    particular objfile.  */
1015796c8dcSSimon Schubert 
1025796c8dcSSimon Schubert static void
mipscoff_symfile_finish(struct objfile * objfile)1035796c8dcSSimon Schubert mipscoff_symfile_finish (struct objfile *objfile)
1045796c8dcSSimon Schubert {
1055796c8dcSSimon Schubert }
1065796c8dcSSimon Schubert 
1075796c8dcSSimon Schubert /* Alpha OSF/1 encapsulates the dynamic symbols in ELF format in a
1085796c8dcSSimon Schubert    standard COFF section.  The ELF format for the symbols differs from
1095796c8dcSSimon Schubert    the format defined in elf/external.h.  It seems that a normal ELF
1105796c8dcSSimon Schubert    32-bit format is used, and the representation only changes because
1115796c8dcSSimon Schubert    longs are 64-bit on the alpha.  In addition, the handling of
1125796c8dcSSimon Schubert    text/data section indices for symbols is different from the ELF
1135796c8dcSSimon Schubert    ABI.  As the BFD linker currently does not support dynamic linking
1145796c8dcSSimon Schubert    on the alpha, there seems to be no reason to pollute BFD with
1155796c8dcSSimon Schubert    another mixture of object file formats for now.  */
1165796c8dcSSimon Schubert 
1175796c8dcSSimon Schubert /* Format of an alpha external ELF symbol.  */
1185796c8dcSSimon Schubert 
1195796c8dcSSimon Schubert typedef struct
1205796c8dcSSimon Schubert {
1215796c8dcSSimon Schubert   unsigned char st_name[4];	/* Symbol name, index in string table.  */
1225796c8dcSSimon Schubert   unsigned char st_pad[4];	/* Pad to long word boundary.  */
1235796c8dcSSimon Schubert   unsigned char st_value[8];	/* Value of the symbol.  */
1245796c8dcSSimon Schubert   unsigned char st_size[4];	/* Associated symbol size.  */
1255796c8dcSSimon Schubert   unsigned char st_info[1];	/* Type and binding attributes.  */
1265796c8dcSSimon Schubert   unsigned char st_other[1];	/* No defined meaning, 0.  */
1275796c8dcSSimon Schubert   unsigned char st_shndx[2];	/* Associated section index.  */
1285796c8dcSSimon Schubert } Elfalpha_External_Sym;
1295796c8dcSSimon Schubert 
1305796c8dcSSimon Schubert /* Format of an alpha external ELF dynamic info structure.  */
1315796c8dcSSimon Schubert 
1325796c8dcSSimon Schubert typedef struct
1335796c8dcSSimon Schubert {
1345796c8dcSSimon Schubert   unsigned char d_tag[4];	/* Tag.  */
1355796c8dcSSimon Schubert   unsigned char d_pad[4];	/* Pad to long word boundary.  */
1365796c8dcSSimon Schubert   union
1375796c8dcSSimon Schubert   {
1385796c8dcSSimon Schubert     unsigned char d_ptr[8];	/* Pointer value.  */
1395796c8dcSSimon Schubert     unsigned char d_val[4];	/* Integer value.  */
1405796c8dcSSimon Schubert   }
1415796c8dcSSimon Schubert   d_un;
1425796c8dcSSimon Schubert } Elfalpha_External_Dyn;
1435796c8dcSSimon Schubert 
1445796c8dcSSimon Schubert /* Struct to obtain the section pointers for alpha dynamic symbol info.  */
1455796c8dcSSimon Schubert 
1465796c8dcSSimon Schubert struct alphacoff_dynsecinfo
1475796c8dcSSimon Schubert {
1485796c8dcSSimon Schubert   asection *sym_sect;		/* Section pointer for .dynsym section.  */
1495796c8dcSSimon Schubert   asection *str_sect;		/* Section pointer for .dynstr section.  */
1505796c8dcSSimon Schubert   asection *dyninfo_sect;	/* Section pointer for .dynamic section.  */
1515796c8dcSSimon Schubert   asection *got_sect;		/* Section pointer for .got section.  */
1525796c8dcSSimon Schubert };
1535796c8dcSSimon Schubert 
1545796c8dcSSimon Schubert /* We are called once per section from read_alphacoff_dynamic_symtab.
1555796c8dcSSimon Schubert    We need to examine each section we are passed, check to see if it
1565796c8dcSSimon Schubert    is something we are interested in processing, and if so, stash away
1575796c8dcSSimon Schubert    some access information for the section.  */
1585796c8dcSSimon Schubert 
1595796c8dcSSimon Schubert static void
alphacoff_locate_sections(bfd * ignore_abfd,asection * sectp,void * sip)1605796c8dcSSimon Schubert alphacoff_locate_sections (bfd *ignore_abfd, asection *sectp, void *sip)
1615796c8dcSSimon Schubert {
1625796c8dcSSimon Schubert   struct alphacoff_dynsecinfo *si;
1635796c8dcSSimon Schubert 
1645796c8dcSSimon Schubert   si = (struct alphacoff_dynsecinfo *) sip;
1655796c8dcSSimon Schubert 
1665796c8dcSSimon Schubert   if (strcmp (sectp->name, ".dynsym") == 0)
1675796c8dcSSimon Schubert     si->sym_sect = sectp;
1685796c8dcSSimon Schubert   else if (strcmp (sectp->name, ".dynstr") == 0)
1695796c8dcSSimon Schubert     si->str_sect = sectp;
1705796c8dcSSimon Schubert   else if (strcmp (sectp->name, ".dynamic") == 0)
1715796c8dcSSimon Schubert     si->dyninfo_sect = sectp;
1725796c8dcSSimon Schubert   else if (strcmp (sectp->name, ".got") == 0)
1735796c8dcSSimon Schubert       si->got_sect = sectp;
1745796c8dcSSimon Schubert }
1755796c8dcSSimon Schubert 
1765796c8dcSSimon Schubert /* Scan an alpha dynamic symbol table for symbols of interest and add
1775796c8dcSSimon Schubert    them to the minimal symbol table.  */
1785796c8dcSSimon Schubert 
1795796c8dcSSimon Schubert static void
read_alphacoff_dynamic_symtab(struct section_offsets * section_offsets,struct objfile * objfile)1805796c8dcSSimon Schubert read_alphacoff_dynamic_symtab (struct section_offsets *section_offsets,
1815796c8dcSSimon Schubert 			       struct objfile *objfile)
1825796c8dcSSimon Schubert {
1835796c8dcSSimon Schubert   bfd *abfd = objfile->obfd;
1845796c8dcSSimon Schubert   struct alphacoff_dynsecinfo si;
1855796c8dcSSimon Schubert   char *sym_secptr;
1865796c8dcSSimon Schubert   char *str_secptr;
1875796c8dcSSimon Schubert   char *dyninfo_secptr;
1885796c8dcSSimon Schubert   char *got_secptr;
1895796c8dcSSimon Schubert   bfd_size_type sym_secsize;
1905796c8dcSSimon Schubert   bfd_size_type str_secsize;
1915796c8dcSSimon Schubert   bfd_size_type dyninfo_secsize;
1925796c8dcSSimon Schubert   bfd_size_type got_secsize;
1935796c8dcSSimon Schubert   int sym_count;
1945796c8dcSSimon Schubert   int i;
1955796c8dcSSimon Schubert   int stripped;
1965796c8dcSSimon Schubert   Elfalpha_External_Sym *x_symp;
1975796c8dcSSimon Schubert   char *dyninfo_p;
1985796c8dcSSimon Schubert   char *dyninfo_end;
1995796c8dcSSimon Schubert   int got_entry_size = 8;
2005796c8dcSSimon Schubert   int dt_mips_local_gotno = -1;
2015796c8dcSSimon Schubert   int dt_mips_gotsym = -1;
2025796c8dcSSimon Schubert   struct cleanup *cleanups;
2035796c8dcSSimon Schubert 
2045796c8dcSSimon Schubert   /* We currently only know how to handle alpha dynamic symbols.  */
2055796c8dcSSimon Schubert   if (bfd_get_arch (abfd) != bfd_arch_alpha)
2065796c8dcSSimon Schubert     return;
2075796c8dcSSimon Schubert 
2085796c8dcSSimon Schubert   /* Locate the dynamic symbols sections and read them in.  */
2095796c8dcSSimon Schubert   memset ((char *) &si, 0, sizeof (si));
2105796c8dcSSimon Schubert   bfd_map_over_sections (abfd, alphacoff_locate_sections, (void *) & si);
2115796c8dcSSimon Schubert   if (si.sym_sect == NULL || si.str_sect == NULL
2125796c8dcSSimon Schubert       || si.dyninfo_sect == NULL || si.got_sect == NULL)
2135796c8dcSSimon Schubert     return;
2145796c8dcSSimon Schubert 
2155796c8dcSSimon Schubert   sym_secsize = bfd_get_section_size (si.sym_sect);
2165796c8dcSSimon Schubert   str_secsize = bfd_get_section_size (si.str_sect);
2175796c8dcSSimon Schubert   dyninfo_secsize = bfd_get_section_size (si.dyninfo_sect);
2185796c8dcSSimon Schubert   got_secsize = bfd_get_section_size (si.got_sect);
2195796c8dcSSimon Schubert   sym_secptr = xmalloc (sym_secsize);
2205796c8dcSSimon Schubert   cleanups = make_cleanup (xfree, sym_secptr);
2215796c8dcSSimon Schubert   str_secptr = xmalloc (str_secsize);
2225796c8dcSSimon Schubert   make_cleanup (xfree, str_secptr);
2235796c8dcSSimon Schubert   dyninfo_secptr = xmalloc (dyninfo_secsize);
2245796c8dcSSimon Schubert   make_cleanup (xfree, dyninfo_secptr);
2255796c8dcSSimon Schubert   got_secptr = xmalloc (got_secsize);
2265796c8dcSSimon Schubert   make_cleanup (xfree, got_secptr);
2275796c8dcSSimon Schubert 
2285796c8dcSSimon Schubert   if (!bfd_get_section_contents (abfd, si.sym_sect, sym_secptr,
2295796c8dcSSimon Schubert 				 (file_ptr) 0, sym_secsize))
2305796c8dcSSimon Schubert     return;
2315796c8dcSSimon Schubert   if (!bfd_get_section_contents (abfd, si.str_sect, str_secptr,
2325796c8dcSSimon Schubert 				 (file_ptr) 0, str_secsize))
2335796c8dcSSimon Schubert     return;
2345796c8dcSSimon Schubert   if (!bfd_get_section_contents (abfd, si.dyninfo_sect, dyninfo_secptr,
2355796c8dcSSimon Schubert 				 (file_ptr) 0, dyninfo_secsize))
2365796c8dcSSimon Schubert     return;
2375796c8dcSSimon Schubert   if (!bfd_get_section_contents (abfd, si.got_sect, got_secptr,
2385796c8dcSSimon Schubert 				 (file_ptr) 0, got_secsize))
2395796c8dcSSimon Schubert     return;
2405796c8dcSSimon Schubert 
241a45ae5f8SJohn Marino   /* Find the number of local GOT entries and the index for the
2425796c8dcSSimon Schubert      first dynamic symbol in the GOT.  */
2435796c8dcSSimon Schubert   for (dyninfo_p = dyninfo_secptr, dyninfo_end = dyninfo_p + dyninfo_secsize;
2445796c8dcSSimon Schubert        dyninfo_p < dyninfo_end;
2455796c8dcSSimon Schubert        dyninfo_p += sizeof (Elfalpha_External_Dyn))
2465796c8dcSSimon Schubert     {
2475796c8dcSSimon Schubert       Elfalpha_External_Dyn *x_dynp = (Elfalpha_External_Dyn *) dyninfo_p;
2485796c8dcSSimon Schubert       long dyn_tag;
2495796c8dcSSimon Schubert 
2505796c8dcSSimon Schubert       dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_tag);
2515796c8dcSSimon Schubert       if (dyn_tag == DT_NULL)
2525796c8dcSSimon Schubert 	break;
2535796c8dcSSimon Schubert       else if (dyn_tag == DT_MIPS_LOCAL_GOTNO)
2545796c8dcSSimon Schubert 	{
2555796c8dcSSimon Schubert 	  if (dt_mips_local_gotno < 0)
2565796c8dcSSimon Schubert 	    dt_mips_local_gotno
2575796c8dcSSimon Schubert 	      = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_un.d_val);
2585796c8dcSSimon Schubert 	}
2595796c8dcSSimon Schubert       else if (dyn_tag == DT_MIPS_GOTSYM)
2605796c8dcSSimon Schubert 	{
2615796c8dcSSimon Schubert 	  if (dt_mips_gotsym < 0)
2625796c8dcSSimon Schubert 	    dt_mips_gotsym
2635796c8dcSSimon Schubert 	      = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_un.d_val);
2645796c8dcSSimon Schubert 	}
2655796c8dcSSimon Schubert     }
2665796c8dcSSimon Schubert   if (dt_mips_local_gotno < 0 || dt_mips_gotsym < 0)
2675796c8dcSSimon Schubert     return;
2685796c8dcSSimon Schubert 
2695796c8dcSSimon Schubert   /* Scan all dynamic symbols and enter them into the minimal symbol
2705796c8dcSSimon Schubert      table if appropriate.  */
2715796c8dcSSimon Schubert   sym_count = sym_secsize / sizeof (Elfalpha_External_Sym);
2725796c8dcSSimon Schubert   stripped = (bfd_get_symcount (abfd) == 0);
2735796c8dcSSimon Schubert 
2745796c8dcSSimon Schubert   /* Skip first symbol, which is a null dummy.  */
2755796c8dcSSimon Schubert   for (i = 1, x_symp = (Elfalpha_External_Sym *) sym_secptr + 1;
2765796c8dcSSimon Schubert        i < sym_count;
2775796c8dcSSimon Schubert        i++, x_symp++)
2785796c8dcSSimon Schubert     {
2795796c8dcSSimon Schubert       unsigned long strx;
2805796c8dcSSimon Schubert       char *name;
2815796c8dcSSimon Schubert       bfd_vma sym_value;
2825796c8dcSSimon Schubert       unsigned char sym_info;
2835796c8dcSSimon Schubert       unsigned int sym_shndx;
2845796c8dcSSimon Schubert       int isglobal;
2855796c8dcSSimon Schubert       enum minimal_symbol_type ms_type;
2865796c8dcSSimon Schubert 
2875796c8dcSSimon Schubert       strx = bfd_h_get_32 (abfd, (bfd_byte *) x_symp->st_name);
2885796c8dcSSimon Schubert       if (strx >= str_secsize)
2895796c8dcSSimon Schubert 	continue;
2905796c8dcSSimon Schubert       name = str_secptr + strx;
2915796c8dcSSimon Schubert       if (*name == '\0' || *name == '.')
2925796c8dcSSimon Schubert 	continue;
2935796c8dcSSimon Schubert 
2945796c8dcSSimon Schubert       sym_value = bfd_h_get_64 (abfd, (bfd_byte *) x_symp->st_value);
2955796c8dcSSimon Schubert       sym_info = bfd_h_get_8 (abfd, (bfd_byte *) x_symp->st_info);
2965796c8dcSSimon Schubert       sym_shndx = bfd_h_get_16 (abfd, (bfd_byte *) x_symp->st_shndx);
2975796c8dcSSimon Schubert       if (sym_shndx >= (SHN_LORESERVE & 0xffff))
2985796c8dcSSimon Schubert 	sym_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
2995796c8dcSSimon Schubert       isglobal = (ELF_ST_BIND (sym_info) == STB_GLOBAL);
3005796c8dcSSimon Schubert 
3015796c8dcSSimon Schubert       if (sym_shndx == SHN_UNDEF)
3025796c8dcSSimon Schubert 	{
3035796c8dcSSimon Schubert 	  /* Handle undefined functions which are defined in a shared
3045796c8dcSSimon Schubert 	     library.  */
3055796c8dcSSimon Schubert 	  if (ELF_ST_TYPE (sym_info) != STT_FUNC
3065796c8dcSSimon Schubert 	      || ELF_ST_BIND (sym_info) != STB_GLOBAL)
3075796c8dcSSimon Schubert 	    continue;
3085796c8dcSSimon Schubert 
3095796c8dcSSimon Schubert 	  ms_type = mst_solib_trampoline;
3105796c8dcSSimon Schubert 
3115796c8dcSSimon Schubert 	  /* If sym_value is nonzero, it points to the shared library
3125796c8dcSSimon Schubert 	     trampoline entry, which is what we are looking for.
3135796c8dcSSimon Schubert 
3145796c8dcSSimon Schubert 	     If sym_value is zero, then we have to get the GOT entry
3155796c8dcSSimon Schubert 	     for the symbol.
3165796c8dcSSimon Schubert 
3175796c8dcSSimon Schubert 	     If the GOT entry is nonzero, it represents the quickstart
3185796c8dcSSimon Schubert 	     address of the function and we use that as the symbol
3195796c8dcSSimon Schubert 	     value.
3205796c8dcSSimon Schubert 
3215796c8dcSSimon Schubert 	     If the GOT entry is zero, the function address has to be
3225796c8dcSSimon Schubert 	     resolved by the runtime loader before the executable is
3235796c8dcSSimon Schubert 	     started.  We are unable to find any meaningful address
3245796c8dcSSimon Schubert 	     for these functions in the executable file, so we skip
3255796c8dcSSimon Schubert 	     them.  */
3265796c8dcSSimon Schubert 	  if (sym_value == 0)
3275796c8dcSSimon Schubert 	    {
3285796c8dcSSimon Schubert 	      int got_entry_offset =
3295796c8dcSSimon Schubert 		(i - dt_mips_gotsym + dt_mips_local_gotno) * got_entry_size;
3305796c8dcSSimon Schubert 
3315796c8dcSSimon Schubert 	      if (got_entry_offset < 0 || got_entry_offset >= got_secsize)
3325796c8dcSSimon Schubert 		continue;
3335796c8dcSSimon Schubert 	      sym_value =
3345796c8dcSSimon Schubert 		bfd_h_get_64 (abfd,
3355796c8dcSSimon Schubert 			      (bfd_byte *) (got_secptr + got_entry_offset));
3365796c8dcSSimon Schubert 	      if (sym_value == 0)
3375796c8dcSSimon Schubert 		continue;
3385796c8dcSSimon Schubert 	    }
3395796c8dcSSimon Schubert 	}
3405796c8dcSSimon Schubert       else
3415796c8dcSSimon Schubert 	{
3425796c8dcSSimon Schubert 	  /* Symbols defined in the executable itself.  We only care
3435796c8dcSSimon Schubert 	     about them if this is a stripped executable, otherwise
3445796c8dcSSimon Schubert 	     they have been retrieved from the normal symbol table
3455796c8dcSSimon Schubert 	     already.  */
3465796c8dcSSimon Schubert 	  if (!stripped)
3475796c8dcSSimon Schubert 	    continue;
3485796c8dcSSimon Schubert 
3495796c8dcSSimon Schubert 	  if (sym_shndx == SHN_MIPS_TEXT)
3505796c8dcSSimon Schubert 	    {
3515796c8dcSSimon Schubert 	      if (isglobal)
3525796c8dcSSimon Schubert 		ms_type = mst_text;
3535796c8dcSSimon Schubert 	      else
3545796c8dcSSimon Schubert 		ms_type = mst_file_text;
3555796c8dcSSimon Schubert 	      sym_value += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
3565796c8dcSSimon Schubert 	    }
3575796c8dcSSimon Schubert 	  else if (sym_shndx == SHN_MIPS_DATA)
3585796c8dcSSimon Schubert 	    {
3595796c8dcSSimon Schubert 	      if (isglobal)
3605796c8dcSSimon Schubert 		ms_type = mst_data;
3615796c8dcSSimon Schubert 	      else
3625796c8dcSSimon Schubert 		ms_type = mst_file_data;
3635796c8dcSSimon Schubert 	      sym_value += ANOFFSET (section_offsets, SECT_OFF_DATA (objfile));
3645796c8dcSSimon Schubert 	    }
3655796c8dcSSimon Schubert 	  else if (sym_shndx == SHN_MIPS_ACOMMON)
3665796c8dcSSimon Schubert 	    {
3675796c8dcSSimon Schubert 	      if (isglobal)
3685796c8dcSSimon Schubert 		ms_type = mst_bss;
3695796c8dcSSimon Schubert 	      else
3705796c8dcSSimon Schubert 		ms_type = mst_file_bss;
3715796c8dcSSimon Schubert 	      sym_value += ANOFFSET (section_offsets, SECT_OFF_BSS (objfile));
3725796c8dcSSimon Schubert 	    }
3735796c8dcSSimon Schubert 	  else if (sym_shndx == SHN_ABS)
3745796c8dcSSimon Schubert 	    {
3755796c8dcSSimon Schubert 	      ms_type = mst_abs;
3765796c8dcSSimon Schubert 	    }
3775796c8dcSSimon Schubert 	  else
3785796c8dcSSimon Schubert 	    {
3795796c8dcSSimon Schubert 	      continue;
3805796c8dcSSimon Schubert 	    }
3815796c8dcSSimon Schubert 	}
3825796c8dcSSimon Schubert 
3835796c8dcSSimon Schubert       prim_record_minimal_symbol (name, sym_value, ms_type, objfile);
3845796c8dcSSimon Schubert     }
3855796c8dcSSimon Schubert 
3865796c8dcSSimon Schubert   do_cleanups (cleanups);
3875796c8dcSSimon Schubert }
3885796c8dcSSimon Schubert 
3895796c8dcSSimon Schubert /* Initialization.  */
3905796c8dcSSimon Schubert 
391c50c785cSJohn Marino static const struct sym_fns ecoff_sym_fns =
3925796c8dcSSimon Schubert {
3935796c8dcSSimon Schubert   bfd_target_ecoff_flavour,
394c50c785cSJohn Marino   mipscoff_new_init,		/* init anything gbl to entire symtab */
395c50c785cSJohn Marino   mipscoff_symfile_init,	/* read initial info, setup for sym_read() */
396c50c785cSJohn Marino   mipscoff_symfile_read,	/* read a symbol file into symtab */
397c50c785cSJohn Marino   NULL,				/* sym_read_psymbols */
398c50c785cSJohn Marino   mipscoff_symfile_finish,	/* finished with file, cleanup */
399c50c785cSJohn Marino   default_symfile_offsets,	/* dummy FIXME til implem sym reloc */
400c50c785cSJohn Marino   default_symfile_segments,	/* Get segment information from a file.  */
401c50c785cSJohn Marino   NULL,
402c50c785cSJohn Marino   default_symfile_relocate,	/* Relocate a debug section.  */
403*ef5ccd6cSJohn Marino   NULL,				/* sym_probe_fns */
404c50c785cSJohn Marino   &psym_functions
4055796c8dcSSimon Schubert };
4065796c8dcSSimon Schubert 
4075796c8dcSSimon Schubert /* Provide a prototype to silence -Wmissing-prototypes.  */
4085796c8dcSSimon Schubert void _initialize_mipsread (void);
4095796c8dcSSimon Schubert 
4105796c8dcSSimon Schubert void
_initialize_mipsread(void)4115796c8dcSSimon Schubert _initialize_mipsread (void)
4125796c8dcSSimon Schubert {
4135796c8dcSSimon Schubert   add_symtab_fns (&ecoff_sym_fns);
4145796c8dcSSimon Schubert }
415