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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [gprof/] [corefile.c] - Blame information for rev 853

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

Line No. Rev Author Line
1 38 julius
/* corefile.c
2
 
3
   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
4
   Free Software Foundation, Inc.
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
#include "libiberty.h"
24
#include "gprof.h"
25
#include "search_list.h"
26
#include "source.h"
27
#include "symtab.h"
28
#include "hist.h"
29
#include "corefile.h"
30
#include "safe-ctype.h"
31
 
32
bfd *core_bfd;
33
static int core_num_syms;
34
static asymbol **core_syms;
35
asection *core_text_sect;
36
PTR core_text_space;
37
 
38
static int min_insn_size;
39
int offset_to_code;
40
 
41
/* For mapping symbols to specific .o files during file ordering.  */
42
struct function_map *symbol_map;
43
unsigned int symbol_map_count;
44
 
45
static void read_function_mappings (const char *);
46
static int core_sym_class (asymbol *);
47
static bfd_boolean get_src_info
48
  (bfd_vma, const char **, const char **, int *);
49
 
50
extern void i386_find_call  (Sym *, bfd_vma, bfd_vma);
51
extern void alpha_find_call (Sym *, bfd_vma, bfd_vma);
52
extern void vax_find_call   (Sym *, bfd_vma, bfd_vma);
53
extern void tahoe_find_call (Sym *, bfd_vma, bfd_vma);
54
extern void sparc_find_call (Sym *, bfd_vma, bfd_vma);
55
extern void mips_find_call  (Sym *, bfd_vma, bfd_vma);
56
 
57
static void
58
parse_error (const char *filename)
59
{
60
  fprintf (stderr, _("%s: unable to parse mapping file %s.\n"), whoami, filename);
61
  done (1);
62
}
63
 
64
static void
65
read_function_mappings (const char *filename)
66
{
67
  FILE *file = fopen (filename, "r");
68
  char dummy[1024];
69
  int count = 0;
70
 
71
  if (!file)
72
    {
73
      fprintf (stderr, _("%s: could not open %s.\n"), whoami, filename);
74
      done (1);
75
    }
76
 
77
  /* First parse the mapping file so we know how big we need to
78
     make our tables.  We also do some sanity checks at this
79
     time.  */
80
  while (!feof (file))
81
    {
82
      int matches;
83
 
84
      matches = fscanf (file, "%[^\n:]", dummy);
85
      if (!matches)
86
        parse_error (filename);
87
 
88
      /* Just skip messages about files with no symbols.  */
89
      if (!strncmp (dummy, "No symbols in ", 14))
90
        {
91
          matches = fscanf (file, "\n");
92
          if (matches == EOF)
93
            parse_error (filename);
94
          continue;
95
        }
96
 
97
      /* Don't care what else is on this line at this point.  */
98
      matches = fscanf (file, "%[^\n]\n", dummy);
99
      if (!matches)
100
        parse_error (filename);
101
      count++;
102
    }
103
 
104
  /* Now we know how big we need to make our table.  */
105
  symbol_map = ((struct function_map *)
106
                xmalloc (count * sizeof (struct function_map)));
107
 
108
  /* Rewind the input file so we can read it again.  */
109
  rewind (file);
110
 
111
  /* Read each entry and put it into the table.  */
112
  count = 0;
113
  while (!feof (file))
114
    {
115
      int matches;
116
      char *tmp;
117
 
118
      matches = fscanf (file, "%[^\n:]", dummy);
119
      if (!matches)
120
        parse_error (filename);
121
 
122
      /* Just skip messages about files with no symbols.  */
123
      if (!strncmp (dummy, "No symbols in ", 14))
124
        {
125
          matches = fscanf (file, "\n");
126
          if (matches == EOF)
127
            parse_error (filename);
128
          continue;
129
        }
130
 
131
      /* dummy has the filename, go ahead and copy it.  */
132
      symbol_map[count].file_name = xmalloc (strlen (dummy) + 1);
133
      strcpy (symbol_map[count].file_name, dummy);
134
 
135
      /* Now we need the function name.  */
136
      matches = fscanf (file, "%[^\n]\n", dummy);
137
      if (!matches)
138
        parse_error (filename);
139
      tmp = strrchr (dummy, ' ') + 1;
140
      symbol_map[count].function_name = xmalloc (strlen (tmp) + 1);
141
      strcpy (symbol_map[count].function_name, tmp);
142
      count++;
143
    }
144
 
145
  /* Record the size of the map table for future reference.  */
146
  symbol_map_count = count;
147
}
148
 
