]> Git Repo - binutils.git/blob - gdb/mipsread.c
* gdb.base/scope.exp (text_at_main): Add "hppa*-*-hpux*"
[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 ([email protected]) 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 "gdb_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_backend (abfd)->debug_swap.read_debug_info)
105         (abfd, (asection *) NULL, &ecoff_data (abfd)->debug_info)))
106     error ("Error reading symbol table: %s", bfd_errmsg (bfd_get_error ()));
107
108   mdebug_build_psymtabs (objfile, &ecoff_backend (abfd)->debug_swap,
109                          &ecoff_data (abfd)->debug_info, section_offsets);
110
111   /* Add the dynamic symbols if we are reading the main symbol table.  */
112
113   if (mainline)
114     read_alphacoff_dynamic_symtab (section_offsets, objfile);
115
116   /* Install any minimal symbols that have been collected as the current
117      minimal symbols for this objfile. */
118
119   install_minimal_symbols (objfile);
120
121   do_cleanups (back_to);
122 }
123
124 /* Perform any local cleanups required when we are done with a
125    particular objfile.  */
126
127 static void
128 mipscoff_symfile_finish (objfile)
129      struct objfile *objfile;
130 {
131 }
132
133 /* Fake up identical offsets for all sections.  */
134
135 static struct section_offsets *
136 mipscoff_symfile_offsets (objfile, addr)
137      struct objfile *objfile;
138      CORE_ADDR addr;
139 {
140   struct section_offsets *section_offsets;
141   int i;
142
143   objfile->num_sections = SECT_OFF_MAX;
144   section_offsets = ((struct section_offsets *)
145                      obstack_alloc (&objfile->psymbol_obstack,
146                                     (sizeof (struct section_offsets)
147                                      + (sizeof (section_offsets->offsets)
148                                         * (SECT_OFF_MAX - 1)))));
149
150   for (i = 0; i < SECT_OFF_MAX; i++)
151     ANOFFSET (section_offsets, i) = addr;
152
153   return section_offsets;
154 }
155
156 /* Alpha OSF/1 encapsulates the dynamic symbols in ELF format in a
157    standard coff section.  The ELF format for the symbols differs from
158    the format defined in elf/external.h. It seems that a normal ELF 32 bit
159    format is used, and the representation only changes because longs are
160    64 bit on the alpha. In addition, the handling of text/data section
161    indices for symbols is different from the ELF ABI.
162    As the BFD linker currently does not support dynamic linking on the alpha,
163    there seems to be no reason to pollute BFD with another mixture of object
164    file formats for now.  */
165
166 /* Format of an alpha external ELF symbol.  */
167
168 typedef struct {
169   unsigned char st_name[4];             /* Symbol name, index in string tbl */
170   unsigned char st_pad[4];              /* Pad to long word boundary */
171   unsigned char st_value[8];            /* Value of the symbol */
172   unsigned char st_size[4];             /* Associated symbol size */
173   unsigned char st_info[1];             /* Type and binding attributes */
174   unsigned char st_other[1];            /* No defined meaning, 0 */
175   unsigned char st_shndx[2];            /* Associated section index */
176 } Elfalpha_External_Sym;
177
178 /* Format of an alpha external ELF dynamic info structure.  */
179
180 typedef struct {
181   unsigned char d_tag[4];               /* Tag */
182   unsigned char d_pad[4];               /* Pad to long word boundary */
183   union {
184     unsigned char d_ptr[8];             /* Pointer value */
185     unsigned char d_val[4];             /* Integer value */
186   } d_un;
187 } Elfalpha_External_Dyn;
188
189 /* Struct to obtain the section pointers for alpha dynamic symbol info.  */
190
191 struct alphacoff_dynsecinfo {
192   asection *sym_sect;           /* Section pointer for .dynsym section */
193   asection *str_sect;           /* Section pointer for .dynstr section */
194   asection *dyninfo_sect;       /* Section pointer for .dynamic section */
195   asection *got_sect;           /* Section pointer for .got section */
196 };
197
198 static void
199 alphacoff_locate_sections PARAMS ((bfd *, asection *, void *));
200
201 /* We are called once per section from read_alphacoff_dynamic_symtab.
202    We need to examine each section we are passed, check to see
203    if it is something we are interested in processing, and
204    if so, stash away some access information for the section.  */
205
206 static void
207 alphacoff_locate_sections (ignore_abfd, sectp, sip)
208      bfd *ignore_abfd;
209      asection *sectp;
210      PTR sip;
211 {
212   register struct alphacoff_dynsecinfo *si;
213
214   si = (struct alphacoff_dynsecinfo *) sip;
215
216   if (STREQ (sectp->name, ".dynsym"))
217     {
218       si->sym_sect = sectp;
219     }
220   else if (STREQ (sectp->name, ".dynstr"))
221     {
222       si->str_sect = sectp;
223     }
224   else if (STREQ (sectp->name, ".dynamic"))
225     {
226       si->dyninfo_sect = sectp;
227     }
228   else if (STREQ (sectp->name, ".got"))
229     {
230       si->got_sect = sectp;
231     }
232 }
233
234 /* Scan an alpha dynamic symbol table for symbols of interest and
235    add them to the minimal symbol table.  */
236
237 static void
238 read_alphacoff_dynamic_symtab (section_offsets, objfile)
239      struct section_offsets *section_offsets;
240      struct objfile *objfile;
241 {
242   bfd *abfd = objfile->obfd;
243   struct alphacoff_dynsecinfo si;
244   char *sym_secptr;
245   char *str_secptr;
246   char *dyninfo_secptr;
247   char *got_secptr;
248   bfd_size_type sym_secsize;
249   bfd_size_type str_secsize;
250   bfd_size_type dyninfo_secsize;
251   bfd_size_type got_secsize;
252   int sym_count;
253   int i;
254   int stripped;
255   Elfalpha_External_Sym *x_symp;
256   char *dyninfo_p;
257   char *dyninfo_end;
258   int got_entry_size = 8;
259   int dt_mips_local_gotno = -1;
260   int dt_mips_gotsym = -1;
261
262
263   /* We currently only know how to handle alpha dynamic symbols.  */
264   if (bfd_get_arch (abfd) != bfd_arch_alpha)
265     return;
266
267   /* Locate the dynamic symbols sections and read them in.  */
268   memset ((char *) &si, 0, sizeof (si));
269   bfd_map_over_sections (abfd, alphacoff_locate_sections, (PTR) &si);
270   if (si.sym_sect == NULL
271       || si.str_sect == NULL
272       || si.dyninfo_sect == NULL
273       || si.got_sect == NULL)
274     return;
275
276   sym_secsize = bfd_get_section_size_before_reloc (si.sym_sect);
277   str_secsize = bfd_get_section_size_before_reloc (si.str_sect);
278   dyninfo_secsize = bfd_get_section_size_before_reloc (si.dyninfo_sect);
279   got_secsize = bfd_get_section_size_before_reloc (si.got_sect);
280   sym_secptr = alloca (sym_secsize);
281   str_secptr = alloca (str_secsize);
282   dyninfo_secptr = alloca (dyninfo_secsize);
283   got_secptr = alloca (got_secsize);
284
285   if (!bfd_get_section_contents (abfd, si.sym_sect, sym_secptr,
286                                  (file_ptr)0, sym_secsize))
287     return;
288   if (!bfd_get_section_contents (abfd, si.str_sect, str_secptr,
289                                  (file_ptr)0, str_secsize))
290     return;
291   if (!bfd_get_section_contents (abfd, si.dyninfo_sect, dyninfo_secptr,
292                                  (file_ptr)0, dyninfo_secsize))
293     return;
294   if (!bfd_get_section_contents (abfd, si.got_sect, got_secptr,
295                                  (file_ptr)0, got_secsize))
296     return;
297
298   /* Find the number of local GOT entries and the index for the
299      the first dynamic symbol in the GOT. */
300   for (dyninfo_p = dyninfo_secptr, dyninfo_end = dyninfo_p + dyninfo_secsize;
301        dyninfo_p < dyninfo_end;
302        dyninfo_p += sizeof (Elfalpha_External_Dyn))
303     {
304       Elfalpha_External_Dyn *x_dynp = (Elfalpha_External_Dyn *)dyninfo_p;
305       long dyn_tag;
306
307       dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_tag);
308       if (dyn_tag == DT_NULL)
309         break;
310       else if (dyn_tag == DT_MIPS_LOCAL_GOTNO)
311         {
312           dt_mips_local_gotno = bfd_h_get_32 (abfd,
313                                               (bfd_byte *) x_dynp->d_un.d_val);
314         }
315       else if (dyn_tag == DT_MIPS_GOTSYM)
316         {
317           dt_mips_gotsym = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_un.d_val);
318         }
319     }
320   if (dt_mips_local_gotno < 0 || dt_mips_gotsym < 0)
321     return;
322
323   /* Scan all dynamic symbols and enter them into the minimal symbol table
324      if appropriate.  */
325   sym_count = sym_secsize / sizeof (Elfalpha_External_Sym);
326   stripped = (bfd_get_symcount (abfd) == 0);
327
328   /* Skip first symbol, which is a null dummy.  */
329   for (i = 1, x_symp = (Elfalpha_External_Sym *) sym_secptr + 1;
330        i < sym_count;
331        i++, x_symp++)
332     {
333       unsigned long strx;
334       char *name;
335       bfd_vma sym_value;
336       unsigned char sym_info;
337       unsigned int sym_shndx;
338       int isglobal;
339       enum minimal_symbol_type ms_type;
340
341       strx = bfd_h_get_32 (abfd, (bfd_byte *) x_symp->st_name);
342       if (strx >= str_secsize)
343         continue;
344       name = str_secptr + strx;
345       if (*name == '\0' || *name == '.')
346         continue;
347
348       sym_value = bfd_h_get_64 (abfd, (bfd_byte *) x_symp->st_value);
349       sym_info = bfd_h_get_8 (abfd, (bfd_byte *) x_symp->st_info);
350       sym_shndx = bfd_h_get_16 (abfd, (bfd_byte *) x_symp->st_shndx);
351       isglobal = (ELF_ST_BIND (sym_info) == STB_GLOBAL);
352
353       if (sym_shndx == SHN_UNDEF)
354         {
355           /* Handle undefined functions which are defined in a shared
356              library.  */
357           if (ELF_ST_TYPE (sym_info) != STT_FUNC
358               || ELF_ST_BIND (sym_info) != STB_GLOBAL)
359             continue;
360
361           ms_type = mst_solib_trampoline;
362
363           /* If sym_value is nonzero, it points to the shared library
364              trampoline entry, which is what we are looking for.
365
366              If sym_value is zero, then we have to get the GOT entry
367              for the symbol.
368              If the GOT entry is nonzero, it represents the quickstart
369              address of the function and we use that as the symbol value.
370
371              If the GOT entry is zero, the function address has to be resolved
372              by the runtime loader before the executable is started.
373              We are unable to find any meaningful address for these
374              functions in the executable file, so we skip them.  */
375           if (sym_value == 0)
376             {
377               int got_entry_offset =
378                 (i - dt_mips_gotsym + dt_mips_local_gotno) * got_entry_size;
379
380               if (got_entry_offset < 0 || got_entry_offset >= got_secsize)
381                 continue;
382               sym_value =
383                 bfd_h_get_64 (abfd,
384                               (bfd_byte *) (got_secptr + got_entry_offset));
385               if (sym_value == 0)
386                 continue;
387             }
388         }
389       else
390         {
391           /* Symbols defined in the executable itself. We only care about
392              them if this is a stripped executable, otherwise they have
393              been retrieved from the normal symbol table already.  */
394           if (!stripped)
395             continue;
396
397           if (sym_shndx == SHN_MIPS_TEXT)
398             {
399               if (isglobal)
400                 ms_type = mst_text;
401               else
402                 ms_type = mst_file_text;
403               sym_value += ANOFFSET (section_offsets, SECT_OFF_TEXT);
404             }
405           else if (sym_shndx == SHN_MIPS_DATA)
406             {
407               if (isglobal)
408                 ms_type = mst_data;
409               else
410                 ms_type = mst_file_data;
411               sym_value += ANOFFSET (section_offsets, SECT_OFF_DATA);
412             }
413           else if (sym_shndx == SHN_MIPS_ACOMMON)
414             {
415               if (isglobal)
416                 ms_type = mst_bss;
417               else
418                 ms_type = mst_file_bss;
419               sym_value += ANOFFSET (section_offsets, SECT_OFF_BSS);
420             }
421           else if (sym_shndx == SHN_ABS)
422             {
423               ms_type = mst_abs;
424             }
425           else
426             {
427               continue;
428             }
429         }
430
431       prim_record_minimal_symbol (obsavestring (name,
432                                                 strlen (name),
433                                                 &objfile -> symbol_obstack),
434                                   sym_value,
435                                   ms_type,
436                                   objfile);
437     }
438 }
439
440 /* Initialization */
441
442 static struct sym_fns ecoff_sym_fns =
443 {
444   bfd_target_ecoff_flavour,
445   mipscoff_new_init,            /* sym_new_init: init anything gbl to entire symtab */
446   mipscoff_symfile_init,        /* sym_init: read initial info, setup for sym_read() */
447   mipscoff_symfile_read,        /* sym_read: read a symbol file into symtab */
448   mipscoff_symfile_finish,      /* sym_finish: finished with file, cleanup */
449   mipscoff_symfile_offsets,     /* sym_offsets: dummy FIXME til implem sym reloc */
450   NULL                          /* next: pointer to next struct sym_fns */
451 };
452
453 void
454 _initialize_mipsread ()
455 {
456   add_symtab_fns (&ecoff_sym_fns);
457 }
This page took 0.049383 seconds and 4 git commands to generate.