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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [binutils/] [rdcoff.c] - Blame information for rev 833

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

Line No. Rev Author Line
1 38 julius
/* stabs.c -- Parse COFF debugging information
2
   Copyright 1996, 1999, 2000, 2002, 2003, 2007
3
   Free Software Foundation, Inc.
4
   Written by Ian Lance Taylor <ian@cygnus.com>.
5
 
6
   This file is part of GNU Binutils.
7
 
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3 of the License, or
11
   (at your option) any later version.
12
 
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program; if not, write to the Free Software
20
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
21
   02110-1301, USA.  */
22
 
23
/* This file contains code which parses COFF debugging information.  */
24
 
25
#include "sysdep.h"
26
#include "bfd.h"
27
#include "coff/internal.h"
28
#include "libiberty.h"
29
#include "bucomm.h"
30
#include "debug.h"
31
#include "budbg.h"
32
 
33
/* FIXME: We should not need this BFD internal file.  We need it for
34
   the N_BTMASK, etc., values.  */
35
#include "libcoff.h"
36
 
37
/* These macros extract the right mask and shifts for this BFD.  They
38
   assume that there is a local variable named ABFD.  This is so that
39
   macros like ISFCN and DECREF, from coff/internal.h, will work
40
   without modification.  */
41
#define N_BTMASK (coff_data (abfd)->local_n_btmask)
42
#define N_BTSHFT (coff_data (abfd)->local_n_btshft)
43
#define N_TMASK  (coff_data (abfd)->local_n_tmask)
44
#define N_TSHIFT (coff_data (abfd)->local_n_tshift)
45
 
46
/* This structure is used to hold the symbols, as well as the current
47
   location within the symbols.  */
48
 
49
struct coff_symbols
50
{
51
  /* The symbols.  */
52
  asymbol **syms;
53
  /* The number of symbols.  */
54
  long symcount;
55
  /* The index of the current symbol.  */
56
  long symno;
57
  /* The index of the current symbol in the COFF symbol table (where
58
     each auxent counts as a symbol).  */
59
  long coff_symno;
60
};
61
 
62
/* The largest basic type we are prepared to handle.  */
63
 
64
#define T_MAX (T_LNGDBL)
65
 
66
/* This structure is used to hold slots.  */
67
 
68
struct coff_slots
69
{
70
  /* Next set of slots.  */
71
  struct coff_slots *next;
72
  /* Slots.  */
73
#define COFF_SLOTS (16)
74
  debug_type slots[COFF_SLOTS];
75
};
76
 
77
/* This structure is used to map symbol indices to types.  */
78
 
79
struct coff_types
80
{
81
  /* Slots.  */
82
  struct coff_slots *slots;
83
  /* Basic types.  */
84
  debug_type basic[T_MAX + 1];
85
};
86
 
87
static debug_type *coff_get_slot (struct coff_types *, int);
88
static debug_type parse_coff_type
89
  (bfd *, struct coff_symbols *, struct coff_types *, long, int,
90
   union internal_auxent *, bfd_boolean, void *);
91
static debug_type parse_coff_base_type
92
  (bfd *, struct coff_symbols *, struct coff_types *, long, int,
93
   union internal_auxent *, void *);
94
static debug_type parse_coff_struct_type
95
  (bfd *, struct coff_symbols *, struct coff_types *, int,
96
   union internal_auxent *, void *);
97
static debug_type parse_coff_enum_type
98
  (bfd *, struct coff_symbols *, struct coff_types *,
99
   union internal_auxent *, void *);
100
static bfd_boolean parse_coff_symbol
101
  (bfd *, struct coff_types *, asymbol *, long, struct internal_syment *,
102
   void *, debug_type, bfd_boolean);
103
static bfd_boolean external_coff_symbol_p (int sym_class);
104
 
105
/* Return the slot for a type.  */
106
 
107
static debug_type *
108
coff_get_slot (struct coff_types *types, int indx)
109
{
110
  struct coff_slots **pps;
111
 
112
  pps = &types->slots;
113
 
114
  while (indx >= COFF_SLOTS)
115
    {
116
      if (*pps == NULL)
117
        {
118
          *pps = (struct coff_slots *) xmalloc (sizeof **pps);
119
          memset (*pps, 0, sizeof **pps);
120
        }
121
      pps = &(*pps)->next;
122
      indx -= COFF_SLOTS;
123
    }
124
 
125
  if (*pps == NULL)
126
    {
127
      *pps = (struct coff_slots *) xmalloc (sizeof **pps);
128
      memset (*pps, 0, sizeof **pps);
129
    }
130
 
131
  return (*pps)->slots + indx;
132
}
133
 
