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 143

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
      if (*name == '.')
391
        {
392
          /* Allow GCC cloned functions.  */
393
          if (strlen (name) > 7 && strncmp (name, ".clone.", 7) == 0)
394
            name += 6;
395
 
396
          /* Do not discard nested subprograms (those
397
             which end with .NNN, where N are digits).  */
398
          for (name++; *name; name++)
399
            if (! ISDIGIT (*name))
400
              return 0;
401
 
402
          break;
403
        }
404
    }
405
 
406
  /* On systems where the C compiler adds an underscore to all
407
     names, static names without underscores seem usually to be
408
     labels in hand written assembler in the library.  We don't want
409
     these names.  This is certainly necessary on a Sparc running
410
     SunOS 4.1 (try profiling a program that does a lot of
411
     division). I don't know whether it has harmful side effects on
412
     other systems.  Perhaps it should be made configurable.  */
413
  sym_prefix = bfd_get_symbol_leading_char (core_bfd);
414
 
415
  if ((sym_prefix && sym_prefix != sym->name[0])
416
      /* GCC may add special symbols to help gdb figure out the file
417
        language.  We want to ignore these, since sometimes they mask
418
        the real function.  (dj@ctron)  */
419
      || !strncmp (sym->name, "__gnu_compiled", 14)
420
      || !strncmp (sym->name, "___gnu_compiled", 15))
421
    {
422
      return 0;
423
    }
424
 
425
  /* If the object file supports marking of function symbols, then
426
     we can zap anything that doesn't have BSF_FUNCTION set.  */
427
  if (ignore_non_functions && (sym->flags & BSF_FUNCTION) == 0)
428
    return 0;
429
 
430
  return 't';                   /* It's a static text symbol.  */
431
}
432
 
433
/* Get whatever source info we can get regarding address ADDR.  */
434
 
435
static bfd_boolean
436
get_src_info (bfd_vma addr, const char **filename, const char **name, int *line_num)
437
{
438
  const char *fname = 0, *func_name = 0;
439
  int l = 0;
440
 
441
  if (bfd_find_nearest_line (core_bfd, core_text_sect, core_syms,
442
                             addr - core_text_sect->vma,
443
                             &fname, &func_name, (unsigned int *) &l)
444
      && fname && func_name && l)
445
    {
446
      DBG (AOUTDEBUG, printf ("[get_src_info] 0x%lx -> %s:%d (%s)\n",
447
                              (unsigned long) addr, fname, l, func_name));
448
      *filename = fname;
449
      *name = func_name;
450
      *line_num = l;
451
      return TRUE;
452
    }
453
  else
454
    {
455
      DBG (AOUTDEBUG, printf ("[get_src_info] no info for 0x%lx (%s:%d,%s)\n",
456
                              (unsigned long) addr,
457
                              fname ? fname : "<unknown>", l,
458
                              func_name ? func_name : "<unknown>"));
459
      return FALSE;
460
    }
461
}
462
 
463
/* Return number of symbols in a symbol-table file.  */
464
 
465
static int
466
num_of_syms_in (FILE * f)
467
{
468
  const int BUFSIZE = 1024;
469
  char * buf = (char *) xmalloc (BUFSIZE);
470
  char * address = (char *) xmalloc (BUFSIZE);
471
  char   type;
472
  char * name = (char *) xmalloc (BUFSIZE);
473
  int num = 0;
474
 
475
  while (!feof (f) && fgets (buf, BUFSIZE - 1, f))
476
    {
477
      if (sscanf (buf, "%s %c %s", address, &type, name) == 3)
478
        if (type == 't' || type == 'T')
479
          ++num;
480
    }
481
 
482
  free (buf);
483
  free (address);
484
  free (name);
485
 
486
  return num;
487
}
488
 
489
/* Read symbol table from a file.  */
490
 
