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

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [gdb/] [mipsread.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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