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

Subversion Repositories or1k

[/] [or1k/] [tags/] [VER_5_3/] [gdb-5.3/] [gdb/] [mipsread.c] - Blame information for rev 1778

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

Line No. Rev Author Line
1 1181 sfurman
/* Read a symbol table in MIPS' format (Third-Eye).
2
   Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
3
   1998, 1999, 2000, 2001
4
   Free Software Foundation, Inc.
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 2 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, write to the Free Software
22
   Foundation, Inc., 59 Temple Place - Suite 330,
23
   Boston, MA 02111-1307, USA.  */
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 "symfile.h"
33
#include "objfiles.h"
34
#include "buildsym.h"
35
#include "stabsread.h"
36
 
37
#include "coff/sym.h"
38
#include "coff/internal.h"
39
#include "coff/ecoff.h"
40
#include "libcoff.h"            /* Private BFD COFF information.  */
41
#include "libecoff.h"           /* Private BFD ECOFF information.  */
42
#include "elf/common.h"
43
#include "elf/mips.h"
44
 
45
extern void _initialize_mipsread (void);
46
 
47
static void mipscoff_new_init (struct objfile *);
48
 
49
static void mipscoff_symfile_init (struct objfile *);
50
 
51
static void mipscoff_symfile_read (struct objfile *, int);
52
 
53
static void mipscoff_symfile_finish (struct objfile *);
54
 
55
static void
56
read_alphacoff_dynamic_symtab (struct section_offsets *,
57
                               struct objfile *objfile);
58
 
59
/* Initialize anything that needs initializing when a completely new
60
   symbol file is specified (not just adding some symbols from another
61
   file, e.g. a shared library).  */
62
 
63
extern CORE_ADDR sigtramp_address;
64
 
65
static void
66
mipscoff_new_init (struct objfile *ignore)
67
{
68
  sigtramp_address = 0;
69
  stabsread_new_init ();
70
  buildsym_new_init ();
71
}
72
 
73
/* Initialize to read a symbol file (nothing to do).  */
74
 
75
static void
76
mipscoff_symfile_init (struct objfile *objfile)
77
{
78
}
79
 
80
/* Read a symbol file from a file.  */
81
 
82
static void
83
mipscoff_symfile_read (struct objfile *objfile, int mainline)
84
{
85
  bfd *abfd = objfile->obfd;
86
  struct cleanup *back_to;
87
 
88
  init_minimal_symbol_collection ();
89
  back_to = make_cleanup_discard_minimal_symbols ();
90
 
91
  /* Now that the executable file is positioned at symbol table,
92
     process it and define symbols accordingly.  */
93
 
94
  if (!((*ecoff_backend (abfd)->debug_swap.read_debug_info)
95
        (abfd, (asection *) NULL, &ecoff_data (abfd)->debug_info)))
96
    error ("Error reading symbol table: %s", bfd_errmsg (bfd_get_error ()));
97
 
98
  mdebug_build_psymtabs (objfile, &ecoff_backend (abfd)->debug_swap,
99
                         &ecoff_data (abfd)->debug_info);
100
 
101
  /* Add alpha coff dynamic symbols.  */
102
 
103
  read_alphacoff_dynamic_symtab (objfile->section_offsets, objfile);
104
 
105
  /* Install any minimal symbols that have been collected as the current
106
     minimal symbols for this objfile. */
107
 
108
  install_minimal_symbols (objfile);
109
 
110
  /* If the entry_file bounds are still unknown after processing the
111
     partial symbols, then try to set them from the minimal symbols
112
     surrounding the entry_point.  */
113
 
114
  if (mainline
115
      && objfile->ei.entry_point != INVALID_ENTRY_POINT
116
      && objfile->ei.entry_file_lowpc == INVALID_ENTRY_LOWPC)
117
    {
118
      struct minimal_symbol *m;
119
 
120
      m = lookup_minimal_symbol_by_pc (objfile->ei.entry_point);
121
      if (m && SYMBOL_NAME (m + 1))
122
        {
123
          objfile->ei.entry_file_lowpc = SYMBOL_VALUE_ADDRESS (m);
124
          objfile->ei.entry_file_highpc = SYMBOL_VALUE_ADDRESS (m + 1);
125
        }
126
    }
127
 
128
  do_cleanups (back_to);
129
}
130
 
