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