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.
5 by Per Bothner, John Gilmore and Ian Lance Taylor at Cygnus Support.
7 This file is part of GDB.
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.
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.
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. */
23 /* Read symbols from an ECOFF file. Most of the work is done in
33 #include "stabsread.h"
34 #include "gdb-stabs.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"
45 mipscoff_new_init PARAMS ((struct objfile *));
48 mipscoff_symfile_init PARAMS ((struct objfile *));
51 mipscoff_symfile_read PARAMS ((struct objfile *, struct section_offsets *,
55 mipscoff_symfile_finish PARAMS ((struct objfile *));
57 static struct section_offsets *
58 mipscoff_symfile_offsets PARAMS ((struct objfile *, CORE_ADDR));
61 read_alphacoff_dynamic_symtab PARAMS ((struct section_offsets *,
62 struct objfile *objfile));
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). */
68 extern CORE_ADDR sigtramp_address;
71 mipscoff_new_init (ignore)
72 struct objfile *ignore;
75 stabsread_new_init ();
79 /* Initialize to read a symbol file (nothing to do). */
82 mipscoff_symfile_init (objfile)
83 struct objfile *objfile;
87 /* Read a symbol file from a file. */
90 mipscoff_symfile_read (objfile, section_offsets, mainline)
91 struct objfile *objfile;
92 struct section_offsets *section_offsets;
95 bfd *abfd = objfile->obfd;
96 struct cleanup * back_to;
98 init_minimal_symbol_collection ();
99 back_to = make_cleanup (discard_minimal_symbols, 0);
101 /* Now that the executable file is positioned at symbol table,
102 process it and define symbols accordingly. */
104 if (ecoff_slurp_symbolic_info (abfd) == false)
105 error ("Error reading symbol table: %s", bfd_errmsg (bfd_get_error ()));
107 mdebug_build_psymtabs (objfile, &ecoff_backend (abfd)->debug_swap,
108 &ecoff_data (abfd)->debug_info, section_offsets);
110 /* Add the dynamic symbols if we are reading the main symbol table. */
113 read_alphacoff_dynamic_symtab (section_offsets, objfile);
115 if (!have_partial_symbols ())
118 printf_filtered ("(no debugging symbols found)...");
122 /* Install any minimal symbols that have been collected as the current
123 minimal symbols for this objfile. */
125 install_minimal_symbols (objfile);
127 do_cleanups (back_to);
130 /* Perform any local cleanups required when we are done with a
131 particular objfile. */
134 mipscoff_symfile_finish (objfile)
135 struct objfile *objfile;
139 /* Fake up identical offsets for all sections. */
141 static struct section_offsets *
142 mipscoff_symfile_offsets (objfile, addr)
143 struct objfile *objfile;
146 struct section_offsets *section_offsets;
149 objfile->num_sections = SECT_OFF_MAX;
150 section_offsets = ((struct section_offsets *)
151 obstack_alloc (&objfile->psymbol_obstack,
152 (sizeof (struct section_offsets)
153 + (sizeof (section_offsets->offsets)
154 * (SECT_OFF_MAX - 1)))));
156 for (i = 0; i < SECT_OFF_MAX; i++)
157 ANOFFSET (section_offsets, i) = addr;
159 return section_offsets;
162 /* Alpha OSF/1 encapsulates the dynamic symbols in ELF format in a
163 standard coff section. The ELF format for the symbols differs from
164 the format defined in elf/external.h. It seems that a normal ELF 32 bit
165 format is used, and the representation only changes because longs are
166 64 bit on the alpha. In addition, the handling of text/data section
167 indices for symbols is different from the ELF ABI.
168 As the BFD linker currently does not support dynamic linking on the alpha,
169 there seems to be no reason to pollute BFD with another mixture of object
170 file formats for now. */
172 /* Format of an alpha external ELF symbol. */
175 unsigned char st_name[4]; /* Symbol name, index in string tbl */
176 unsigned char st_pad[4]; /* Pad to long word boundary */
177 unsigned char st_value[8]; /* Value of the symbol */
178 unsigned char st_size[4]; /* Associated symbol size */
179 unsigned char st_info[1]; /* Type and binding attributes */
180 unsigned char st_other[1]; /* No defined meaning, 0 */
181 unsigned char st_shndx[2]; /* Associated section index */
182 } Elfalpha_External_Sym;
184 /* Format of an alpha external ELF dynamic info structure. */
187 unsigned char d_tag[4]; /* Tag */
188 unsigned char d_pad[4]; /* Pad to long word boundary */
190 unsigned char d_ptr[8]; /* Pointer value */
191 unsigned char d_val[4]; /* Integer value */
193 } Elfalpha_External_Dyn;
195 /* Struct to obtain the section pointers for alpha dynamic symbol info. */
197 struct alphacoff_dynsecinfo {
198 asection *sym_sect; /* Section pointer for .dynsym section */
199 asection *str_sect; /* Section pointer for .dynstr section */
200 asection *dyninfo_sect; /* Section pointer for .dynamic section */
201 asection *got_sect; /* Section pointer for .got section */
205 alphacoff_locate_sections PARAMS ((bfd *, asection *, void *));
207 /* We are called once per section from read_alphacoff_dynamic_symtab.
208 We need to examine each section we are passed, check to see
209 if it is something we are interested in processing, and
210 if so, stash away some access information for the section. */
213 alphacoff_locate_sections (ignore_abfd, sectp, sip)
218 register struct alphacoff_dynsecinfo *si;
220 si = (struct alphacoff_dynsecinfo *) sip;
222 if (STREQ (sectp->name, ".dynsym"))
224 si->sym_sect = sectp;
226 else if (STREQ (sectp->name, ".dynstr"))
228 si->str_sect = sectp;
230 else if (STREQ (sectp->name, ".dynamic"))
232 si->dyninfo_sect = sectp;
234 else if (STREQ (sectp->name, ".got"))
236 si->got_sect = sectp;
240 /* Scan an alpha dynamic symbol table for symbols of interest and
241 add them to the minimal symbol table. */
244 read_alphacoff_dynamic_symtab (section_offsets, objfile)
245 struct section_offsets *section_offsets;
246 struct objfile *objfile;
248 bfd *abfd = objfile->obfd;
249 struct alphacoff_dynsecinfo si;
252 char *dyninfo_secptr;
254 bfd_size_type sym_secsize;
255 bfd_size_type str_secsize;
256 bfd_size_type dyninfo_secsize;
257 bfd_size_type got_secsize;
261 Elfalpha_External_Sym *x_symp;
264 int got_entry_size = 8;
265 int dt_mips_local_gotno = -1;
266 int dt_mips_gotsym = -1;
269 /* We currently only know how to handle alpha dynamic symbols. */
270 if (bfd_get_arch (abfd) != bfd_arch_alpha)
273 /* Locate the dynamic symbols sections and read them in. */
274 memset ((char *) &si, 0, sizeof (si));
275 bfd_map_over_sections (abfd, alphacoff_locate_sections, (PTR) &si);
276 if (si.sym_sect == NULL
277 || si.str_sect == NULL
278 || si.dyninfo_sect == NULL
279 || si.got_sect == NULL)
282 sym_secsize = bfd_get_section_size_before_reloc (si.sym_sect);
283 str_secsize = bfd_get_section_size_before_reloc (si.str_sect);
284 dyninfo_secsize = bfd_get_section_size_before_reloc (si.dyninfo_sect);
285 got_secsize = bfd_get_section_size_before_reloc (si.got_sect);
286 sym_secptr = alloca (sym_secsize);
287 str_secptr = alloca (str_secsize);
288 dyninfo_secptr = alloca (dyninfo_secsize);
289 got_secptr = alloca (got_secsize);
291 if (!bfd_get_section_contents (abfd, si.sym_sect, sym_secptr,
292 (file_ptr)0, sym_secsize))
294 if (!bfd_get_section_contents (abfd, si.str_sect, str_secptr,
295 (file_ptr)0, str_secsize))
297 if (!bfd_get_section_contents (abfd, si.dyninfo_sect, dyninfo_secptr,
298 (file_ptr)0, dyninfo_secsize))
300 if (!bfd_get_section_contents (abfd, si.got_sect, got_secptr,
301 (file_ptr)0, got_secsize))
304 /* Find the number of local GOT entries and the index for the
305 the first dynamic symbol in the GOT. */
306 for (dyninfo_p = dyninfo_secptr, dyninfo_end = dyninfo_p + dyninfo_secsize;
307 dyninfo_p < dyninfo_end;
308 dyninfo_p += sizeof (Elfalpha_External_Dyn))
310 Elfalpha_External_Dyn *x_dynp = (Elfalpha_External_Dyn *)dyninfo_p;
313 dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_tag);
314 if (dyn_tag == DT_NULL)
316 else if (dyn_tag == DT_MIPS_LOCAL_GOTNO)
318 dt_mips_local_gotno = bfd_h_get_32 (abfd,
319 (bfd_byte *) x_dynp->d_un.d_val);
321 else if (dyn_tag == DT_MIPS_GOTSYM)
323 dt_mips_gotsym = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_un.d_val);
326 if (dt_mips_local_gotno < 0 || dt_mips_gotsym < 0)
329 /* Scan all dynamic symbols and enter them into the minimal symbol table
331 sym_count = sym_secsize / sizeof (Elfalpha_External_Sym);
332 stripped = (bfd_get_symcount (abfd) == 0);
334 /* Skip first symbol, which is a null dummy. */
335 for (i = 1, x_symp = (Elfalpha_External_Sym *) sym_secptr + 1;
342 unsigned char sym_info;
343 unsigned int sym_shndx;
345 enum minimal_symbol_type ms_type;
347 strx = bfd_h_get_32 (abfd, (bfd_byte *) x_symp->st_name);
348 if (strx >= str_secsize)
350 name = str_secptr + strx;
351 if (*name == '\0' || *name == '.')
354 sym_value = bfd_h_get_64 (abfd, (bfd_byte *) x_symp->st_value);
355 sym_info = bfd_h_get_8 (abfd, (bfd_byte *) x_symp->st_info);
356 sym_shndx = bfd_h_get_16 (abfd, (bfd_byte *) x_symp->st_shndx);
357 isglobal = (ELF_ST_BIND (sym_info) == STB_GLOBAL);
359 if (sym_shndx == SHN_UNDEF)
361 /* Handle undefined functions which are defined in a shared
363 if (ELF_ST_TYPE (sym_info) != STT_FUNC
364 || ELF_ST_BIND (sym_info) != STB_GLOBAL)
367 ms_type = mst_solib_trampoline;
369 /* If sym_value is nonzero, it points to the shared library
370 trampoline entry, which is what we are looking for.
372 If sym_value is zero, then we have to get the GOT entry
374 If the GOT entry is nonzero, it represents the quickstart
375 address of the function and we use that as the symbol value.
377 If the GOT entry is zero, the function address has to be resolved
378 by the runtime loader before the executable is started.
379 We are unable to find any meaningful address for these
380 functions in the executable file, so we skip them. */
383 int got_entry_offset =
384 (i - dt_mips_gotsym + dt_mips_local_gotno) * got_entry_size;
386 if (got_entry_offset < 0 || got_entry_offset >= got_secsize)
390 (bfd_byte *) (got_secptr + got_entry_offset));
397 /* Symbols defined in the executable itself. We only care about
398 them if this is a stripped executable, otherwise they have
399 been retrieved from the normal symbol table already. */
403 if (sym_shndx == SHN_MIPS_TEXT)
408 ms_type = mst_file_text;
409 sym_value += ANOFFSET (section_offsets, SECT_OFF_TEXT);
411 else if (sym_shndx == SHN_MIPS_DATA)
416 ms_type = mst_file_data;
417 sym_value += ANOFFSET (section_offsets, SECT_OFF_DATA);
419 else if (sym_shndx == SHN_MIPS_ACOMMON)
424 ms_type = mst_file_bss;
425 sym_value += ANOFFSET (section_offsets, SECT_OFF_BSS);
427 else if (sym_shndx == SHN_ABS)
437 prim_record_minimal_symbol (obsavestring (name,
439 &objfile -> symbol_obstack),
448 static struct sym_fns ecoff_sym_fns =
450 bfd_target_ecoff_flavour,
451 mipscoff_new_init, /* sym_new_init: init anything gbl to entire symtab */
452 mipscoff_symfile_init, /* sym_init: read initial info, setup for sym_read() */
453 mipscoff_symfile_read, /* sym_read: read a symbol file into symtab */
454 mipscoff_symfile_finish, /* sym_finish: finished with file, cleanup */
455 mipscoff_symfile_offsets, /* sym_offsets: dummy FIXME til implem sym reloc */
456 NULL /* next: pointer to next struct sym_fns */
460 _initialize_mipsread ()
462 add_symtab_fns (&ecoff_sym_fns);