131
/* Perform any local cleanups required when we are done with a
132
   particular objfile.  */
133
 
134
static void
135
mipscoff_symfile_finish (struct objfile *objfile)
136
{
137
}
138
 
139
/* Alpha OSF/1 encapsulates the dynamic symbols in ELF format in a
140
   standard coff section.  The ELF format for the symbols differs from
141
   the format defined in elf/external.h. It seems that a normal ELF 32 bit
142
   format is used, and the representation only changes because longs are
143
   64 bit on the alpha. In addition, the handling of text/data section
144
   indices for symbols is different from the ELF ABI.
145
   As the BFD linker currently does not support dynamic linking on the alpha,
146
   there seems to be no reason to pollute BFD with another mixture of object
147
   file formats for now.  */
148
 
149
/* Format of an alpha external ELF symbol.  */
150
 
151
typedef struct
152
{
153
  unsigned char st_name[4];     /* Symbol name, index in string tbl */
154
  unsigned char st_pad[4];      /* Pad to long word boundary */
155
  unsigned char st_value[8];    /* Value of the symbol */
156
  unsigned char st_size[4];     /* Associated symbol size */
157
  unsigned char st_info[1];     /* Type and binding attributes */
158
  unsigned char st_other[1];    /* No defined meaning, 0 */
159
  unsigned char st_shndx[2];    /* Associated section index */
160
}
161
Elfalpha_External_Sym;
162
 
163
/* Format of an alpha external ELF dynamic info structure.  */
164
 
165
typedef struct
166
  {
167
    unsigned char d_tag[4];     /* Tag */
168
    unsigned char d_pad[4];     /* Pad to long word boundary */
169
    union
170
      {
171
        unsigned char d_ptr[8]; /* Pointer value */
172
        unsigned char d_val[4]; /* Integer value */
173
      }
174
    d_un;
175
  }
176
Elfalpha_External_Dyn;
177
 
178
/* Struct to obtain the section pointers for alpha dynamic symbol info.  */
179
 
180
struct alphacoff_dynsecinfo
181
  {
182
    asection *sym_sect;         /* Section pointer for .dynsym section */
183
    asection *str_sect;         /* Section pointer for .dynstr section */
184
    asection *dyninfo_sect;     /* Section pointer for .dynamic section */
185
    asection *got_sect;         /* Section pointer for .got section */
186
  };
187
 
188
/* We are called once per section from read_alphacoff_dynamic_symtab.
189
   We need to examine each section we are passed, check to see
190
   if it is something we are interested in processing, and
191
   if so, stash away some access information for the section.  */
192
 
193
static void
194
alphacoff_locate_sections (bfd *ignore_abfd, asection *sectp, void *sip)
195
{
196
  register struct alphacoff_dynsecinfo *si;
197
 
198
  si = (struct alphacoff_dynsecinfo *) sip;
199
 
200
  if (STREQ (sectp->name, ".dynsym"))
201
    {
202
      si->sym_sect = sectp;
203
    }
204
  else if (STREQ (sectp->name, ".dynstr"))
205
    {
206
      si->str_sect = sectp;
207
    }
208
  else if (STREQ (sectp->name, ".dynamic"))
209
    {
210
      si->dyninfo_sect = sectp;
211
    }
212
  else if (STREQ (sectp->name, ".got"))
213
    {
214
      si->got_sect = sectp;
215
    }
216
}
217
 
218
/* Scan an alpha dynamic symbol table for symbols of interest and
219
   add them to the minimal symbol table.  */
220
 
221
static void
222
read_alphacoff_dynamic_symtab (struct section_offsets *section_offsets,
223
                               struct objfile *objfile)
