OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [gdb/] [mipsread.c] - Blame information for rev 227

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
/* Read a symbol table in MIPS' format (Third-Eye).
2
 
3
   Copyright (C) 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
4
   1998, 1999, 2000, 2001, 2003, 2004, 2007, 2008, 2009, 2010
5
   Free Software Foundation, Inc.
6
 
7
   Contributed by Alessandro Forin (af@cs.cmu.edu) at CMU.  Major work
8
   by Per Bothner, John Gilmore and Ian Lance Taylor at Cygnus Support.
9
 
10
   This file is part of GDB.
11
 
12
   This program is free software; you can redistribute it and/or modify
13
   it under the terms of the GNU General Public License as published by
14
   the Free Software Foundation; either version 3 of the License, or
15
   (at your option) any later version.
16
 
17
   This program is distributed in the hope that it will be useful,
18
   but WITHOUT ANY WARRANTY; without even the implied warranty of
19
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
   GNU General Public License for more details.
21
 
22
   You should have received a copy of the GNU General Public License
23
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
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/internal.h"
43
#include "elf/mips.h"
44
 
45
static void
46
read_alphacoff_dynamic_symtab (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
  buildsym_new_init ();
58
}
59
 
60
/* Initialize to read a symbol file (nothing to do).  */
61
 
62
static void
63
mipscoff_symfile_init (struct objfile *objfile)
64
{
65
}
66
 
67
/* Read a symbol file from a file.  */
68
 
69
static void
70
mipscoff_symfile_read (struct objfile *objfile, int symfile_flags)
71
{
72
  bfd *abfd = objfile->obfd;
73
  struct cleanup *back_to;
74
 
75
  init_minimal_symbol_collection ();
76
  back_to = make_cleanup_discard_minimal_symbols ();
77
 
78
  /* Now that the executable file is positioned at symbol table,
79
     process it and define symbols accordingly.  */
80
 
81
  if (!((*ecoff_backend (abfd)->debug_swap.read_debug_info)
82
        (abfd, (asection *) NULL, &ecoff_data (abfd)->debug_info)))
83
    error (_("Error reading symbol table: %s"), bfd_errmsg (bfd_get_error ()));
84
 
85
  mdebug_build_psymtabs (objfile, &ecoff_backend (abfd)->debug_swap,
86
                         &ecoff_data (abfd)->debug_info);
87
 
88
  /* Add alpha coff dynamic symbols.  */
89
 
90
  read_alphacoff_dynamic_symtab (objfile->section_offsets, objfile);
91
 
92
  /* Install any minimal symbols that have been collected as the current
93
     minimal symbols for this objfile. */
94
 
95
  install_minimal_symbols (objfile);
96
  do_cleanups (back_to);
97
}
98
 
99
/* Perform any local cleanups required when we are done with a
100
   particular objfile.  */
101
 
102
static void
103
mipscoff_symfile_finish (struct objfile *objfile)
104
{
105
}
106
 
107
/* Alpha OSF/1 encapsulates the dynamic symbols in ELF format in a
108
   standard COFF section.  The ELF format for the symbols differs from
109
   the format defined in elf/external.h.  It seems that a normal ELF
110
   32-bit format is used, and the representation only changes because
111
   longs are 64-bit on the alpha. In addition, the handling of
112
   text/data section indices for symbols is different from the ELF
113
   ABI.  As the BFD linker currently does not support dynamic linking
114
   on the alpha, there seems to be no reason to pollute BFD with
115
   another mixture of object file formats for now.  */
116
 
117
/* Format of an alpha external ELF symbol.  */
118
 
119
typedef struct
120
{
121
  unsigned char st_name[4];     /* Symbol name, index in string table.  */
122
  unsigned char st_pad[4];      /* Pad to long word boundary.  */
123
  unsigned char st_value[8];    /* Value of the symbol.  */
124
  unsigned char st_size[4];     /* Associated symbol size.  */
125
  unsigned char st_info[1];     /* Type and binding attributes.  */
126
  unsigned char st_other[1];    /* No defined meaning, 0.  */
127
  unsigned char st_shndx[2];    /* Associated section index.  */
128
} Elfalpha_External_Sym;
129
 
