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