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