134
/* Parse a COFF type code in NTYPE.  */
135
 
136
static debug_type
137
parse_coff_type (bfd *abfd, struct coff_symbols *symbols,
138
                 struct coff_types *types, long coff_symno, int ntype,
139
                 union internal_auxent *pauxent, bfd_boolean useaux,
140
                 void *dhandle)
141
{
142
  debug_type type;
143
 
144
  if ((ntype & ~N_BTMASK) != 0)
145
    {
146
      int newtype;
147
 
148
      newtype = DECREF (ntype);
149
 
150
      if (ISPTR (ntype))
151
        {
152
          type = parse_coff_type (abfd, symbols, types, coff_symno, newtype,
153
                                  pauxent, useaux, dhandle);
154
          type = debug_make_pointer_type (dhandle, type);
155
        }
156
      else if (ISFCN (ntype))
157
        {
158
          type = parse_coff_type (abfd, symbols, types, coff_symno, newtype,
159
                                  pauxent, useaux, dhandle);
160
          type = debug_make_function_type (dhandle, type, (debug_type *) NULL,
161
                                           FALSE);
162
        }
163
      else if (ISARY (ntype))
164
        {
165
          int n;
166
 
167
          if (pauxent == NULL)
168
            n = 0;
169
          else
170
            {
171
              unsigned short *dim;
172
              int i;
173
 
174
              /* FIXME: If pauxent->x_sym.x_tagndx.l == 0, gdb sets
175
                 the c_naux field of the syment to 0.  */
176
 
177
              /* Move the dimensions down, so that the next array
178
                 picks up the next one.  */
179
              dim = pauxent->x_sym.x_fcnary.x_ary.x_dimen;
180
              n = dim[0];
181
              for (i = 0; *dim != 0 && i < DIMNUM - 1; i++, dim++)
182
                *dim = *(dim + 1);
183
              *dim = 0;
184
            }
185
 
186
          type = parse_coff_type (abfd, symbols, types, coff_symno, newtype,
187
                                  pauxent, FALSE, dhandle);
188
          type = debug_make_array_type (dhandle, type,
189
                                        parse_coff_base_type (abfd, symbols,
190
                                                              types,
191
                                                              coff_symno,
192
                                                              T_INT,
193
                                                              NULL, dhandle),
194
                                        0, n - 1, FALSE);
195
        }
196
      else
197
        {
198
          non_fatal (_("parse_coff_type: Bad type code 0x%x"), ntype);
199
          return DEBUG_TYPE_NULL;
200
        }
201
 
202
      return type;
203
    }
204
 
205
  if (pauxent != NULL && pauxent->x_sym.x_tagndx.l > 0)
206
    {
207
      debug_type *slot;
208
 
209
      /* This is a reference to an existing type.  FIXME: gdb checks
210
         that the class is not C_STRTAG, nor C_UNTAG, nor C_ENTAG.  */
211
      slot = coff_get_slot (types, pauxent->x_sym.x_tagndx.l);
212
      if (*slot != DEBUG_TYPE_NULL)
213
        return *slot;
214
      else
215
        return debug_make_indirect_type (dhandle, slot, (const char *) NULL);
216
    }
217
 
218
  /* If the aux entry has already been used for something, useaux will
219
     have been set to false, indicating that parse_coff_base_type
220
     should not use it.  We need to do it this way, rather than simply
221
     passing pauxent as NULL, because we need to be able handle
222
     multiple array dimensions while still discarding pauxent after
223
     having handled all of them.  */
224
  if (! useaux)
225
    pauxent = NULL;
226
 
227
  return parse_coff_base_type (abfd, symbols, types, coff_symno, ntype,
228
                               pauxent, dhandle);
229
}
230
 
231
/* Parse a basic COFF type in NTYPE.  */
232
 
