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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [mipsread.c] - Blame information for rev 1774

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

Line No. Rev Author Line
1 578 markom
/* 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
static void alphacoff_locate_sections (bfd *, asection *, PTR);
189
 
190
/* We are called once per section from read_alphacoff_dynamic_symtab.
191
   We need to examine each section we are passed, check to see
192
   if it is something we are interested in processing, and
193
   if so, stash away some access information for the section.  */
194
 
195
static void
196
alphacoff_locate_sections (bfd *ignore_abfd, asection *sectp, PTR sip)
197
{
198
  register struct alphacoff_dynsecinfo *si;
199
 
200
  si = (struct alphacoff_dynsecinfo *) sip;
201
 
202
  if (STREQ (sectp->name, ".dynsym"))
203
    {
204
      si->sym_sect = sectp;
205
    }
206
  else if (STREQ (sectp->name, ".dynstr"))
207
    {
208
      si->str_sect = sectp;
209
    }
210
  else if (STREQ (sectp->name, ".dynamic"))
211
    {
212
      si->dyninfo_sect = sectp;
213
    }
214
  else if (STREQ (sectp->name, ".got"))
215
    {
216
      si->got_sect = sectp;
217
    }
218
}
219
 
220
/* Scan an alpha dynamic symbol table for symbols of interest and
221
   add them to the minimal symbol table.  */
222
 
223
static void
224
read_alphacoff_dynamic_symtab (struct section_offsets *section_offsets,
225
                               struct objfile *objfile)
226
{
227
  bfd *abfd = objfile->obfd;
228
  struct alphacoff_dynsecinfo si;
229
  char *sym_secptr;
230
  char *str_secptr;
231
  char *dyninfo_secptr;
232
  char *got_secptr;
233
  bfd_size_type sym_secsize;
234
  bfd_size_type str_secsize;
235
  bfd_size_type dyninfo_secsize;
236
  bfd_size_type got_secsize;
237
  int sym_count;
238
  int i;
239
  int stripped;
240
  Elfalpha_External_Sym *x_symp;
241
  char *dyninfo_p;
242
  char *dyninfo_end;
243
  int got_entry_size = 8;
244
  int dt_mips_local_gotno = -1;
245
  int dt_mips_gotsym = -1;
246
  struct cleanup *cleanups;
247
 
248
 
249
  /* We currently only know how to handle alpha dynamic symbols.  */
250
  if (bfd_get_arch (abfd) != bfd_arch_alpha)
251
    return;
252
 
253
  /* Locate the dynamic symbols sections and read them in.  */
254
  memset ((char *) &si, 0, sizeof (si));
255
  bfd_map_over_sections (abfd, alphacoff_locate_sections, (PTR) & si);
256
  if (si.sym_sect == NULL
257
      || si.str_sect == NULL
258
      || si.dyninfo_sect == NULL
259
      || si.got_sect == NULL)
260
    return;
261
 
262
  sym_secsize = bfd_get_section_size_before_reloc (si.sym_sect);
263
  str_secsize = bfd_get_section_size_before_reloc (si.str_sect);
264
  dyninfo_secsize = bfd_get_section_size_before_reloc (si.dyninfo_sect);
265
  got_secsize = bfd_get_section_size_before_reloc (si.got_sect);
266
  sym_secptr = xmalloc (sym_secsize);
267
  cleanups = make_cleanup (free, sym_secptr);
268
  str_secptr = xmalloc (str_secsize);
269
  make_cleanup (free, str_secptr);
270
  dyninfo_secptr = xmalloc (dyninfo_secsize);
271
  make_cleanup (free, dyninfo_secptr);
272
  got_secptr = xmalloc (got_secsize);
273
  make_cleanup (free, got_secptr);
274
 
275
  if (!bfd_get_section_contents (abfd, si.sym_sect, sym_secptr,
276
                                 (file_ptr) 0, sym_secsize))
277
    return;
278
  if (!bfd_get_section_contents (abfd, si.str_sect, str_secptr,
279
                                 (file_ptr) 0, str_secsize))
280
    return;
281
  if (!bfd_get_section_contents (abfd, si.dyninfo_sect, dyninfo_secptr,
282
                                 (file_ptr) 0, dyninfo_secsize))
283
    return;
284
  if (!bfd_get_section_contents (abfd, si.got_sect, got_secptr,
285
                                 (file_ptr) 0, got_secsize))
286
    return;
287
 
288
  /* Find the number of local GOT entries and the index for the
289
     the first dynamic symbol in the GOT. */
290
  for (dyninfo_p = dyninfo_secptr, dyninfo_end = dyninfo_p + dyninfo_secsize;
291
       dyninfo_p < dyninfo_end;
292
       dyninfo_p += sizeof (Elfalpha_External_Dyn))
293
    {
294
      Elfalpha_External_Dyn *x_dynp = (Elfalpha_External_Dyn *) dyninfo_p;
295
      long dyn_tag;
296
 
297
      dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_tag);
298
      if (dyn_tag == DT_NULL)
299
        break;
300
      else if (dyn_tag == DT_MIPS_LOCAL_GOTNO)
301
        {
302
          if (dt_mips_local_gotno < 0)
303
            dt_mips_local_gotno
304
              = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_un.d_val);
305
        }
306
      else if (dyn_tag == DT_MIPS_GOTSYM)
307
        {
308
          if (dt_mips_gotsym < 0)
309
            dt_mips_gotsym
310
              = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_un.d_val);
