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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [gdb/] [mipsread.c] - Blame information for rev 853

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 225 jeremybenn
#include "elf/internal.h"       /* JPB for compatibility with latest binutils */
43 24 jeremybenn
#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 mainline)
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 (free, sym_secptr);
221
  str_secptr = xmalloc (str_secsize);
222
  make_cleanup (free, str_secptr);
223
  dyninfo_secptr = xmalloc (dyninfo_secsize);
224
  make_cleanup (free, dyninfo_secptr);
225
  got_secptr = xmalloc (got_secsize);
226
  make_cleanup (free, 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
      isglobal = (ELF_ST_BIND (sym_info) == STB_GLOBAL);
298
 
299
      if (sym_shndx == SHN_UNDEF)
300
        {
301
          /* Handle undefined functions which are defined in a shared
302
             library.  */
303
          if (ELF_ST_TYPE (sym_info) != STT_FUNC
304
              || ELF_ST_BIND (sym_info) != STB_GLOBAL)
305
            continue;
306
 
307
          ms_type = mst_solib_trampoline;
308
 
309
          /* If sym_value is nonzero, it points to the shared library
310
             trampoline entry, which is what we are looking for.
311
 
312
             If sym_value is zero, then we have to get the GOT entry
313
             for the symbol.
314
 
315
             If the GOT entry is nonzero, it represents the quickstart
316
             address of the function and we use that as the symbol
317
             value.
318
 
319
             If the GOT entry is zero, the function address has to be
320
             resolved by the runtime loader before the executable is
321
             started.  We are unable to find any meaningful address
322
             for these functions in the executable file, so we skip
323
             them.  */
324
          if (sym_value == 0)
325
            {
326
              int got_entry_offset =
327
                (i - dt_mips_gotsym + dt_mips_local_gotno) * got_entry_size;
328
 
329
              if (got_entry_offset < 0 || got_entry_offset >= got_secsize)
330
                continue;
331
              sym_value =
332
                bfd_h_get_64 (abfd,
333
                              (bfd_byte *) (got_secptr + got_entry_offset));
334
              if (sym_value == 0)
335
                continue;
336
            }
337
        }
338
      else
339
        {
340
          /* Symbols defined in the executable itself. We only care
341
             about them if this is a stripped executable, otherwise
342
             they have been retrieved from the normal symbol table
343
             already.  */
344
          if (!stripped)
345
            continue;
346
 
347
          if (sym_shndx == SHN_MIPS_TEXT)
348
            {
349
              if (isglobal)
350
                ms_type = mst_text;
351
              else
352
                ms_type = mst_file_text;
353
              sym_value += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
354
            }
355
          else if (sym_shndx == SHN_MIPS_DATA)
356
            {
357
              if (isglobal)
358
                ms_type = mst_data;
359
              else
360
                ms_type = mst_file_data;
361
              sym_value += ANOFFSET (section_offsets, SECT_OFF_DATA (objfile));
362
            }
363
          else if (sym_shndx == SHN_MIPS_ACOMMON)
364
            {
365
              if (isglobal)
366
                ms_type = mst_bss;
367
              else
368
                ms_type = mst_file_bss;
369
              sym_value += ANOFFSET (section_offsets, SECT_OFF_BSS (objfile));
370
            }
371
          else if (sym_shndx == SHN_ABS)
372
            {
373
              ms_type = mst_abs;
374
            }
375
          else
376
            {
377
              continue;
378
            }
379
        }
380
 
381
      prim_record_minimal_symbol (name, sym_value, ms_type, objfile);
382
    }
383
 
384
  do_cleanups (cleanups);
385
}
386
 
387
/* Initialization.  */
388
 
389
static struct sym_fns ecoff_sym_fns =
390
{
391
  bfd_target_ecoff_flavour,
392
  mipscoff_new_init,            /* sym_new_init: init anything gbl to entire symtab */
393
  mipscoff_symfile_init,        /* sym_init: read initial info, setup for sym_read() */
394
  mipscoff_symfile_read,        /* sym_read: read a symbol file into symtab */
395
  mipscoff_symfile_finish,      /* sym_finish: finished with file, cleanup */
396
  default_symfile_offsets,      /* sym_offsets: dummy FIXME til implem sym reloc */
397
  default_symfile_segments,     /* sym_segments: Get segment information from
398
                                   a file.  */
399
  NULL,                         /* sym_read_linetable */
400
  NULL                          /* next: pointer to next struct sym_fns */
401
};
402
 
403
/* Provide a prototype to silence -Wmissing-prototypes.  */
404
void _initialize_mipsread (void);
405
 
406
void
407
_initialize_mipsread (void)
408
{
409
  add_symtab_fns (&ecoff_sym_fns);
410
}

powered by: WebSVN 2.1.0

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