149
 
150
void
151
core_init (const char *aout_name)
152
{
153
  int core_sym_bytes;
154
  asymbol *synthsyms;
155
  long synth_count;
156
 
157
  core_bfd = bfd_openr (aout_name, 0);
158
 
159
  if (!core_bfd)
160
    {
161
      perror (aout_name);
162
      done (1);
163
    }
164
 
165
  if (!bfd_check_format (core_bfd, bfd_object))
166
    {
167
      fprintf (stderr, _("%s: %s: not in executable format\n"), whoami, aout_name);
168
      done (1);
169
    }
170
 
171
  /* Get core's text section.  */
172
  core_text_sect = bfd_get_section_by_name (core_bfd, ".text");
173
  if (!core_text_sect)
174
    {
175
      core_text_sect = bfd_get_section_by_name (core_bfd, "$CODE$");
176
      if (!core_text_sect)
177
        {
178
          fprintf (stderr, _("%s: can't find .text section in %s\n"),
179
                   whoami, aout_name);
180
          done (1);
181
        }
182
    }
183
 
184
  /* Read core's symbol table.  */
185
 
186
  /* This will probably give us more than we need, but that's ok.  */
187
  core_sym_bytes = bfd_get_symtab_upper_bound (core_bfd);
188
  if (core_sym_bytes < 0)
189
    {
190
      fprintf (stderr, "%s: %s: %s\n", whoami, aout_name,
191
               bfd_errmsg (bfd_get_error ()));
192
      done (1);
193
    }
194
 
195
  core_syms = (asymbol **) xmalloc (core_sym_bytes);
196
  core_num_syms = bfd_canonicalize_symtab (core_bfd, core_syms);
197
 
198
  if (core_num_syms < 0)
199
    {
200
      fprintf (stderr, "%s: %s: %s\n", whoami, aout_name,
201
               bfd_errmsg (bfd_get_error ()));
202
      done (1);
203
    }
204
 
205
  synth_count = bfd_get_synthetic_symtab (core_bfd, core_num_syms, core_syms,
206
                                          0, NULL, &synthsyms);
207
  if (synth_count > 0)
208
    {
209
      asymbol **symp;
210
      long new_size;
211
      long i;
212
 
213
      new_size = (core_num_syms + synth_count + 1) * sizeof (*core_syms);
214
      core_syms = xrealloc (core_syms, new_size);
215
      symp = core_syms + core_num_syms;
216
      core_num_syms += synth_count;
217
      for (i = 0; i < synth_count; i++)
218
        *symp++ = synthsyms + i;
219
      *symp = 0;
220
    }
221
 
222
  min_insn_size = 1;
223
  offset_to_code = 0;
224
 
225
  switch (bfd_get_arch (core_bfd))
226
    {
227
    case bfd_arch_vax:
228
    case bfd_arch_tahoe:
229
      offset_to_code = 2;
230
      break;
231
 
232
    case bfd_arch_alpha:
233
      min_insn_size = 4;
234
      break;
235
 
236
    default:
237
      break;
238
    }
239
 
240
  if (function_mapping_file)
241
    read_function_mappings (function_mapping_file);
242
}
243
 
244
/* Read in the text space of an a.out file.  */
245
 