224
{
225
  bfd *abfd = objfile->obfd;
226
  struct alphacoff_dynsecinfo si;
227
  char *sym_secptr;
228
  char *str_secptr;
229
  char *dyninfo_secptr;
230
  char *got_secptr;
231
  bfd_size_type sym_secsize;
232
  bfd_size_type str_secsize;
233
  bfd_size_type dyninfo_secsize;
234
  bfd_size_type got_secsize;
235
  int sym_count;
236
  int i;
237
  int stripped;
238
  Elfalpha_External_Sym *x_symp;
239
  char *dyninfo_p;
240
  char *dyninfo_end;
241
  int got_entry_size = 8;
242
  int dt_mips_local_gotno = -1;
243
  int dt_mips_gotsym = -1;
244
  struct cleanup *cleanups;
245
 
246
 
247
  /* We currently only know how to handle alpha dynamic symbols.  */
248
  if (bfd_get_arch (abfd) != bfd_arch_alpha)
249
    return;
250
 
251
  /* Locate the dynamic symbols sections and read them in.  */
252
  memset ((char *) &si, 0, sizeof (si));
253
  bfd_map_over_sections (abfd, alphacoff_locate_sections, (void *) & si);
254
  if (si.sym_sect == NULL
255
      || si.str_sect == NULL
256
      || si.dyninfo_sect == NULL
257
      || si.got_sect == NULL)
258
    return;
259
 
260
  sym_secsize = bfd_get_section_size_before_reloc (si.sym_sect);
261
  str_secsize = bfd_get_section_size_before_reloc (si.str_sect);
262
  dyninfo_secsize = bfd_get_section_size_before_reloc (si.dyninfo_sect);
263
  got_secsize = bfd_get_section_size_before_reloc (si.got_sect);
264
  sym_secptr = xmalloc (sym_secsize);
265
  cleanups = make_cleanup (free, sym_secptr);
266
  str_secptr = xmalloc (str_secsize);
267
  make_cleanup (free, str_secptr);
268
  dyninfo_secptr = xmalloc (dyninfo_secsize);
269
  make_cleanup (free, dyninfo_secptr);
270
  got_secptr = xmalloc (got_secsize);
271
  make_cleanup (free, got_secptr);
272
 
273
  if (!bfd_get_section_contents (abfd, si.sym_sect, sym_secptr,
274
                                 (file_ptr) 0, sym_secsize))
275
    return;
276
  if (!bfd_get_section_contents (abfd, si.str_sect, str_secptr,
277
                                 (file_ptr) 0, str_secsize))
278
    return;
279
  if (!bfd_get_section_contents (abfd, si.dyninfo_sect, dyninfo_secptr,
280
                                 (file_ptr) 0, dyninfo_secsize))
281
    return;
282
  if (!bfd_get_section_contents (abfd, si.got_sect, got_secptr,
283
                                 (file_ptr) 0, got_secsize))
284
    return;
285
 
286
  /* Find the number of local GOT entries and the index for the
287
     the first dynamic symbol in the GOT. */
288
  for (dyninfo_p = dyninfo_secptr, dyninfo_end = dyninfo_p + dyninfo_secsize;
289
       dyninfo_p < dyninfo_end;
290
       dyninfo_p += sizeof (Elfalpha_External_Dyn))
291
    {
292
      Elfalpha_External_Dyn *x_dynp = (Elfalpha_External_Dyn *) dyninfo_p;
293
      long dyn_tag;
294
 
295
      dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_tag);
296
      if (dyn_tag == DT_NULL)
297
        break;
298
      else if (dyn_tag == DT_MIPS_LOCAL_GOTNO)
299
        {
300
          if (dt_mips_local_gotno < 0)
301
            dt_mips_local_gotno
302
              = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_un.d_val);
303
        }
304
      else if (dyn_tag == DT_MIPS_GOTSYM)
305
        {
306
          if (dt_mips_gotsym < 0)
307
            dt_mips_gotsym
308
              = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_un.d_val);
309
        }
310
    }
311
  if (dt_mips_local_gotno < 0 || dt_mips_gotsym < 0)
312
    return;
313
 
314
  /* Scan all dynamic symbols and enter them into the minimal symbol table
315
     if appropriate.  */
316
  sym_count = sym_secsize / sizeof (Elfalpha_External_Sym);
317
  stripped = (bfd_get_symcount (abfd) == 0);
318
 
319
  /* Skip first symbol, which is a null dummy.  */
320
  for (i = 1, x_symp = (Elfalpha_External_Sym *) sym_secptr + 1;
321
       i < sym_count;
322
       i++, x_symp++)
