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