130
/* Format of an alpha external ELF dynamic info structure.  */
131
 
132
typedef struct
133
{
134
  unsigned char d_tag[4];       /* Tag.  */
135
  unsigned char d_pad[4];       /* Pad to long word boundary.  */
136
  union
137
  {
138
    unsigned char d_ptr[8];     /* Pointer value.  */
139
    unsigned char d_val[4];     /* Integer value.  */
140
  }
141
  d_un;
142
} Elfalpha_External_Dyn;
143
 
144
/* Struct to obtain the section pointers for alpha dynamic symbol info.  */
145
 
146
struct alphacoff_dynsecinfo
147
{
148
  asection *sym_sect;           /* Section pointer for .dynsym section.  */
149
  asection *str_sect;           /* Section pointer for .dynstr section.  */
150
  asection *dyninfo_sect;       /* Section pointer for .dynamic section.  */
151
  asection *got_sect;           /* Section pointer for .got section.  */
152
};
153
 
154
/* We are called once per section from read_alphacoff_dynamic_symtab.
155
   We need to examine each section we are passed, check to see if it
156
   is something we are interested in processing, and if so, stash away
157
   some access information for the section.  */
158
 
159
static void
160
alphacoff_locate_sections (bfd *ignore_abfd, asection *sectp, void *sip)
161
{
162
  struct alphacoff_dynsecinfo *si;
163
 
164
  si = (struct alphacoff_dynsecinfo *) sip;
165
 
166
  if (strcmp (sectp->name, ".dynsym") == 0)
167
    si->sym_sect = sectp;
168
  else if (strcmp (sectp->name, ".dynstr") == 0)
169
    si->str_sect = sectp;
170
  else if (strcmp (sectp->name, ".dynamic") == 0)
171
    si->dyninfo_sect = sectp;
172
  else if (strcmp (sectp->name, ".got") == 0)
173
      si->got_sect = sectp;
174
}
175
 
176
/* Scan an alpha dynamic symbol table for symbols of interest and add
177
   them to the minimal symbol table.  */
178
 
179
static void
180
read_alphacoff_dynamic_symtab (struct section_offsets *section_offsets,
181
                               struct objfile *objfile)
