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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gprof/] [corefile.c] - Blame information for rev 287

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

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

powered by: WebSVN 2.1.0

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