311
        }
312
    }
313
  if (dt_mips_local_gotno < 0 || dt_mips_gotsym < 0)
314
    return;
315
 
316
  /* Scan all dynamic symbols and enter them into the minimal symbol table
317
     if appropriate.  */
318
  sym_count = sym_secsize / sizeof (Elfalpha_External_Sym);
319
  stripped = (bfd_get_symcount (abfd) == 0);
320
 
321
  /* Skip first symbol, which is a null dummy.  */
322
  for (i = 1, x_symp = (Elfalpha_External_Sym *) sym_secptr + 1;
323
       i < sym_count;
324
       i++, x_symp++)
325
    {
326
      unsigned long strx;
327
      char *name;
328
      bfd_vma sym_value;
329
      unsigned char sym_info;
330
      unsigned int sym_shndx;
331
      int isglobal;
332
      enum minimal_symbol_type ms_type;
333
 
334
      strx = bfd_h_get_32 (abfd, (bfd_byte *) x_symp->st_name);
335
      if (strx >= str_secsize)
336
        continue;
337
      name = str_secptr + strx;
338
      if (*name == '\0' || *name == '.')
339
        continue;
340
 
341
      sym_value = bfd_h_get_64 (abfd, (bfd_byte *) x_symp->st_value);
342
      sym_info = bfd_h_get_8 (abfd, (bfd_byte *) x_symp->st_info);
343
      sym_shndx = bfd_h_get_16 (abfd, (bfd_byte *) x_symp->st_shndx);
344
      isglobal = (ELF_ST_BIND (sym_info) == STB_GLOBAL);
345
 
346
      if (sym_shndx == SHN_UNDEF)
347
        {
348
          /* Handle undefined functions which are defined in a shared
349
             library.  */
350
          if (ELF_ST_TYPE (sym_info) != STT_FUNC
351
              || ELF_ST_BIND (sym_info) != STB_GLOBAL)
352
            continue;
353
 
354
          ms_type = mst_solib_trampoline;
355
 
356
          /* If sym_value is nonzero, it points to the shared library
357
             trampoline entry, which is what we are looking for.
358
 
359
             If sym_value is zero, then we have to get the GOT entry
360
             for the symbol.
361
             If the GOT entry is nonzero, it represents the quickstart
362
             address of the function and we use that as the symbol value.
363
 
364
             If the GOT entry is zero, the function address has to be resolved
365
             by the runtime loader before the executable is started.
366
             We are unable to find any meaningful address for these
367
             functions in the executable file, so we skip them.  */
368
          if (sym_value == 0)
369
            {
370
              int got_entry_offset =
371
              (i - dt_mips_gotsym + dt_mips_local_gotno) * got_entry_size;
372
 
373
              if (got_entry_offset < 0 || got_entry_offset >= got_secsize)
374
                continue;
375
              sym_value =
376
                bfd_h_get_64 (abfd,
377
                              (bfd_byte *) (got_secptr + got_entry_offset));
378
              if (sym_value == 0)
379
                continue;
380
            }
381
        }
382
      else
383
        {
384
          /* Symbols defined in the executable itself. We only care about
385
             them if this is a stripped executable, otherwise they have
386
             been retrieved from the normal symbol table already.  */
387
          if (!stripped)
388
            continue;
389
 
390
          if (sym_shndx == SHN_MIPS_TEXT)
391
            {
392
              if (isglobal)
393
                ms_type = mst_text;
394
              else
395
                ms_type = mst_file_text;
396
              sym_value += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
397
            }
398
          else if (sym_shndx == SHN_MIPS_DATA)
399
            {
400
              if (isglobal)
401
                ms_type = mst_data;
402
              else
403
                ms_type = mst_file_data;
404
              sym_value += ANOFFSET (section_offsets, SECT_OFF_DATA (objfile));
405
            }
406
          else if (sym_shndx == SHN_MIPS_ACOMMON)
407
            {
408
              if (isglobal)
409
                ms_type = mst_bss;
410
              else
411
                ms_type = mst_file_bss;
412
              sym_value += ANOFFSET (section_offsets, SECT_OFF_BSS (objfile));
413
            }
414
          else if (sym_shndx == SHN_ABS)
415
            {
416
              ms_type = mst_abs;
417
            }
418
          else
419
            {
420
              continue;
421
            }
422
        }
423
 
424
      prim_record_minimal_symbol (name, sym_value, ms_type, objfile);
425
    }
426
 
427
  do_cleanups (cleanups);
428
}
429
 
430
/* Initialization */
431
 
432
static struct sym_fns ecoff_sym_fns =
433
{
434
  bfd_target_ecoff_flavour,
435
  mipscoff_new_init,            /* sym_new_init: init anything gbl to entire symtab */
436
  mipscoff_symfile_init,        /* sym_init: read initial info, setup for sym_read() */
437
  mipscoff_symfile_read,        /* sym_read: read a symbol file into symtab */
438
  mipscoff_symfile_finish,      /* sym_finish: finished with file, cleanup */
439
  default_symfile_offsets,      /* sym_offsets: dummy FIXME til implem sym reloc */
440
  NULL                          /* next: pointer to next struct sym_fns */
441
};
442
 
443
void
444
_initialize_mipsread (void)
445
{
446
  add_symtab_fns (&ecoff_sym_fns);
447
}

powered by: WebSVN 2.1.0

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