182
{
183
  bfd *abfd = objfile->obfd;
184
  struct alphacoff_dynsecinfo si;
185
  char *sym_secptr;
186
  char *str_secptr;
187
  char *dyninfo_secptr;
188
  char *got_secptr;
189
  bfd_size_type sym_secsize;
190
  bfd_size_type str_secsize;
191
  bfd_size_type dyninfo_secsize;
192
  bfd_size_type got_secsize;
193
  int sym_count;
194
  int i;
195
  int stripped;
196
  Elfalpha_External_Sym *x_symp;
197
  char *dyninfo_p;
198
  char *dyninfo_end;
199
  int got_entry_size = 8;
200
  int dt_mips_local_gotno = -1;
201
  int dt_mips_gotsym = -1;
202
  struct cleanup *cleanups;
203
 
204
  /* We currently only know how to handle alpha dynamic symbols.  */
205
  if (bfd_get_arch (abfd) != bfd_arch_alpha)
206
    return;
207
 
208
  /* Locate the dynamic symbols sections and read them in.  */
209
  memset ((char *) &si, 0, sizeof (si));
210
  bfd_map_over_sections (abfd, alphacoff_locate_sections, (void *) & si);
211
  if (si.sym_sect == NULL || si.str_sect == NULL
212
      || si.dyninfo_sect == NULL || si.got_sect == NULL)
213
    return;
214
 
215
  sym_secsize = bfd_get_section_size (si.sym_sect);
216
  str_secsize = bfd_get_section_size (si.str_sect);
217
  dyninfo_secsize = bfd_get_section_size (si.dyninfo_sect);
218
  got_secsize = bfd_get_section_size (si.got_sect);
219
  sym_secptr = xmalloc (sym_secsize);
220
  cleanups = make_cleanup (xfree, sym_secptr);
221
  str_secptr = xmalloc (str_secsize);
222
  make_cleanup (xfree, str_secptr);
223
  dyninfo_secptr = xmalloc (dyninfo_secsize);
224
  make_cleanup (xfree, dyninfo_secptr);
225
  got_secptr = xmalloc (got_secsize);
226
  make_cleanup (xfree, got_secptr);
227
 
228
  if (!bfd_get_section_contents (abfd, si.sym_sect, sym_secptr,
229
                                 (file_ptr) 0, sym_secsize))
230
    return;
231
  if (!bfd_get_section_contents (abfd, si.str_sect, str_secptr,
232
                                 (file_ptr) 0, str_secsize))
233
    return;
234
  if (!bfd_get_section_contents (abfd, si.dyninfo_sect, dyninfo_secptr,
235
                                 (file_ptr) 0, dyninfo_secsize))
236
    return;
237
  if (!bfd_get_section_contents (abfd, si.got_sect, got_secptr,
238
                                 (file_ptr) 0, got_secsize))
239
    return;
240
 
241
  /* Find the number of local GOT entries and the index for the the
242
     first dynamic symbol in the GOT.  */
243
  for (dyninfo_p = dyninfo_secptr, dyninfo_end = dyninfo_p + dyninfo_secsize;
244
       dyninfo_p < dyninfo_end;
245
       dyninfo_p += sizeof (Elfalpha_External_Dyn))
246
    {
247
      Elfalpha_External_Dyn *x_dynp = (Elfalpha_External_Dyn *) dyninfo_p;
248
      long dyn_tag;
249
 
250
      dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_tag);
251
      if (dyn_tag == DT_NULL)
252
        break;
253
      else if (dyn_tag == DT_MIPS_LOCAL_GOTNO)
254
        {
255
          if (dt_mips_local_gotno < 0)
256
            dt_mips_local_gotno
257
              = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_un.d_val);
258
        }
259
      else if (dyn_tag == DT_MIPS_GOTSYM)
260
        {
261
          if (dt_mips_gotsym < 0)
262
            dt_mips_gotsym
263
              = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_un.d_val);
264
        }
265
    }
266
  if (dt_mips_local_gotno < 0 || dt_mips_gotsym < 0)
267
    return;
268
 
269
  /* Scan all dynamic symbols and enter them into the minimal symbol
270
     table if appropriate.  */
271
  sym_count = sym_secsize / sizeof (Elfalpha_External_Sym);
272
  stripped = (bfd_get_symcount (abfd) == 0);
273
 
274
  /* Skip first symbol, which is a null dummy.  */
275
  for (i = 1, x_symp = (Elfalpha_External_Sym *) sym_secptr + 1;
276
       i < sym_count;
277
       i++, x_symp++)