491
void
492
core_create_syms_from (const char * sym_table_file)
493
{
494
  const int BUFSIZE = 1024;
495
  char * buf = (char *) xmalloc (BUFSIZE);
496
  char * address = (char *) xmalloc (BUFSIZE);
497
  char type;
498
  char * name = (char *) xmalloc (BUFSIZE);
499
  bfd_vma min_vma = ~(bfd_vma) 0;
500
  bfd_vma max_vma = 0;
501
  FILE * f;
502
 
503
  f = fopen (sym_table_file, "r");
504
  if (!f)
505
    {
506
      fprintf (stderr, _("%s: could not open %s.\n"), whoami, sym_table_file);
507
      done (1);
508
    }
509
 
510
  /* Pass 1 - determine upper bound on number of function names.  */
511
  symtab.len = num_of_syms_in (f);
512
 
513
  if (symtab.len == 0)
514
    {
515
      fprintf (stderr, _("%s: file `%s' has no symbols\n"), whoami, sym_table_file);
516
      done (1);
517
    }
518
 
519
  symtab.base = (Sym *) xmalloc (symtab.len * sizeof (Sym));
520
 
521
  /* Pass 2 - create symbols.  */
522
  symtab.limit = symtab.base;
523
 
524
  if (fseek (f, 0, SEEK_SET) != 0)
525
    {
526
      perror (sym_table_file);
527
      done (1);
528
    }
529
 
530
  while (!feof (f) && fgets (buf, BUFSIZE - 1, f))
531
    {
532
      if (sscanf (buf, "%s %c %s", address, &type, name) == 3)
533
        if (type != 't' && type != 'T')
534
          continue;
535
 
536
      sym_init (symtab.limit);
537
 
538
      sscanf (address, "%" BFD_VMA_FMT "x", &(symtab.limit->addr) );
539
 
540
      symtab.limit->name = (char *) xmalloc (strlen (name) + 1);
541
      strcpy ((char *) symtab.limit->name, name);
542
      symtab.limit->mapped = 0;
543
      symtab.limit->is_func = TRUE;
544
      symtab.limit->is_bb_head = TRUE;
545
      symtab.limit->is_static = (type == 't');
546
      min_vma = MIN (symtab.limit->addr, min_vma);
547
      max_vma = MAX (symtab.limit->addr, max_vma);
548
 
549
      ++symtab.limit;
550
    }
551
  fclose (f);
552
 
553
  symtab.len = symtab.limit - symtab.base;
554
  symtab_finalize (&symtab);
555
 
556
  free (buf);
557
  free (address);
558
  free (name);
559
}
560
 
561
static int
562
search_mapped_symbol (const void * l, const void * r)
563
{
564
    return strcmp ((const char *) l, ((const struct function_map *) r)->function_name);
565
}
566
 
567
/* Read in symbol table from core.
568
   One symbol per function is entered.  */
569
 