246
void
247
core_get_text_space (bfd *cbfd)
248
{
249
  core_text_space = malloc (bfd_get_section_size (core_text_sect));
250
 
251
  if (!core_text_space)
252
    {
253
      fprintf (stderr, _("%s: ran out room for %lu bytes of text space\n"),
254
               whoami, (unsigned long) bfd_get_section_size (core_text_sect));
255
      done (1);
256
    }
257
 
258
  if (!bfd_get_section_contents (cbfd, core_text_sect, core_text_space,
259
                                 0, bfd_get_section_size (core_text_sect)))
260
    {
261
      bfd_perror ("bfd_get_section_contents");
262
      free (core_text_space);
263
      core_text_space = 0;
264
    }
265
 
266
  if (!core_text_space)
267
    fprintf (stderr, _("%s: can't do -c\n"), whoami);
268
}
269
 
270
 
271
void
272
find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
273
{
274
  if (core_text_space == 0)
275
    return;
276
 
277
  hist_clip_symbol_address (&p_lowpc, &p_highpc);
278
 
279
  switch (bfd_get_arch (core_bfd))
280
    {
281
    case bfd_arch_i386:
282
      i386_find_call (parent, p_lowpc, p_highpc);
283
      break;
284
 
285
    case bfd_arch_alpha:
286
      alpha_find_call (parent, p_lowpc, p_highpc);
287
      break;
288
 
289
    case bfd_arch_vax:
290
      vax_find_call (parent, p_lowpc, p_highpc);
291
      break;
292
 
293
    case bfd_arch_sparc:
294
      sparc_find_call (parent, p_lowpc, p_highpc);
295
      break;
296
 
297
    case bfd_arch_tahoe:
298
      tahoe_find_call (parent, p_lowpc, p_highpc);
299
      break;
300
 
301
    case bfd_arch_mips:
302
      mips_find_call (parent, p_lowpc, p_highpc);
303
      break;
304
 
305
    default:
306
      fprintf (stderr, _("%s: -c not supported on architecture %s\n"),
307
               whoami, bfd_printable_name(core_bfd));
308
 
309
      /* Don't give the error more than once.  */
310
      ignore_direct_calls = FALSE;
311
    }
312
}
313
 
314
/* Return class of symbol SYM.  The returned class can be any of:
315
 
316
        'T' -> symbol is a global name
317
        't' -> symbol is a local (static) name.  */
318
 
319
static int
320
core_sym_class (asymbol *sym)
321
{
322
  symbol_info syminfo;
323
  const char *name;
324
  char sym_prefix;
325
  int i;
326
 
327
  if (sym->section == NULL || (sym->flags & BSF_DEBUGGING) != 0)
328
    return 0;
329
 
330
  /* Must be a text symbol, and static text symbols
331
     don't qualify if ignore_static_funcs set.   */
332
  if (ignore_static_funcs && (sym->flags & BSF_LOCAL))
333
    {
334
      DBG (AOUTDEBUG, printf ("[core_sym_class] %s: not a function\n",
335
                              sym->name));
336
      return 0;
337
    }
338
 
339
  bfd_get_symbol_info (core_bfd, sym, &syminfo);
340
  i = syminfo.type;
341
 
342
  if (i == 'T')
343
    return i;                   /* It's a global symbol.  */
344
 
345
  if (i == 'W')
346
    /* Treat weak symbols as text symbols.  FIXME: a weak symbol may
347
       also be a data symbol.  */
348
    return 'T';
349
 
350
  if (i != 't')
351
    {
352
      /* Not a static text symbol.  */
353
      DBG (AOUTDEBUG, printf ("[core_sym_class] %s is of class %c\n",
354
                              sym->name, i));
355
      return 0;
356
    }
357
 
358
  /* Do some more filtering on static function-names.  */
359
  if (ignore_static_funcs)
360
    return 0;
361
 
362
  /* Can't zero-length name or funny characters in name, where
363
     `funny' includes: `.' (.o file names) and `$' (Pascal labels).  */
364
  if (!sym->name || sym->name[0] == '\0')
365
    return 0;
366
 
367
  for (name = sym->name; *name; ++name)
368
    {
369
      if (*name == '$')
370
        return 0;
371
 
372
      /* Do not discard nested subprograms (those
373
         which end with .NNN, where N are digits).  */
374
      if (*name == '.')
375
        for (name++; *name; name++)
376
          if (! ISDIGIT (*name))
377
            return 0;
378
    }
379
 
380
  /* On systems where the C compiler adds an underscore to all
381
     names, static names without underscores seem usually to be
382
     labels in hand written assembler in the library.  We don't want
383
     these names.  This is certainly necessary on a Sparc running
384
     SunOS 4.1 (try profiling a program that does a lot of
385
     division). I don't know whether it has harmful side effects on
386
     other systems.  Perhaps it should be made configurable.  */
387
  sym_prefix = bfd_get_symbol_leading_char (core_bfd);
388
 
389
  if ((sym_prefix && sym_prefix != sym->name[0])
390
      /* GCC may add special symbols to help gdb figure out the file
391
        language.  We want to ignore these, since sometimes they mask
392
        the real function.  (dj@ctron)  */
393
      || !strncmp (sym->name, "__gnu_compiled", 14)
394
      || !strncmp (sym->name, "___gnu_compiled", 15))
395
    {
396
      return 0;
397
    }
398
 
399
  /* If the object file supports marking of function symbols, then
400
     we can zap anything that doesn't have BSF_FUNCTION set.  */
401
  if (ignore_non_functions && (sym->flags & BSF_FUNCTION) == 0)
402
    return 0;
403
 
404
  return 't';                   /* It's a static text symbol.  */
405
}
406
 
