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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [gprof/] [corefile.c] - Blame information for rev 298

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

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

powered by: WebSVN 2.1.0

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