323
    {
324
      unsigned long strx;
325
      char *name;
326
      bfd_vma sym_value;
327
      unsigned char sym_info;
328
      unsigned int sym_shndx;
329
      int isglobal;
330
      enum minimal_symbol_type ms_type;
331
 
332
      strx = bfd_h_get_32 (abfd, (bfd_byte *) x_symp->st_name);
333
      if (strx >= str_secsize)
334
        continue;
335
      name = str_secptr + strx;
336
      if (*name == '\0' || *name == '.')
337
        continue;
338
 
339
      sym_value = bfd_h_get_64 (abfd, (bfd_byte *) x_symp->st_value);
340
      sym_info = bfd_h_get_8 (abfd, (bfd_byte *) x_symp->st_info);
341
      sym_shndx = bfd_h_get_16 (abfd, (bfd_byte *) x_symp->st_shndx);
342
      isglobal = (ELF_ST_BIND (sym_info) == STB_GLOBAL);
343
 
344
      if (sym_shndx == SHN_UNDEF)
345
        {
346
          /* Handle undefined functions which are defined in a shared
347
             library.  */
348
          if (ELF_ST_TYPE (sym_info) != STT_FUNC
349
              || ELF_ST_BIND (sym_info) != STB_GLOBAL)
350
            continue;
351
 
352
          ms_type = mst_solib_trampoline;
353
 
354
          /* If sym_value is nonzero, it points to the shared library
355
             trampoline entry, which is what we are looking for.
356
 
357
             If sym_value is zero, then we have to get the GOT entry
358
             for the symbol.
359
             If the GOT entry is nonzero, it represents the quickstart
360
             address of the function and we use that as the symbol value.
361
 
362
             If the GOT entry is zero, the function address has to be resolved
363
             by the runtime loader before the executable is started.
364
             We are unable to find any meaningful address for these
365
             functions in the executable file, so we skip them.  */
366
          if (sym_value == 0)
367
            {
368
              int got_entry_offset =
369
              (i - dt_mips_gotsym + dt_mips_local_gotno) * got_entry_size;
370
 
371
              if (got_entry_offset < 0 || got_entry_offset >= got_secsize)
372
                continue;
373
              sym_value =
374
                bfd_h_get_64 (abfd,
375
                              (bfd_byte *) (got_secptr + got_entry_offset));
376
              if (sym_value == 0)
377
                continue;
378
            }
379
        }
380
      else
381
        {
382
          /* Symbols defined in the executable itself. We only care about
383
             them if this is a stripped executable, otherwise they have
384
             been retrieved from the normal symbol table already.  */
385
          if (!stripped)
386
            continue;
387
 
388
          if (sym_shndx == SHN_MIPS_TEXT)
389
            {
390
              if (isglobal)
391
                ms_type = mst_text;
392
              else
393
                ms_type = mst_file_text;
394
              sym_value += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
395
            }
396
          else if (sym_shndx == SHN_MIPS_DATA)
397
            {
398
              if (isglobal)
399
                ms_type = mst_data;
400
              else
401
                ms_type = mst_file_data;
402
              sym_value += ANOFFSET (section_offsets, SECT_OFF_DATA (objfile));
403
            }
404
          else if (sym_shndx == SHN_MIPS_ACOMMON)
405
            {
406
              if (isglobal)
407
                ms_type = mst_bss;
408
              else
409
                ms_type = mst_file_bss;
410
              sym_value += ANOFFSET (section_offsets, SECT_OFF_BSS (objfile));
411
            }
412
          else if (sym_shndx == SHN_ABS)
413
            {
414
              ms_type = mst_abs;
415
            }
416
          else
417
            {
418
              continue;
419
            }
420
        }
421
 
422
      prim_record_minimal_symbol (name, sym_value, ms_type, objfile);
423
    }
424
 
425
  do_cleanups (cleanups);
426
}
427
 
428
/* Initialization */
429
 
430
static struct sym_fns ecoff_sym_fns =
431
{
432
  bfd_target_ecoff_flavour,
433
  mipscoff_new_init,            /* sym_new_init: init anything gbl to entire symtab */
434
  mipscoff_symfile_init,        /* sym_init: read initial info, setup for sym_read() */
435
  mipscoff_symfile_read,        /* sym_read: read a symbol file into symtab */
436
  mipscoff_symfile_finish,      /* sym_finish: finished with file, cleanup */
437
  default_symfile_offsets,      /* sym_offsets: dummy FIXME til implem sym reloc */
438
  NULL                          /* next: pointer to next struct sym_fns */
439
};
440
 
441
void
442
_initialize_mipsread (void)
443
{
444
  add_symtab_fns (&ecoff_sym_fns);
445
}

powered by: WebSVN 2.1.0

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