233
static debug_type
234
parse_coff_base_type (bfd *abfd, struct coff_symbols *symbols,
235
                      struct coff_types *types, long coff_symno, int ntype,
236
                      union internal_auxent *pauxent, void *dhandle)
237
{
238
  debug_type ret;
239
  bfd_boolean set_basic;
240
  const char *name;
241
  debug_type *slot;
242
 
243
  if (ntype >= 0
244
      && ntype <= T_MAX
245
      && types->basic[ntype] != DEBUG_TYPE_NULL)
246
    return types->basic[ntype];
247
 
248
  set_basic = TRUE;
249
  name = NULL;
250
 
251
  switch (ntype)
252
    {
253
    default:
254
      ret = debug_make_void_type (dhandle);
255
      break;
256
 
257
    case T_NULL:
258
    case T_VOID:
259
      ret = debug_make_void_type (dhandle);
260
      name = "void";
261
      break;
262
 
263
    case T_CHAR:
264
      ret = debug_make_int_type (dhandle, 1, FALSE);
265
      name = "char";
266
      break;
267
 
268
    case T_SHORT:
269
      ret = debug_make_int_type (dhandle, 2, FALSE);
270
      name = "short";
271
      break;
272
 
273
    case T_INT:
274
      /* FIXME: Perhaps the size should depend upon the architecture.  */
275
      ret = debug_make_int_type (dhandle, 4, FALSE);
276
      name = "int";
277
      break;
278
 
279
    case T_LONG:
280
      ret = debug_make_int_type (dhandle, 4, FALSE);
281
      name = "long";
282
      break;
283
 
284
    case T_FLOAT:
285
      ret = debug_make_float_type (dhandle, 4);
286
      name = "float";
287
      break;
288
 
289
    case T_DOUBLE:
290
      ret = debug_make_float_type (dhandle, 8);
291
      name = "double";
292
      break;
293
 
294
    case T_LNGDBL:
295
      ret = debug_make_float_type (dhandle, 12);
296
      name = "long double";
297
      break;
298
 
299
    case T_UCHAR:
300
      ret = debug_make_int_type (dhandle, 1, TRUE);
301
      name = "unsigned char";
302
      break;
303
 
304
    case T_USHORT:
305
      ret = debug_make_int_type (dhandle, 2, TRUE);
306
      name = "unsigned short";
307
      break;
308
 
309
    case T_UINT:
310
      ret = debug_make_int_type (dhandle, 4, TRUE);
311
      name = "unsigned int";
312
      break;
313
 
314
    case T_ULONG:
315
      ret = debug_make_int_type (dhandle, 4, TRUE);
316
      name = "unsigned long";
317
      break;
318
 
319
    case T_STRUCT:
320
      if (pauxent == NULL)
321
        ret = debug_make_struct_type (dhandle, TRUE, 0,
322
                                      (debug_field *) NULL);
323
      else
324
        ret = parse_coff_struct_type (abfd, symbols, types, ntype, pauxent,
325
                                      dhandle);
326
 
327
      slot = coff_get_slot (types, coff_symno);
328
      *slot = ret;
329
 
330
      set_basic = FALSE;
331
      break;
332
 
333
    case T_UNION:
334
      if (pauxent == NULL)
335
        ret = debug_make_struct_type (dhandle, FALSE, 0, (debug_field *) NULL);
336
      else
337
        ret = parse_coff_struct_type (abfd, symbols, types, ntype, pauxent,
338
                                      dhandle);
339
 
340
      slot = coff_get_slot (types, coff_symno);
341
      *slot = ret;
342
 
343
      set_basic = FALSE;
344
      break;
345
 
346
    case T_ENUM:
347
      if (pauxent == NULL)
348
        ret = debug_make_enum_type (dhandle, (const char **) NULL,
349
                                    (bfd_signed_vma *) NULL);
350
      else
351
        ret = parse_coff_enum_type (abfd, symbols, types, pauxent, dhandle);
352
 
353
      slot = coff_get_slot (types, coff_symno);
354
      *slot = ret;
355
 
356
      set_basic = FALSE;
357
      break;
358
    }
359
 
360
  if (name != NULL)
361
    ret = debug_name_type (dhandle, name, ret);
362
 
363
  if (set_basic
364
      && ntype >= 0
365
      && ntype <= T_MAX)
366
    types->basic[ntype] = ret;
367
 
368
  return ret;
369
}
370
 
