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