Update/correct copyright notices.
[external/binutils.git] / gdb / mipsread.c
1 /* Read a symbol table in MIPS' format (Third-Eye).
2    Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
3    1998, 1999, 2000, 2001
4    Free Software Foundation, Inc.
5    Contributed by Alessandro Forin (af@cs.cmu.edu) at CMU.  Major work
6    by Per Bothner, John Gilmore and Ian Lance Taylor at Cygnus Support.
7
8    This file is part of GDB.
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 2 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330,
23    Boston, MA 02111-1307, USA.  */
24
25 /* Read symbols from an ECOFF file.  Most of the work is done in
26    mdebugread.c.  */
27
28 #include "defs.h"
29 #include "gdb_string.h"
30 #include "bfd.h"
31 #include "symtab.h"
32 #include "symfile.h"
33 #include "objfiles.h"
34 #include "buildsym.h"
35 #include "stabsread.h"
36 #include "gdb-stabs.h"
37
38 #include "coff/sym.h"
39 #include "coff/internal.h"
40 #include "coff/ecoff.h"
41 #include "libcoff.h"            /* Private BFD COFF information.  */
42 #include "libecoff.h"           /* Private BFD ECOFF information.  */
43 #include "elf/common.h"
44 #include "elf/mips.h"
45
46 extern void _initialize_mipsread (void);
47
48 static void mipscoff_new_init (struct objfile *);
49
50 static void mipscoff_symfile_init (struct objfile *);
51
52 static void mipscoff_symfile_read (struct objfile *, int);
53
54 static void mipscoff_symfile_finish (struct objfile *);
55
56 static void
57 read_alphacoff_dynamic_symtab (struct section_offsets *,
58                                struct objfile *objfile);
59
60 /* Initialize anything that needs initializing when a completely new
61    symbol file is specified (not just adding some symbols from another
62    file, e.g. a shared library).  */
63
64 extern CORE_ADDR sigtramp_address;
65
66 static void
67 mipscoff_new_init (struct objfile *ignore)
68 {
69   sigtramp_address = 0;
70   stabsread_new_init ();
71   buildsym_new_init ();
72 }
73
74 /* Initialize to read a symbol file (nothing to do).  */
75
76 static void
77 mipscoff_symfile_init (struct objfile *objfile)
78 {
79 }
80
81 /* Read a symbol file from a file.  */
82
83 static void
84 mipscoff_symfile_read (struct objfile *objfile, int mainline)
85 {
86   bfd *abfd = objfile->obfd;
87   struct cleanup *back_to;
88
89   init_minimal_symbol_collection ();
90   back_to = make_cleanup_discard_minimal_symbols ();
91
92   /* Now that the executable file is positioned at symbol table,
93      process it and define symbols accordingly.  */
94
95   if (!((*ecoff_backend (abfd)->debug_swap.read_debug_info)
96         (abfd, (asection *) NULL, &ecoff_data (abfd)->debug_info)))
97     error ("Error reading symbol table: %s", bfd_errmsg (bfd_get_error ()));
98
99   mdebug_build_psymtabs (objfile, &ecoff_backend (abfd)->debug_swap,
100                          &ecoff_data (abfd)->debug_info);
101
102   /* Add alpha coff dynamic symbols.  */
103
104   read_alphacoff_dynamic_symtab (objfile->section_offsets, objfile);
105
106   /* Install any minimal symbols that have been collected as the current
107      minimal symbols for this objfile. */
108
109   install_minimal_symbols (objfile);
110
111   /* If the entry_file bounds are still unknown after processing the
112      partial symbols, then try to set them from the minimal symbols
113      surrounding the entry_point.  */
114
115   if (mainline
116       && objfile->ei.entry_point != INVALID_ENTRY_POINT
117       && objfile->ei.entry_file_lowpc == INVALID_ENTRY_LOWPC)
118     {
119       struct minimal_symbol *m;
120
121       m = lookup_minimal_symbol_by_pc (objfile->ei.entry_point);
122       if (m && SYMBOL_NAME (m + 1))
123         {
124           objfile->ei.entry_file_lowpc = SYMBOL_VALUE_ADDRESS (m);
125           objfile->ei.entry_file_highpc = SYMBOL_VALUE_ADDRESS (m + 1);
126         }
127     }
128
129   do_cleanups (back_to);
130 }
131
132 /* Perform any local cleanups required when we are done with a
133    particular objfile.  */
134
135 static void
136 mipscoff_symfile_finish (struct objfile *objfile)
137 {
138 }
139
140 /* Alpha OSF/1 encapsulates the dynamic symbols in ELF format in a
141    standard coff section.  The ELF format for the symbols differs from
142    the format defined in elf/external.h. It seems that a normal ELF 32 bit
143    format is used, and the representation only changes because longs are
144    64 bit on the alpha. In addition, the handling of text/data section
145    indices for symbols is different from the ELF ABI.
146    As the BFD linker currently does not support dynamic linking on the alpha,
147    there seems to be no reason to pollute BFD with another mixture of object
148    file formats for now.  */
149
150 /* Format of an alpha external ELF symbol.  */
151
152 typedef struct
153 {
154   unsigned char st_name[4];     /* Symbol name, index in string tbl */
155   unsigned char st_pad[4];      /* Pad to long word boundary */
156   unsigned char st_value[8];    /* Value of the symbol */
157   unsigned char st_size[4];     /* Associated symbol size */
158   unsigned char st_info[1];     /* Type and binding attributes */
159   unsigned char st_other[1];    /* No defined meaning, 0 */
160   unsigned char st_shndx[2];    /* Associated section index */
161 }
162 Elfalpha_External_Sym;
163
164 /* Format of an alpha external ELF dynamic info structure.  */
165
166 typedef struct
167   {
168     unsigned char d_tag[4];     /* Tag */
169     unsigned char d_pad[4];     /* Pad to long word boundary */
170     union
171       {
172         unsigned char d_ptr[8]; /* Pointer value */
173         unsigned char d_val[4]; /* Integer value */
174       }
175     d_un;
176   }
177 Elfalpha_External_Dyn;
178
179 /* Struct to obtain the section pointers for alpha dynamic symbol info.  */
180
181 struct alphacoff_dynsecinfo
182   {
183     asection *sym_sect;         /* Section pointer for .dynsym section */
184     asection *str_sect;         /* Section pointer for .dynstr section */
185     asection *dyninfo_sect;     /* Section pointer for .dynamic section */
186     asection *got_sect;         /* Section pointer for .got section */
187   };
188
189 static void alphacoff_locate_sections (bfd *, asection *, void *);
190
191 /* We are called once per section from read_alphacoff_dynamic_symtab.
192    We need to examine each section we are passed, check to see
193    if it is something we are interested in processing, and
194    if so, stash away some access information for the section.  */
195
196 static void
197 alphacoff_locate_sections (bfd *ignore_abfd, asection *sectp, PTR sip)
198 {
199   register struct alphacoff_dynsecinfo *si;
200
201   si = (struct alphacoff_dynsecinfo *) sip;
202
203   if (STREQ (sectp->name, ".dynsym"))
204     {
205       si->sym_sect = sectp;
206     }
207   else if (STREQ (sectp->name, ".dynstr"))
208     {
209       si->str_sect = sectp;
210     }
211   else if (STREQ (sectp->name, ".dynamic"))
212     {
213       si->dyninfo_sect = sectp;
214     }
215   else if (STREQ (sectp->name, ".got"))
216     {
217       si->got_sect = sectp;
218     }
219 }
220
221 /* Scan an alpha dynamic symbol table for symbols of interest and
222    add them to the minimal symbol table.  */
223
224 static void
225 read_alphacoff_dynamic_symtab (struct section_offsets *section_offsets,
226                                struct objfile *objfile)
227 {
228   bfd *abfd = objfile->obfd;
229   struct alphacoff_dynsecinfo si;
230   char *sym_secptr;
231   char *str_secptr;
232   char *dyninfo_secptr;
233   char *got_secptr;
234   bfd_size_type sym_secsize;
235   bfd_size_type str_secsize;
236   bfd_size_type dyninfo_secsize;
237   bfd_size_type got_secsize;
238   int sym_count;
239   int i;
240   int stripped;
241   Elfalpha_External_Sym *x_symp;
242   char *dyninfo_p;
243   char *dyninfo_end;
244   int got_entry_size = 8;
245   int dt_mips_local_gotno = -1;
246   int dt_mips_gotsym = -1;
247   struct cleanup *cleanups;
248
249
250   /* We currently only know how to handle alpha dynamic symbols.  */
251   if (bfd_get_arch (abfd) != bfd_arch_alpha)
252     return;
253
254   /* Locate the dynamic symbols sections and read them in.  */
255   memset ((char *) &si, 0, sizeof (si));
256   bfd_map_over_sections (abfd, alphacoff_locate_sections, (PTR) & si);
257   if (si.sym_sect == NULL
258       || si.str_sect == NULL
259       || si.dyninfo_sect == NULL
260       || si.got_sect == NULL)
261     return;
262
263   sym_secsize = bfd_get_section_size_before_reloc (si.sym_sect);
264   str_secsize = bfd_get_section_size_before_reloc (si.str_sect);
265   dyninfo_secsize = bfd_get_section_size_before_reloc (si.dyninfo_sect);
266   got_secsize = bfd_get_section_size_before_reloc (si.got_sect);
267   sym_secptr = xmalloc (sym_secsize);
268   cleanups = make_cleanup (free, sym_secptr);
269   str_secptr = xmalloc (str_secsize);
270   make_cleanup (free, str_secptr);
271   dyninfo_secptr = xmalloc (dyninfo_secsize);
272   make_cleanup (free, dyninfo_secptr);
273   got_secptr = xmalloc (got_secsize);
274   make_cleanup (free, got_secptr);
275
276   if (!bfd_get_section_contents (abfd, si.sym_sect, sym_secptr,
277                                  (file_ptr) 0, sym_secsize))
278     return;
279   if (!bfd_get_section_contents (abfd, si.str_sect, str_secptr,
280                                  (file_ptr) 0, str_secsize))
281     return;
282   if (!bfd_get_section_contents (abfd, si.dyninfo_sect, dyninfo_secptr,
283                                  (file_ptr) 0, dyninfo_secsize))
284     return;
285   if (!bfd_get_section_contents (abfd, si.got_sect, got_secptr,
286                                  (file_ptr) 0, got_secsize))
287     return;
288
289   /* Find the number of local GOT entries and the index for the
290      the first dynamic symbol in the GOT. */
291   for (dyninfo_p = dyninfo_secptr, dyninfo_end = dyninfo_p + dyninfo_secsize;
292        dyninfo_p < dyninfo_end;
293        dyninfo_p += sizeof (Elfalpha_External_Dyn))
294     {
295       Elfalpha_External_Dyn *x_dynp = (Elfalpha_External_Dyn *) dyninfo_p;
296       long dyn_tag;
297
298       dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_tag);
299       if (dyn_tag == DT_NULL)
300         break;
301       else if (dyn_tag == DT_MIPS_LOCAL_GOTNO)
302         {
303           if (dt_mips_local_gotno < 0)
304             dt_mips_local_gotno
305               = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_un.d_val);
306         }
307       else if (dyn_tag == DT_MIPS_GOTSYM)
308         {
309           if (dt_mips_gotsym < 0)
310             dt_mips_gotsym
311               = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_un.d_val);
312         }
313     }
314   if (dt_mips_local_gotno < 0 || dt_mips_gotsym < 0)
315     return;
316
317   /* Scan all dynamic symbols and enter them into the minimal symbol table
318      if appropriate.  */
319   sym_count = sym_secsize / sizeof (Elfalpha_External_Sym);
320   stripped = (bfd_get_symcount (abfd) == 0);
321
322   /* Skip first symbol, which is a null dummy.  */
323   for (i = 1, x_symp = (Elfalpha_External_Sym *) sym_secptr + 1;
324        i < sym_count;
325        i++, x_symp++)
326     {
327       unsigned long strx;
328       char *name;
329       bfd_vma sym_value;
330       unsigned char sym_info;
331       unsigned int sym_shndx;
332       int isglobal;
333       enum minimal_symbol_type ms_type;
334
335       strx = bfd_h_get_32 (abfd, (bfd_byte *) x_symp->st_name);
336       if (strx >= str_secsize)
337         continue;
338       name = str_secptr + strx;
339       if (*name == '\0' || *name == '.')
340         continue;
341
342       sym_value = bfd_h_get_64 (abfd, (bfd_byte *) x_symp->st_value);
343       sym_info = bfd_h_get_8 (abfd, (bfd_byte *) x_symp->st_info);
344       sym_shndx = bfd_h_get_16 (abfd, (bfd_byte *) x_symp->st_shndx);
345       isglobal = (ELF_ST_BIND (sym_info) == STB_GLOBAL);
346
347       if (sym_shndx == SHN_UNDEF)
348         {
349           /* Handle undefined functions which are defined in a shared
350              library.  */
351           if (ELF_ST_TYPE (sym_info) != STT_FUNC
352               || ELF_ST_BIND (sym_info) != STB_GLOBAL)
353             continue;
354
355           ms_type = mst_solib_trampoline;
356
357           /* If sym_value is nonzero, it points to the shared library
358              trampoline entry, which is what we are looking for.
359
360              If sym_value is zero, then we have to get the GOT entry
361              for the symbol.
362              If the GOT entry is nonzero, it represents the quickstart
363              address of the function and we use that as the symbol value.
364
365              If the GOT entry is zero, the function address has to be resolved
366              by the runtime loader before the executable is started.
367              We are unable to find any meaningful address for these
368              functions in the executable file, so we skip them.  */
369           if (sym_value == 0)
370             {
371               int got_entry_offset =
372               (i - dt_mips_gotsym + dt_mips_local_gotno) * got_entry_size;
373
374               if (got_entry_offset < 0 || got_entry_offset >= got_secsize)
375                 continue;
376               sym_value =
377                 bfd_h_get_64 (abfd,
378                               (bfd_byte *) (got_secptr + got_entry_offset));
379               if (sym_value == 0)
380                 continue;
381             }
382         }
383       else
384         {
385           /* Symbols defined in the executable itself. We only care about
386              them if this is a stripped executable, otherwise they have
387              been retrieved from the normal symbol table already.  */
388           if (!stripped)
389             continue;
390
391           if (sym_shndx == SHN_MIPS_TEXT)
392             {
393               if (isglobal)
394                 ms_type = mst_text;
395               else
396                 ms_type = mst_file_text;
397               sym_value += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
398             }
399           else if (sym_shndx == SHN_MIPS_DATA)
400             {
401               if (isglobal)
402                 ms_type = mst_data;
403               else
404                 ms_type = mst_file_data;
405               sym_value += ANOFFSET (section_offsets, SECT_OFF_DATA (objfile));
406             }
407           else if (sym_shndx == SHN_MIPS_ACOMMON)
408             {
409               if (isglobal)
410                 ms_type = mst_bss;
411               else
412                 ms_type = mst_file_bss;
413               sym_value += ANOFFSET (section_offsets, SECT_OFF_BSS (objfile));
414             }
415           else if (sym_shndx == SHN_ABS)
416             {
417               ms_type = mst_abs;
418             }
419           else
420             {
421               continue;
422             }
423         }
424
425       prim_record_minimal_symbol (name, sym_value, ms_type, objfile);
426     }
427
428   do_cleanups (cleanups);
429 }
430
431 /* Initialization */
432
433 static struct sym_fns ecoff_sym_fns =
434 {
435   bfd_target_ecoff_flavour,
436   mipscoff_new_init,            /* sym_new_init: init anything gbl to entire symtab */
437   mipscoff_symfile_init,        /* sym_init: read initial info, setup for sym_read() */
438   mipscoff_symfile_read,        /* sym_read: read a symbol file into symtab */
439   mipscoff_symfile_finish,      /* sym_finish: finished with file, cleanup */
440   default_symfile_offsets,      /* sym_offsets: dummy FIXME til implem sym reloc */
441   NULL                          /* next: pointer to next struct sym_fns */
442 };
443
444 void
445 _initialize_mipsread (void)
446 {
447   add_symtab_fns (&ecoff_sym_fns);
448 }