371
/* Parse a struct type.  */
372
 
373
static debug_type
374
parse_coff_struct_type (bfd *abfd, struct coff_symbols *symbols,
375
                        struct coff_types *types, int ntype,
376
                        union internal_auxent *pauxent, void *dhandle)
377
{
378
  long symend;
379
  int alloc;
380
  debug_field *fields;
381
  int count;
382
  bfd_boolean done;
383
 
384
  symend = pauxent->x_sym.x_fcnary.x_fcn.x_endndx.l;
385
 
386
  alloc = 10;
387
  fields = (debug_field *) xmalloc (alloc * sizeof *fields);
388
  count = 0;
389
 
390
  done = FALSE;
391
  while (! done
392
         && symbols->coff_symno < symend
393
         && symbols->symno < symbols->symcount)
394
    {
395
      asymbol *sym;
396
      long this_coff_symno;
397
      struct internal_syment syment;
398
      union internal_auxent auxent;
399
      union internal_auxent *psubaux;
400
      bfd_vma bitpos = 0, bitsize = 0;
401
 
402
      sym = symbols->syms[symbols->symno];
403
 
404
      if (! bfd_coff_get_syment (abfd, sym, &syment))
405
        {
406
          non_fatal (_("bfd_coff_get_syment failed: %s"),
407
                     bfd_errmsg (bfd_get_error ()));
408
          return DEBUG_TYPE_NULL;
409
        }
410
 
411
      this_coff_symno = symbols->coff_symno;
412
 
413
      ++symbols->symno;
414
      symbols->coff_symno += 1 + syment.n_numaux;
415
 
416
      if (syment.n_numaux == 0)
417
        psubaux = NULL;
418
      else
419
        {
420
          if (! bfd_coff_get_auxent (abfd, sym, 0, &auxent))
421
            {
422
              non_fatal (_("bfd_coff_get_auxent failed: %s"),
423
                         bfd_errmsg (bfd_get_error ()));
424
              return DEBUG_TYPE_NULL;
425
            }
426
          psubaux = &auxent;
427
        }
428
 
429
      switch (syment.n_sclass)
430
        {
431
        case C_MOS:
432
        case C_MOU:
433
          bitpos = 8 * bfd_asymbol_value (sym);
434
          bitsize = 0;
435
          break;
436
 
437
        case C_FIELD:
438
          bitpos = bfd_asymbol_value (sym);
439
          bitsize = auxent.x_sym.x_misc.x_lnsz.x_size;
440
          break;
441
 
442
        case C_EOS:
443
          done = TRUE;
444
          break;
445
        }
446
 
447
      if (! done)
448
        {
449
          debug_type ftype;
450
          debug_field f;
451
 
452
          ftype = parse_coff_type (abfd, symbols, types, this_coff_symno,
453
                                   syment.n_type, psubaux, TRUE, dhandle);
454
          f = debug_make_field (dhandle, bfd_asymbol_name (sym), ftype,
455
                                bitpos, bitsize, DEBUG_VISIBILITY_PUBLIC);
456
          if (f == DEBUG_FIELD_NULL)
457
            return DEBUG_TYPE_NULL;
458
 
459
          if (count + 1 >= alloc)
460
            {
461
              alloc += 10;
462
              fields = ((debug_field *)
463
                        xrealloc (fields, alloc * sizeof *fields));
464
            }
465
 
466
          fields[count] = f;
467
          ++count;
468
        }
469
    }
470
 
471
  fields[count] = DEBUG_FIELD_NULL;
472
 
473
  return debug_make_struct_type (dhandle, ntype == T_STRUCT,
474
                                 pauxent->x_sym.x_misc.x_lnsz.x_size,
475
                                 fields);
476
}
477
 
478
/* Parse an enum type.  */
479
 
480
static debug_type
481
parse_coff_enum_type (bfd *abfd, struct coff_symbols *symbols,
482
                      struct coff_types *types ATTRIBUTE_UNUSED,
483
                      union internal_auxent *pauxent, void *dhandle)