278
    {
279
      unsigned long strx;
280
      char *name;
281
      bfd_vma sym_value;
282
      unsigned char sym_info;
283
      unsigned int sym_shndx;
284
      int isglobal;
285
      enum minimal_symbol_type ms_type;
286
 
287
      strx = bfd_h_get_32 (abfd, (bfd_byte *) x_symp->st_name);
288
      if (strx >= str_secsize)
289
        continue;
290
      name = str_secptr + strx;
291
      if (*name == '\0' || *name == '.')
292
        continue;
293
 
294
      sym_value = bfd_h_get_64 (abfd, (bfd_byte *) x_symp->st_value);
295
      sym_info = bfd_h_get_8 (abfd, (bfd_byte *) x_symp->st_info);
296
      sym_shndx = bfd_h_get_16 (abfd, (bfd_byte *) x_symp->st_shndx);
297
      if (sym_shndx >= (SHN_LORESERVE & 0xffff))
298
        sym_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
299
      isglobal = (ELF_ST_BIND (sym_info) == STB_GLOBAL);
300
 
301
      if (sym_shndx == SHN_UNDEF)
302
        {
303
          /* Handle undefined functions which are defined in a shared
304
             library.  */
305
          if (ELF_ST_TYPE (sym_info) != STT_FUNC
306
              || ELF_ST_BIND (sym_info) != STB_GLOBAL)
307
            continue;
308
 
309
          ms_type = mst_solib_trampoline;
310
 
311
          /* If sym_value is nonzero, it points to the shared library
312
             trampoline entry, which is what we are looking for.
313
 
314
             If sym_value is zero, then we have to get the GOT entry
315
             for the symbol.
316
 
317
             If the GOT entry is nonzero, it represents the quickstart
318
             address of the function and we use that as the symbol
319
             value.
320
 
321
             If the GOT entry is zero, the function address has to be
322
             resolved by the runtime loader before the executable is
323
             started.  We are unable to find any meaningful address
324
             for these functions in the executable file, so we skip
325
             them.  */
326
          if (sym_value == 0)
327
            {
328
              int got_entry_offset =
329
                (i - dt_mips_gotsym + dt_mips_local_gotno) * got_entry_size;
330
 
331
              if (got_entry_offset < 0 || got_entry_offset >= got_secsize)
332
                continue;
333
              sym_value =
334
                bfd_h_get_64 (abfd,
335
                              (bfd_byte *) (got_secptr + got_entry_offset));
336
              if (sym_value == 0)
337
                continue;
338
            }
339
        }
340
      else
341
        {
342
          /* Symbols defined in the executable itself. We only care
343
             about them if this is a stripped executable, otherwise
344
             they have been retrieved from the normal symbol table
345
             already.  */
346
          if (!stripped)
347
            continue;
348
 
349
          if (sym_shndx == SHN_MIPS_TEXT)
350
            {
351
              if (isglobal)
352
                ms_type = mst_text;
353
              else
354
                ms_type = mst_file_text;
355
              sym_value += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
356
            }
357
          else if (sym_shndx == SHN_MIPS_DATA)
358
            {
359
              if (isglobal)
360
                ms_type = mst_data;
361
              else
362
                ms_type = mst_file_data;
363
              sym_value += ANOFFSET (section_offsets, SECT_OFF_DATA (objfile));
364
            }
365
          else if (sym_shndx == SHN_MIPS_ACOMMON)
366
            {
367
              if (isglobal)
368
                ms_type = mst_bss;
369
              else
370
                ms_type = mst_file_bss;
371
              sym_value += ANOFFSET (section_offsets, SECT_OFF_BSS (objfile));
372
            }
373
          else if (sym_shndx == SHN_ABS)
374
            {
375
              ms_type = mst_abs;
376
            }
377
          else
378
            {
379
              continue;
380
            }
381
        }
382
 
383
      prim_record_minimal_symbol (name, sym_value, ms_type, objfile);
384
    }
385
 
386
  do_cleanups (cleanups);
387
}
388
 
389
/* Initialization.  */
390
 
391
static struct sym_fns ecoff_sym_fns =
392
{
393
  bfd_target_ecoff_flavour,
394
  mipscoff_new_init,            /* sym_new_init: init anything gbl to entire symtab */
395
  mipscoff_symfile_init,        /* sym_init: read initial info, setup for sym_read() */
396
  mipscoff_symfile_read,        /* sym_read: read a symbol file into symtab */
397
  mipscoff_symfile_finish,      /* sym_finish: finished with file, cleanup */
398
  default_symfile_offsets,      /* sym_offsets: dummy FIXME til implem sym reloc */
399
  default_symfile_segments,     /* sym_segments: Get segment information from
400
                                   a file.  */
401
  NULL,                         /* sym_read_linetable */
402
  default_symfile_relocate,     /* sym_relocate: Relocate a debug section.  */
403
  NULL                          /* next: pointer to next struct sym_fns */
404
};
405
 
406
/* Provide a prototype to silence -Wmissing-prototypes.  */
407
void _initialize_mipsread (void);
408
 
409
void
410
_initialize_mipsread (void)
411
{
412
  add_symtab_fns (&ecoff_sym_fns);
413
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.