407
/* Get whatever source info we can get regarding address ADDR.  */
408
 
409
static bfd_boolean
410
get_src_info (bfd_vma addr, const char **filename, const char **name, int *line_num)
411
{
412
  const char *fname = 0, *func_name = 0;
413
  int l = 0;
414
 
415
  if (bfd_find_nearest_line (core_bfd, core_text_sect, core_syms,
416
                             addr - core_text_sect->vma,
417
                             &fname, &func_name, (unsigned int *) &l)
418
      && fname && func_name && l)
419
    {
420
      DBG (AOUTDEBUG, printf ("[get_src_info] 0x%lx -> %s:%d (%s)\n",
421
                              (unsigned long) addr, fname, l, func_name));
422
      *filename = fname;
423
      *name = func_name;
424
      *line_num = l;
425
      return TRUE;
426
    }
427
  else
428
    {
429
      DBG (AOUTDEBUG, printf ("[get_src_info] no info for 0x%lx (%s:%d,%s)\n",
430
                              (long) addr, fname ? fname : "<unknown>", l,
431
                              func_name ? func_name : "<unknown>"));
432
      return FALSE;
433
    }
434
}
435
 
436
/* Read in symbol table from core.
437
   One symbol per function is entered.  */
438
 
439
void
440
core_create_function_syms ()
441
{
442
  bfd_vma min_vma = ~(bfd_vma) 0;
443
  bfd_vma max_vma = 0;
444
  int class;
445
  long i, found, skip;
446
  unsigned int j;
447
 
448
  /* Pass 1 - determine upper bound on number of function names.  */
449
  symtab.len = 0;
450
 
451
  for (i = 0; i < core_num_syms; ++i)
452
    {
453
      if (!core_sym_class (core_syms[i]))
454
        continue;
455
 
456
      /* This should be replaced with a binary search or hashed
457
         search.  Gross.
458
 
459
         Don't create a symtab entry for a function that has
460
         a mapping to a file, unless it's the first function
461
         in the file.  */
462
      skip = 0;
463
      for (j = 0; j < symbol_map_count; j++)
464
        if (!strcmp (core_syms[i]->name, symbol_map[j].function_name))
465
          {
466
            if (j > 0 && ! strcmp (symbol_map [j].file_name,
467
                                   symbol_map [j - 1].file_name))
468
              skip = 1;
469
            break;
470
          }
471
 
472
      if (!skip)
473
        ++symtab.len;
474
    }
475
 
476
  if (symtab.len == 0)
477
    {
478
      fprintf (stderr, _("%s: file `%s' has no symbols\n"), whoami, a_out_name);
479
      done (1);
480
    }
481
 
482
  /* The "+ 2" is for the sentinels.  */
483
  symtab.base = (Sym *) xmalloc ((symtab.len + 2) * sizeof (Sym));
484
 
485
  /* Pass 2 - create symbols.  */
486
  symtab.limit = symtab.base;
487
 
488
  for (i = 0; i < core_num_syms; ++i)
489
    {
490
      asection *sym_sec;
491
 
492
      class = core_sym_class (core_syms[i]);
493
 
494
      if (!class)
495
        {
496
          DBG (AOUTDEBUG,
497
               printf ("[core_create_function_syms] rejecting: 0x%lx %s\n",
498
                       (unsigned long) core_syms[i]->value,
499
                       core_syms[i]->name));
500
          continue;
501
        }
502
 
503
      /* This should be replaced with a binary search or hashed
504
         search.  Gross.   */
505
      skip = 0;
506
      found = 0;
507
 
508
      for (j = 0; j < symbol_map_count; j++)
509
        if (!strcmp (core_syms[i]->name, symbol_map[j].function_name))
510
          {
511
            if (j > 0 && ! strcmp (symbol_map [j].file_name,
512
                                   symbol_map [j - 1].file_name))
513
              skip = 1;
514
            else
515
              found = j;
516
            break;
517
          }
518
 
519
      if (skip)
520
        continue;
521
 
522
      sym_init (symtab.limit);
523
 
524
      /* Symbol offsets are always section-relative.  */
525
      sym_sec = core_syms[i]->section;
526
      symtab.limit->addr = core_syms[i]->value;
527
      if (sym_sec)
528
        symtab.limit->addr += bfd_get_section_vma (sym_sec->owner, sym_sec);
529
 
530
      if (symbol_map_count
531
          && !strcmp (core_syms[i]->name, symbol_map[found].function_name))
532
        {
533
          symtab.limit->name = symbol_map[found].file_name;
534
          symtab.limit->mapped = 1;
535
        }
536
      else
537
        {
538
          symtab.limit->name = core_syms[i]->name;
539
          symtab.limit->mapped = 0;
540
        }
541
 
542
      /* Lookup filename and line number, if we can.  */
543
      {
544
        const char *filename, *func_name;
545
 
546
        if (get_src_info (symtab.limit->addr, &filename, &func_name,
547
                          &symtab.limit->line_num))
548
          {
549
            symtab.limit->file = source_file_lookup_path (filename);
550
 
551
            /* FIXME: Checking __osf__ here does not work with a cross
552
               gprof.  */
553
#ifdef __osf__
554
            /* Suppress symbols that are not function names.  This is
555
               useful to suppress code-labels and aliases.
556
 
557
               This is known to be useful under DEC's OSF/1.  Under SunOS 4.x,
558
               labels do not appear in the symbol table info, so this isn't
559
               necessary.  */
560
 
561
            if (strcmp (symtab.limit->name, func_name) != 0)
562
              {
563
                /* The symbol's address maps to a different name, so
564
                   it can't be a function-entry point.  This happens
565
                   for labels, for example.  */
566
                DBG (AOUTDEBUG,
567
                     printf ("[core_create_function_syms: rej %s (maps to %s)\n",
568
                             symtab.limit->name, func_name));
569
                continue;
570
              }
571
#endif
572
          }
573
      }
574
 
575
      symtab.limit->is_func = TRUE;
576
      symtab.limit->is_bb_head = TRUE;
577
 
578
      if (class == 't')
579
        symtab.limit->is_static = TRUE;
580
 
581
      /* Keep track of the minimum and maximum vma addresses used by all
582
         symbols.  When computing the max_vma, use the ending address of the
583
         section containing the symbol, if available.  */
584
      min_vma = MIN (symtab.limit->addr, min_vma);
585
      if (sym_sec)
586
        max_vma = MAX (bfd_get_section_vma (sym_sec->owner, sym_sec)
587
                       + bfd_section_size (sym_sec->owner, sym_sec) - 1,
588
                       max_vma);
589
      else
590
        max_vma = MAX (symtab.limit->addr, max_vma);
591
 
592
      DBG (AOUTDEBUG, printf ("[core_create_function_syms] %ld %s 0x%lx\n",
593
                              (long) (symtab.limit - symtab.base),
594
                              symtab.limit->name,
595
                              (unsigned long) symtab.limit->addr));
596
      ++symtab.limit;
597
    }
598
 
599
  /* Create sentinels.  */
600
  sym_init (symtab.limit);
601
  symtab.limit->name = "<locore>";
602
  symtab.limit->addr = 0;
603
  symtab.limit->end_addr = min_vma - 1;
604
  ++symtab.limit;
605
 
606
  sym_init (symtab.limit);
607
  symtab.limit->name = "<hicore>";
608
  symtab.limit->addr = max_vma + 1;
609
  symtab.limit->end_addr = ~(bfd_vma) 0;
610
  ++symtab.limit;
611
 
612
  symtab.len = symtab.limit - symtab.base;
613
  symtab_finalize (&symtab);
614
}
615
 