570
void
571
core_create_function_syms (void)
572
{
573
  bfd_vma min_vma = ~ (bfd_vma) 0;
574
  bfd_vma max_vma = 0;
575
  int cxxclass;
576
  long i;
577
  struct function_map * found;
578
  int core_has_func_syms = 0;
579
 
580
  switch (core_bfd->xvec->flavour)
581
    {
582
    default:
583
      break;
584
    case bfd_target_coff_flavour:
585
    case bfd_target_ecoff_flavour:
586
    case bfd_target_xcoff_flavour:
587
    case bfd_target_elf_flavour:
588
    case bfd_target_nlm_flavour:
589
    case bfd_target_som_flavour:
590
      core_has_func_syms = 1;
591
    }
592
 
593
  /* Pass 1 - determine upper bound on number of function names.  */
594
  symtab.len = 0;
595
 
596
  for (i = 0; i < core_num_syms; ++i)
597
    {
598
      if (!core_sym_class (core_syms[i]))
599
        continue;
600
 
601
      /* Don't create a symtab entry for a function that has
602
         a mapping to a file, unless it's the first function
603
         in the file.  */
604
      found = (struct function_map *) bsearch (core_syms[i]->name, symbol_map,
605
                                               symbol_map_count,
606
                                               sizeof (struct function_map),
607
                                               search_mapped_symbol);
608
      if (found == NULL || found->is_first)
609
        ++symtab.len;
610
    }
611
 
612
  if (symtab.len == 0)
613
    {
614
      fprintf (stderr, _("%s: file `%s' has no symbols\n"), whoami, a_out_name);
615
      done (1);
616
    }
617
 
618
  symtab.base = (Sym *) xmalloc (symtab.len * sizeof (Sym));
619
 
620
  /* Pass 2 - create symbols.  */
621
  symtab.limit = symtab.base;
622
 
623
  for (i = 0; i < core_num_syms; ++i)
624
    {
625
      asection *sym_sec;
626
 
627
      cxxclass = core_sym_class (core_syms[i]);
628
 
629
      if (!cxxclass)
630
        {
631
          DBG (AOUTDEBUG,
632
               printf ("[core_create_function_syms] rejecting: 0x%lx %s\n",
633
                       (unsigned long) core_syms[i]->value,
634
                       core_syms[i]->name));
635
          continue;
636
        }
637
 
638
      found = (struct function_map *) bsearch (core_syms[i]->name, symbol_map,
639
                                               symbol_map_count,
640
                       sizeof (struct function_map), search_mapped_symbol);
641
      if (found && ! found->is_first)
642
        continue;
643
 
644
      sym_init (symtab.limit);
645
 
646
      /* Symbol offsets are always section-relative.  */
647
      sym_sec = core_syms[i]->section;
648
      symtab.limit->addr = core_syms[i]->value;
649
      if (sym_sec)
650
        symtab.limit->addr += bfd_get_section_vma (sym_sec->owner, sym_sec);
651
 
652
      if (found)
653
        {
654
          symtab.limit->name = found->file_name;
655
          symtab.limit->mapped = 1;
656
        }
657
      else
658
        {
659
          symtab.limit->name = core_syms[i]->name;
660
          symtab.limit->mapped = 0;
661
        }
662
 
663
      /* Lookup filename and line number, if we can.  */
664
      {
665
        const char * filename;
666
        const char * func_name;
667
 
668
        if (get_src_info (symtab.limit->addr, & filename, & func_name,
669
                          & symtab.limit->line_num))
670
          {
671
            symtab.limit->file = source_file_lookup_path (filename);
672
 
673
            /* FIXME: Checking __osf__ here does not work with a cross
674
               gprof.  */
675
#ifdef __osf__
676
            /* Suppress symbols that are not function names.  This is
677
               useful to suppress code-labels and aliases.
678
 
679
               This is known to be useful under DEC's OSF/1.  Under SunOS 4.x,
680
               labels do not appear in the symbol table info, so this isn't
681
               necessary.  */
682
 
683
            if (strcmp (symtab.limit->name, func_name) != 0)
684
              {
685
                /* The symbol's address maps to a different name, so
686
                   it can't be a function-entry point.  This happens
687
                   for labels, for example.  */
688
                DBG (AOUTDEBUG,
689
                     printf ("[core_create_function_syms: rej %s (maps to %s)\n",
690
                             symtab.limit->name, func_name));
691
                continue;
692
              }
693
#endif
694
          }
695
      }
696
 
697
      symtab.limit->is_func = (!core_has_func_syms
698
                               || (core_syms[i]->flags & BSF_FUNCTION) != 0);
699
      symtab.limit->is_bb_head = TRUE;
700
 
701
      if (cxxclass == 't')
702
        symtab.limit->is_static = TRUE;
703
 
704
      /* Keep track of the minimum and maximum vma addresses used by all
705
         symbols.  When computing the max_vma, use the ending address of the
706
         section containing the symbol, if available.  */
707
      min_vma = MIN (symtab.limit->addr, min_vma);
708
      if (sym_sec)
709
        max_vma = MAX (bfd_get_section_vma (sym_sec->owner, sym_sec)
710
                       + bfd_section_size (sym_sec->owner, sym_sec) - 1,
711
                       max_vma);
712
      else
713
        max_vma = MAX (symtab.limit->addr, max_vma);
714
 
715
      DBG (AOUTDEBUG, printf ("[core_create_function_syms] %ld %s 0x%lx\n",
716
                              (long) (symtab.limit - symtab.base),
717
                              symtab.limit->name,
718
                              (unsigned long) symtab.limit->addr));
719
      ++symtab.limit;
720
    }
721
 
722
  symtab.len = symtab.limit - symtab.base;
723
  symtab_finalize (&symtab);
724
}
725
 
726
/* Read in symbol table from core.
727
   One symbol per line of source code is entered.  */
728
 
