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

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-src/] [gdb-6.8/] [pre-binutils-2.20.1-sync/] [gdb/] [mipsread.c] - Blame information for rev 435

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 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
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/mips.h"
43
 
44
static void
45
read_alphacoff_dynamic_symtab (struct section_offsets *,
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
53
mipscoff_new_init (struct objfile *ignore)
54
{
55
  stabsread_new_init ();
56
  buildsym_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, int mainline)
70
{
71
  bfd *abfd = objfile->obfd;
72
  struct cleanup *back_to;
73
 
74
  init_minimal_symbol_collection ();
75
  back_to = make_cleanup_discard_minimal_symbols ();
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
 
89
  read_alphacoff_dynamic_symtab (objfile->section_offsets, objfile);
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
102
mipscoff_symfile_finish (struct objfile *objfile)
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.  */
127
} Elfalpha_External_Sym;
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;
141
} Elfalpha_External_Dyn;
142
 
143
/* Struct to obtain the section pointers for alpha dynamic symbol info.  */
144
 
145
struct alphacoff_dynsecinfo
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
179
read_alphacoff_dynamic_symtab (struct section_offsets *section_offsets,
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 (free, sym_secptr);
220
  str_secptr = xmalloc (str_secsize);
221
  make_cleanup (free, str_secptr);
222
  dyninfo_secptr = xmalloc (dyninfo_secsize);
223
  make_cleanup (free, dyninfo_secptr);
224
  got_secptr = xmalloc (got_secsize);
225
  make_cleanup (free, got_secptr);
226
 
227
  if (!bfd_get_section_contents (abfd, si.sym_sect, sym_secptr,
228
                                 (file_ptr) 0, sym_secsize))
229
    return;
230
  if (!bfd_get_section_contents (abfd, si.str_sect, str_secptr,
231
                                 (file_ptr) 0, str_secsize))
232
    return;
233
  if (!bfd_get_section_contents (abfd, si.dyninfo_sect, dyninfo_secptr,
234
                                 (file_ptr) 0, dyninfo_secsize))
235
    return;
236
  if (!bfd_get_section_contents (abfd, si.got_sect, got_secptr,
237
                                 (file_ptr) 0, got_secsize))
238
    return;
239
 
240
  /* Find the number of local GOT entries and the index for the the
241
     first dynamic symbol in the GOT.  */
242
  for (dyninfo_p = dyninfo_secptr, dyninfo_end = dyninfo_p + dyninfo_secsize;
243
       dyninfo_p < dyninfo_end;
244
       dyninfo_p += sizeof (Elfalpha_External_Dyn))
245
    {
246
      Elfalpha_External_Dyn *x_dynp = (Elfalpha_External_Dyn *) dyninfo_p;
247
      long dyn_tag;
248
 
249
      dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_tag);
250
      if (dyn_tag == DT_NULL)
251
        break;
252
      else if (dyn_tag == DT_MIPS_LOCAL_GOTNO)
253
        {
254
          if (dt_mips_local_gotno < 0)
255
            dt_mips_local_gotno
256
              = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_un.d_val);
257
        }
258
      else if (dyn_tag == DT_MIPS_GOTSYM)
259
        {
260
          if (dt_mips_gotsym < 0)
261
            dt_mips_gotsym
262
              = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_un.d_val);
263
        }
264
    }
265
  if (dt_mips_local_gotno < 0 || dt_mips_gotsym < 0)
266
    return;
267
 
268
  /* Scan all dynamic symbols and enter them into the minimal symbol
269
     table if appropriate.  */
270
  sym_count = sym_secsize / sizeof (Elfalpha_External_Sym);
271
  stripped = (bfd_get_symcount (abfd) == 0);
272
 
273
  /* Skip first symbol, which is a null dummy.  */
274
  for (i = 1, x_symp = (Elfalpha_External_Sym *) sym_secptr + 1;
275
       i < sym_count;
276
       i++, x_symp++)