616
/* Read in symbol table from core.
617
   One symbol per line of source code is entered.  */
618
 
619
void
620
core_create_line_syms ()
621
{
622
  char *prev_name, *prev_filename;
623
  unsigned int prev_name_len, prev_filename_len;
624
  bfd_vma vma, min_vma = ~(bfd_vma) 0, max_vma = 0;
625
  Sym *prev, dummy, *sentinel, *sym;
626
  const char *filename;
627
  int prev_line_num;
628
  Sym_Table ltab;
629
  bfd_vma vma_high;
630
 
631
  /* Create symbols for functions as usual.  This is necessary in
632
     cases where parts of a program were not compiled with -g.  For
633
     those parts we still want to get info at the function level.  */
634
  core_create_function_syms ();
635
 
636
  /* Pass 1: count the number of symbols.  */
637
 
638
  /* To find all line information, walk through all possible
639
     text-space addresses (one by one!) and get the debugging
640
     info for each address.  When the debugging info changes,
641
     it is time to create a new symbol.
642
 
643
     Of course, this is rather slow and it would be better if
644
     BFD would provide an iterator for enumerating all line infos.  */
645
  prev_name_len = PATH_MAX;
646
  prev_filename_len = PATH_MAX;
647
  prev_name = xmalloc (prev_name_len);
648
  prev_filename = xmalloc (prev_filename_len);
649
  ltab.len = 0;
650
  prev_line_num = 0;
651
 
652
  vma_high = core_text_sect->vma + bfd_get_section_size (core_text_sect);
653
  for (vma = core_text_sect->vma; vma < vma_high; vma += min_insn_size)
654
    {
655
      unsigned int len;
656
 
657
      if (!get_src_info (vma, &filename, &dummy.name, &dummy.line_num)
658
          || (prev_line_num == dummy.line_num
659
              && prev_name != NULL
660
              && strcmp (prev_name, dummy.name) == 0
661
              && strcmp (prev_filename, filename) == 0))
662
        continue;
663
 
664
      ++ltab.len;
665
      prev_line_num = dummy.line_num;
666
 
667
      len = strlen (dummy.name);
668
      if (len >= prev_name_len)
669
        {
670
          prev_name_len = len + 1024;
671
          free (prev_name);
672
          prev_name = xmalloc (prev_name_len);
673
        }
674
 
675
      strcpy (prev_name, dummy.name);
676
      len = strlen (filename);
677
 
678
      if (len >= prev_filename_len)
679
        {
680
          prev_filename_len = len + 1024;
681
          free (prev_filename);
682
          prev_filename = xmalloc (prev_filename_len);
683
        }
684
 
685
      strcpy (prev_filename, filename);
686
 
687
      min_vma = MIN (vma, min_vma);
688
      max_vma = MAX (vma, max_vma);
689
    }
690
 
691
  free (prev_name);
692
  free (prev_filename);
693
 
694
  /* Make room for function symbols, too.  */
695
  ltab.len += symtab.len;
696
  ltab.base = (Sym *) xmalloc (ltab.len * sizeof (Sym));
697
  ltab.limit = ltab.base;
698
 
699
  /* Pass 2 - create symbols.  */
700
 
701
  /* We now set is_static as we go along, rather than by running
702
     through the symbol table at the end.
703
 
704
     The old way called symtab_finalize before the is_static pass,
705
     causing a problem since symtab_finalize uses is_static as part of
706
     its address conflict resolution algorithm.  Since global symbols
707
     were prefered over static symbols, and all line symbols were
708
     global at that point, static function names that conflicted with
709
     their own line numbers (static, but labeled as global) were
710
     rejected in favor of the line num.
711
 
712
     This was not the desired functionality.  We always want to keep
713
     our function symbols and discard any conflicting line symbols.
714
     Perhaps symtab_finalize should be modified to make this
715
     distinction as well, but the current fix works and the code is a
716
     lot cleaner now.  */
717
  prev = 0;
718
 
719
  for (vma = core_text_sect->vma; vma < vma_high; vma += min_insn_size)
720
    {
721
      sym_init (ltab.limit);
722
 
723
      if (!get_src_info (vma, &filename, &ltab.limit->name, &ltab.limit->line_num)
724
          || (prev && prev->line_num == ltab.limit->line_num
725
              && strcmp (prev->name, ltab.limit->name) == 0
726
              && strcmp (prev->file->name, filename) == 0))
727
        continue;
728
 
729
      /* Make name pointer a malloc'ed string.  */
730
      ltab.limit->name = xstrdup (ltab.limit->name);
731
      ltab.limit->file = source_file_lookup_path (filename);
732
 
733
      ltab.limit->addr = vma;
734
 
735
      /* Set is_static based on the enclosing function, using either:
736
         1) the previous symbol, if it's from the same function, or
737
         2) a symtab lookup.  */
738
      if (prev && ltab.limit->file == prev->file &&
739
          strcmp (ltab.limit->name, prev->name) == 0)
740
        {
741
          ltab.limit->is_static = prev->is_static;
742
        }
743
      else
744
        {
745
          sym = sym_lookup(&symtab, ltab.limit->addr);
746
          ltab.limit->is_static = sym->is_static;
747
        }
748
 
749
      prev = ltab.limit;
750
 
751
      DBG (AOUTDEBUG, printf ("[core_create_line_syms] %lu %s 0x%lx\n",
752
                              (unsigned long) (ltab.limit - ltab.base),
753
                              ltab.limit->name,
754
                              (unsigned long) ltab.limit->addr));
755
      ++ltab.limit;
756
    }
757
 
758
  /* Update sentinels.  */
759
  sentinel = sym_lookup (&symtab, (bfd_vma) 0);
760
 
761
  if (sentinel
762
      && strcmp (sentinel->name, "<locore>") == 0
763
      && min_vma <= sentinel->end_addr)
764
    sentinel->end_addr = min_vma - 1;
765
 
766
  sentinel = sym_lookup (&symtab, ~(bfd_vma) 0);
767
 
768
  if (sentinel
769
      && strcmp (sentinel->name, "<hicore>") == 0
770
      && max_vma >= sentinel->addr)
771
    sentinel->addr = max_vma + 1;
772
 
773
  /* Copy in function symbols.  */
774
  memcpy (ltab.limit, symtab.base, symtab.len * sizeof (Sym));
775
  ltab.limit += symtab.len;
776
 
777
  if ((unsigned int) (ltab.limit - ltab.base) != ltab.len)
778
    {
779
      fprintf (stderr,
780
               _("%s: somebody miscounted: ltab.len=%d instead of %ld\n"),
781
               whoami, ltab.len, (long) (ltab.limit - ltab.base));
782
      done (1);
783
    }
784
 
785
  /* Finalize ltab and make it symbol table.  */
786
  symtab_finalize (&ltab);
787
  free (symtab.base);
788
  symtab = ltab;
789
}

powered by: WebSVN 2.1.0

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