729
void
730
core_create_line_syms (void)
731
{
732
  char *prev_name, *prev_filename;
733
  unsigned int prev_name_len, prev_filename_len;
734
  bfd_vma vma, min_vma = ~(bfd_vma) 0, max_vma = 0;
735
  Sym *prev, dummy, *sym;
736
  const char *filename;
737
  int prev_line_num;
738
  Sym_Table ltab;
739
  bfd_vma vma_high;
740
 
741
  /* Create symbols for functions as usual.  This is necessary in
742
     cases where parts of a program were not compiled with -g.  For
743
     those parts we still want to get info at the function level.  */
744
  core_create_function_syms ();
745
 
746
  /* Pass 1: count the number of symbols.  */
747
 
748
  /* To find all line information, walk through all possible
749
     text-space addresses (one by one!) and get the debugging
750
     info for each address.  When the debugging info changes,
751
     it is time to create a new symbol.
752
 
753
     Of course, this is rather slow and it would be better if
754
     BFD would provide an iterator for enumerating all line infos.  */
755
  prev_name_len = PATH_MAX;
756
  prev_filename_len = PATH_MAX;
757
  prev_name = (char *) xmalloc (prev_name_len);
758
  prev_filename = (char *) xmalloc (prev_filename_len);
759
  ltab.len = 0;
760
  prev_line_num = 0;
761
 
762
  vma_high = core_text_sect->vma + bfd_get_section_size (core_text_sect);
763
  for (vma = core_text_sect->vma; vma < vma_high; vma += min_insn_size)
764
    {
765
      unsigned int len;
766
 
767
      if (!get_src_info (vma, &filename, &dummy.name, &dummy.line_num)
768
          || (prev_line_num == dummy.line_num
769
              && prev_name != NULL
770
              && strcmp (prev_name, dummy.name) == 0
771
              && filename_cmp (prev_filename, filename) == 0))
772
        continue;
773
 
774
      ++ltab.len;
775
      prev_line_num = dummy.line_num;
776
 
777
      len = strlen (dummy.name);
778
      if (len >= prev_name_len)
779
        {
780
          prev_name_len = len + 1024;
781
          free (prev_name);
782
          prev_name = (char *) xmalloc (prev_name_len);
783
        }
784
 
785
      strcpy (prev_name, dummy.name);
786
      len = strlen (filename);
787
 
788
      if (len >= prev_filename_len)
789
        {
790
          prev_filename_len = len + 1024;
791
          free (prev_filename);
792
          prev_filename = (char *) xmalloc (prev_filename_len);
793
        }
794
 
795
      strcpy (prev_filename, filename);
796
 
797
      min_vma = MIN (vma, min_vma);
798
      max_vma = MAX (vma, max_vma);
799
    }
800
 
801
  free (prev_name);
802
  free (prev_filename);
803
 
804
  /* Make room for function symbols, too.  */
805
  ltab.len += symtab.len;
806
  ltab.base = (Sym *) xmalloc (ltab.len * sizeof (Sym));
807
  ltab.limit = ltab.base;
808
 
809
  /* Pass 2 - create symbols.  */
810
 
811
  /* We now set is_static as we go along, rather than by running
812
     through the symbol table at the end.
813
 
814
     The old way called symtab_finalize before the is_static pass,
815
     causing a problem since symtab_finalize uses is_static as part of
816
     its address conflict resolution algorithm.  Since global symbols
817
     were prefered over static symbols, and all line symbols were
818
     global at that point, static function names that conflicted with
819
     their own line numbers (static, but labeled as global) were
820
     rejected in favor of the line num.
821
 
822
     This was not the desired functionality.  We always want to keep
823
     our function symbols and discard any conflicting line symbols.
824
     Perhaps symtab_finalize should be modified to make this
825
     distinction as well, but the current fix works and the code is a
826
     lot cleaner now.  */
827
  prev = 0;
828
 
829
  for (vma = core_text_sect->vma; vma < vma_high; vma += min_insn_size)
830
    {
831
      sym_init (ltab.limit);
832
 
833
      if (!get_src_info (vma, &filename, &ltab.limit->name, &ltab.limit->line_num)
834
          || (prev && prev->line_num == ltab.limit->line_num
835
              && strcmp (prev->name, ltab.limit->name) == 0
836
              && filename_cmp (prev->file->name, filename) == 0))
837
        continue;
838
 
839
      /* Make name pointer a malloc'ed string.  */
840
      ltab.limit->name = xstrdup (ltab.limit->name);
841
      ltab.limit->file = source_file_lookup_path (filename);
842
 
843
      ltab.limit->addr = vma;
844
 
845
      /* Set is_static based on the enclosing function, using either:
846
         1) the previous symbol, if it's from the same function, or
847
         2) a symtab lookup.  */
848
      if (prev && ltab.limit->file == prev->file &&
849
          strcmp (ltab.limit->name, prev->name) == 0)
850
        {
851
          ltab.limit->is_static = prev->is_static;
852
        }
853
      else
854
        {
855
          sym = sym_lookup(&symtab, ltab.limit->addr);
856
          if (sym)
857
            ltab.limit->is_static = sym->is_static;
858
        }
859
 
860
      prev = ltab.limit;
861
 
862
      DBG (AOUTDEBUG, printf ("[core_create_line_syms] %lu %s 0x%lx\n",
863
                              (unsigned long) (ltab.limit - ltab.base),
864
                              ltab.limit->name,
865
                              (unsigned long) ltab.limit->addr));
866
      ++ltab.limit;
867
    }
868
 
869
  /* Copy in function symbols.  */
870
  memcpy (ltab.limit, symtab.base, symtab.len * sizeof (Sym));
871
  ltab.limit += symtab.len;
872
 
873
  if ((unsigned int) (ltab.limit - ltab.base) != ltab.len)
874
    {
875
      fprintf (stderr,
876
               _("%s: somebody miscounted: ltab.len=%d instead of %ld\n"),
877
               whoami, ltab.len, (long) (ltab.limit - ltab.base));
878
      done (1);
879
    }
880
 
881
  /* Finalize ltab and make it symbol table.  */
882
  symtab_finalize (&ltab);
883
  free (symtab.base);
884
  symtab = ltab;
885
}

powered by: WebSVN 2.1.0

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