484
{
485
  long symend;
486
  int alloc;
487
  const char **names;
488
  bfd_signed_vma *vals;
489
  int count;
490
  bfd_boolean done;
491
 
492
  symend = pauxent->x_sym.x_fcnary.x_fcn.x_endndx.l;
493
 
494
  alloc = 10;
495
  names = (const char **) xmalloc (alloc * sizeof *names);
496
  vals = (bfd_signed_vma *) xmalloc (alloc * sizeof *vals);
497
  count = 0;
498
 
499
  done = FALSE;
500
  while (! done
501
         && symbols->coff_symno < symend
502
         && symbols->symno < symbols->symcount)
503
    {
504
      asymbol *sym;
505
      struct internal_syment syment;
506
 
507
      sym = symbols->syms[symbols->symno];
508
 
509
      if (! bfd_coff_get_syment (abfd, sym, &syment))
510
        {
511
          non_fatal (_("bfd_coff_get_syment failed: %s"),
512
                     bfd_errmsg (bfd_get_error ()));
513
          return DEBUG_TYPE_NULL;
514
        }
515
 
516
      ++symbols->symno;
517
      symbols->coff_symno += 1 + syment.n_numaux;
518
 
519
      switch (syment.n_sclass)
520
        {
521
        case C_MOE:
522
          if (count + 1 >= alloc)
523
            {
524
              alloc += 10;
525
              names = ((const char **)
526
                       xrealloc (names, alloc * sizeof *names));
527
              vals = ((bfd_signed_vma *)
528
                      xrealloc (vals, alloc * sizeof *vals));
529
            }
530
 
531
          names[count] = bfd_asymbol_name (sym);
532
          vals[count] = bfd_asymbol_value (sym);
533
          ++count;
534
          break;
535
 
536
        case C_EOS:
537
          done = TRUE;
538
          break;
539
        }
540
    }
541
 
542
  names[count] = NULL;
543
 
544
  return debug_make_enum_type (dhandle, names, vals);
545
}
546
 
547
/* Handle a single COFF symbol.  */
548
 
549
static bfd_boolean
550
parse_coff_symbol (bfd *abfd ATTRIBUTE_UNUSED, struct coff_types *types,
551
                   asymbol *sym, long coff_symno,
552
                   struct internal_syment *psyment, void *dhandle,
553
                   debug_type type, bfd_boolean within_function)
554
{
555
  switch (psyment->n_sclass)
556
    {
557
    case C_NULL:
558
      break;
559
 
560
    case C_AUTO:
561
      if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
562
                                   DEBUG_LOCAL, bfd_asymbol_value (sym)))
563
        return FALSE;
564
      break;
565
 
566
    case C_WEAKEXT:
567
    case C_EXT:
568
      if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
569
                                   DEBUG_GLOBAL, bfd_asymbol_value (sym)))
570
        return FALSE;
571
      break;
572
 
573
    case C_STAT:
574
      if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
575
                                   (within_function
576
                                    ? DEBUG_LOCAL_STATIC
577
                                    : DEBUG_STATIC),
578
                                   bfd_asymbol_value (sym)))
579
        return FALSE;
580
      break;
581
 
582
    case C_REG:
583
      /* FIXME: We may need to convert the register number.  */
584
      if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
585
                                   DEBUG_REGISTER, bfd_asymbol_value (sym)))
586
        return FALSE;
587
      break;
588
 
589
    case C_LABEL:
590
      break;
591
 
592
    case C_ARG:
593
      if (! debug_record_parameter (dhandle, bfd_asymbol_name (sym), type,
594
                                    DEBUG_PARM_STACK, bfd_asymbol_value (sym)))
595
        return FALSE;
596
      break;
597
 
598
    case C_REGPARM:
599
      /* FIXME: We may need to convert the register number.  */
600
      if (! debug_record_parameter (dhandle, bfd_asymbol_name (sym), type,
601
                                    DEBUG_PARM_REG, bfd_asymbol_value (sym)))
602
        return FALSE;
603
      break;
604
 
605
    case C_TPDEF:
606
      type = debug_name_type (dhandle, bfd_asymbol_name (sym), type);
607
      if (type == DEBUG_TYPE_NULL)
608
        return FALSE;
609
      break;
610
 
611
    case C_STRTAG:
612
    case C_UNTAG:
613
    case C_ENTAG:
614
      {
615
        debug_type *slot;
616
 
617
        type = debug_tag_type (dhandle, bfd_asymbol_name (sym), type);
618
        if (type == DEBUG_TYPE_NULL)
619
          return FALSE;
620
 
621
        /* Store the named type into the slot, so that references get
622
           the name.  */
623
        slot = coff_get_slot (types, coff_symno);
624
        *slot = type;
625
      }
626
      break;
627
 
628
    default:
629
      break;
630
    }
631
 
632
  return TRUE;
633
}
634
 
635
/* Determine if a symbol has external visibility.  */
636
 
637
static bfd_boolean
638
external_coff_symbol_p (int sym_class)
639
{
640
  switch (sym_class)
641
    {
642
    case C_EXT:
643
    case C_WEAKEXT:
644
      return TRUE;
645
    default:
646
      break;
647
    }
648
  return FALSE;
649
}
650
 
651
/* This is the main routine.  It looks through all the symbols and
652
   handles them.  */
653
 
654
bfd_boolean
655
parse_coff (bfd *abfd, asymbol **syms, long symcount, void *dhandle)
656
{
657
  struct coff_symbols symbols;
658
  struct coff_types types;
659
  int i;
660
  long next_c_file;
661
  const char *fnname;
662
  int fnclass;
663
  int fntype;
664
  bfd_vma fnend;
665
  alent *linenos;
666
  bfd_boolean within_function;
667
  long this_coff_symno;
668
 
669
  symbols.syms = syms;
670
  symbols.symcount = symcount;
671
  symbols.symno = 0;
672
  symbols.coff_symno = 0;
673
 
674
  types.slots = NULL;
675
  for (i = 0; i <= T_MAX; i++)
676
    types.basic[i] = DEBUG_TYPE_NULL;
677
 
678
  next_c_file = -1;
679
  fnname = NULL;
680
  fnclass = 0;
681
  fntype = 0;
682
  fnend = 0;
683
  linenos = NULL;
684
  within_function = FALSE;
685
 
686
  while (symbols.symno < symcount)
687
    {
688
      asymbol *sym;
689
      const char *name;
690
      struct internal_syment syment;
691
      union internal_auxent auxent;
692
      union internal_auxent *paux;
693
      debug_type type;
694
 
695
      sym = syms[symbols.symno];
696
 
697
      if (! bfd_coff_get_syment (abfd, sym, &syment))
698
        {
699
          non_fatal (_("bfd_coff_get_syment failed: %s"),
700
                     bfd_errmsg (bfd_get_error ()));
701
          return FALSE;
702
        }
703
 
704
      name = bfd_asymbol_name (sym);
705
 
706
      this_coff_symno = symbols.coff_symno;
707
 
708
      ++symbols.symno;
709
      symbols.coff_symno += 1 + syment.n_numaux;
710
 
711
      /* We only worry about the first auxent, because that is the
712
         only one which is relevant for debugging information.  */
713
      if (syment.n_numaux == 0)
714
        paux = NULL;
715
      else
716
        {
717
          if (! bfd_coff_get_auxent (abfd, sym, 0, &auxent))
718
            {
719
              non_fatal (_("bfd_coff_get_auxent failed: %s"),
720
                         bfd_errmsg (bfd_get_error ()));
721
              return FALSE;
722
            }
723
          paux = &auxent;
724
        }
725
 
726
      if (this_coff_symno == next_c_file && syment.n_sclass != C_FILE)
727
        {
728
          /* The last C_FILE symbol points to the first external
729
             symbol.  */
730
          if (! debug_set_filename (dhandle, "*globals*"))
731
            return FALSE;
732
        }
733
 
734
      switch (syment.n_sclass)
735
        {
736
        case C_EFCN:
737
        case C_EXTDEF:
738
        case C_ULABEL:
739
        case C_USTATIC:
740
        case C_LINE:
741
        case C_ALIAS:
742
        case C_HIDDEN:
743
          /* Just ignore these classes.  */
744
          break;
745
 
746
        case C_FILE:
747
          next_c_file = syment.n_value;
748
          if (! debug_set_filename (dhandle, name))
749
            return FALSE;
750
          break;
751
 
752
        case C_STAT:
753
          /* Ignore static symbols with a type of T_NULL.  These
754
             represent section entries.  */
755
          if (syment.n_type == T_NULL)
756
            break;
757
          /* Fall through.  */
758
        case C_WEAKEXT:
759
        case C_EXT:
760
          if (ISFCN (syment.n_type))
761
            {
762
              fnname = name;
763
              fnclass = syment.n_sclass;
764
              fntype = syment.n_type;
765
              if (syment.n_numaux > 0)
766
                fnend = bfd_asymbol_value (sym) + auxent.x_sym.x_misc.x_fsize;
767
              else
768
                fnend = 0;
769
              linenos = BFD_SEND (abfd, _get_lineno, (abfd, sym));
770
              break;
771
            }
772
          type = parse_coff_type (abfd, &symbols, &types, this_coff_symno,
773
                                  syment.n_type, paux, TRUE, dhandle);
774
          if (type == DEBUG_TYPE_NULL)
775
            return FALSE;
776
          if (! parse_coff_symbol (abfd, &types, sym, this_coff_symno, &syment,
777
                                   dhandle, type, within_function))
778
            return FALSE;
779
          break;
780
 
781
        case C_FCN:
782
          if (strcmp (name, ".bf") == 0)
783
            {
784
              if (fnname == NULL)
785
                {
786
                  non_fatal (_("%ld: .bf without preceding function"),
787
                             this_coff_symno);
788
                  return FALSE;
789
                }
790
 
791
              type = parse_coff_type (abfd, &symbols, &types, this_coff_symno,
792
                                      DECREF (fntype), paux, FALSE, dhandle);
793
              if (type == DEBUG_TYPE_NULL)
794
                return FALSE;
795
 
796
              if (! debug_record_function (dhandle, fnname, type,
797
                                           external_coff_symbol_p (fnclass),
798
                                           bfd_asymbol_value (sym)))
799
                return FALSE;
800
 
801
              if (linenos != NULL)
802
                {
803
                  int base;
804
                  bfd_vma addr;
805
 
806
                  if (syment.n_numaux == 0)
807
                    base = 0;
808
                  else
809
                    base = auxent.x_sym.x_misc.x_lnsz.x_lnno - 1;
810
 
811
                  addr = bfd_get_section_vma (abfd, bfd_get_section (sym));
812
 
813
                  ++linenos;
814
 
815
                  while (linenos->line_number != 0)
816
                    {
817
                      if (! debug_record_line (dhandle,
818
                                               linenos->line_number + base,
819
                                               linenos->u.offset + addr))
820
                        return FALSE;
821
                      ++linenos;
822
                    }
823
                }
824
 
825
              fnname = NULL;
826
              linenos = NULL;
827
              fnclass = 0;
828
              fntype = 0;
829
 
830
              within_function = TRUE;
831
            }
832
          else if (strcmp (name, ".ef") == 0)
833
            {
834
              if (! within_function)
835
                {
836
                  non_fatal (_("%ld: unexpected .ef\n"), this_coff_symno);
837
                  return FALSE;
838
                }
839
 
840
              if (bfd_asymbol_value (sym) > fnend)
841
                fnend = bfd_asymbol_value (sym);
842
              if (! debug_end_function (dhandle, fnend))
843
                return FALSE;
844
 
845
              fnend = 0;
846
              within_function = FALSE;
847
            }
848
          break;
849
 
850
        case C_BLOCK:
851
          if (strcmp (name, ".bb") == 0)
852
            {
853
              if (! debug_start_block (dhandle, bfd_asymbol_value (sym)))
854
                return FALSE;
855
            }
856
          else if (strcmp (name, ".eb") == 0)
857
            {
858
              if (! debug_end_block (dhandle, bfd_asymbol_value (sym)))
859
                return FALSE;
860
            }
861
          break;
862
 
863
        default:
864
          type = parse_coff_type (abfd, &symbols, &types, this_coff_symno,
865
                                  syment.n_type, paux, TRUE, dhandle);
866
          if (type == DEBUG_TYPE_NULL)
867
            return FALSE;
868
          if (! parse_coff_symbol (abfd, &types, sym, this_coff_symno, &syment,
869
                                   dhandle, type, within_function))
870
            return FALSE;
871
          break;
872
        }
873
    }
874
 
875
  return TRUE;
876
}

powered by: WebSVN 2.1.0

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