277
    {
278
      unsigned long strx;
279
      char *name;
280
      bfd_vma sym_value;
281
      unsigned char sym_info;
282
      unsigned int sym_shndx;
283
      int isglobal;
284
      enum minimal_symbol_type ms_type;
285
 
286
      strx = bfd_h_get_32 (abfd, (bfd_byte *) x_symp->st_name);
287
      if (strx >= str_secsize)
288
        continue;
289
      name = str_secptr + strx;
290
      if (*name == '\0' || *name == '.')
291
        continue;
292
 
293
      sym_value = bfd_h_get_64 (abfd, (bfd_byte *) x_symp->st_value);
294
      sym_info = bfd_h_get_8 (abfd, (bfd_byte *) x_symp->st_info);
295
      sym_shndx = bfd_h_get_16 (abfd, (bfd_byte *) x_symp->st_shndx);
296
      isglobal = (ELF_ST_BIND (sym_info) == STB_GLOBAL);
297
 
298
      if (sym_shndx == SHN_UNDEF)
299
        {
300
          /* Handle undefined functions which are defined in a shared
301
             library.  */
302
          if (ELF_ST_TYPE (sym_info) != STT_FUNC
303
              || ELF_ST_BIND (sym_info) != STB_GLOBAL)
304
            continue;
305
 
306
          ms_type = mst_solib_trampoline;
307
 
308
          /* If sym_value is nonzero, it points to the shared library
309
             trampoline entry, which is what we are looking for.
310
 
311
             If sym_value is zero, then we have to get the GOT entry
312
             for the symbol.
313
 
314
             If the GOT entry is nonzero, it represents the quickstart
315
             address of the function and we use that as the symbol
316
             value.
317
 
318
             If the GOT entry is zero, the function address has to be
319
             resolved by the runtime loader before the executable is
320
             started.  We are unable to find any meaningful address
321
             for these functions in the executable file, so we skip
322
             them.  */
323
          if (sym_value == 0)
324
            {
325
              int got_entry_offset =
326
                (i - dt_mips_gotsym + dt_mips_local_gotno) * got_entry_size;
327
 
328
              if (got_entry_offset < 0 || got_entry_offset >= got_secsize)
329
                continue;
330
              sym_value =
331
                bfd_h_get_64 (abfd,
332
                              (bfd_byte *) (got_secptr + got_entry_offset));
333
              if (sym_value == 0)
334
                continue;
335
            }
336
        }
337
      else
338
        {
339
          /* Symbols defined in the executable itself. We only care
340
             about them if this is a stripped executable, otherwise
341
             they have been retrieved from the normal symbol table
342
             already.  */
343
          if (!stripped)
344
            continue;
345
 
346
          if (sym_shndx == SHN_MIPS_TEXT)
347
            {
348
              if (isglobal)
349
                ms_type = mst_text;
350
              else
351
                ms_type = mst_file_text;
352
              sym_value += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
353
            }
354
          else if (sym_shndx == SHN_MIPS_DATA)
355
            {
356
              if (isglobal)
357
                ms_type = mst_data;
358
              else
359
                ms_type = mst_file_data;
360
              sym_value += ANOFFSET (section_offsets, SECT_OFF_DATA (objfile));
361
            }
362
          else if (sym_shndx == SHN_MIPS_ACOMMON)
363
            {
364
              if (isglobal)
365
                ms_type = mst_bss;
366
              else
367
                ms_type = mst_file_bss;
368
              sym_value += ANOFFSET (section_offsets, SECT_OFF_BSS (objfile));
369
            }
370
          else if (sym_shndx == SHN_ABS)
371
            {
372
              ms_type = mst_abs;
373
            }
374
          else
375
            {
376
              continue;
377
            }
378
        }
379
 
380
      prim_record_minimal_symbol (name, sym_value, ms_type, objfile);
381
    }
382
 
383
  do_cleanups (cleanups);
384
}
385
 
386
/* Initialization.  */
387
 
388
static struct sym_fns ecoff_sym_fns =
389
{
390
  bfd_target_ecoff_flavour,
391
  mipscoff_new_init,            /* sym_new_init: init anything gbl to entire symtab */
392
  mipscoff_symfile_init,        /* sym_init: read initial info, setup for sym_read() */
393
  mipscoff_symfile_read,        /* sym_read: read a symbol file into symtab */
394
  mipscoff_symfile_finish,      /* sym_finish: finished with file, cleanup */
395
  default_symfile_offsets,      /* sym_offsets: dummy FIXME til implem sym reloc */
396
  default_symfile_segments,     /* sym_segments: Get segment information from
397
                                   a file.  */
398
  NULL,                         /* sym_read_linetable */
399
  NULL                          /* next: pointer to next struct sym_fns */
400
};
401
 
402
/* Provide a prototype to silence -Wmissing-prototypes.  */
403
void _initialize_mipsread (void);
404
 
405
void
406
_initialize_mipsread (void)
407
{
408
  add_symtab_fns (&ecoff_sym_fns);
409
}

powered by: WebSVN 2.1.0

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