Tue Feb 3 14:25:25 1998 Brent Baccala <baccala@freesoft.org>
[deliverable/binutils-gdb.git] / gprof / call_graph.c
CommitLineData
5489fcc3
KR
1#include "cg_arcs.h"
2#include "call_graph.h"
3#include "core.h"
4#include "gmon_io.h"
5#include "gmon_out.h"
6#include "symtab.h"
7#include "sym_ids.h"
8
9extern void
12516a37
KR
10DEFUN (cg_tally, (from_pc, self_pc, count),
11 bfd_vma from_pc AND bfd_vma self_pc AND int count)
5489fcc3 12{
12516a37
KR
13 Sym *parent;
14 Sym *child;
5489fcc3 15
12516a37
KR
16 parent = sym_lookup (&symtab, from_pc);
17 child = sym_lookup (&symtab, self_pc);
5489fcc3 18
7862d7d0
ILT
19 if (child == NULL || parent == NULL)
20 return;
21
22 /* If we're doing line-by-line profiling, both the parent and the
23 child will probably point to line symbols instead of function
24 symbols. For the parent this is fine, since this identifies the
25 line number in the calling routing, but the child should always
26 point to a function entry point, so we back up in the symbol
27 table until we find it.
28
29 For normal profiling, is_func will be set on all symbols, so this
30 code will do nothing. */
31
32 while (child >= symtab.base && ! child->is_func)
33 --child;
34
35 if (child < symtab.base)
36 return;
37
12516a37
KR
38 /*
39 * Keep arc if it is on INCL_ARCS table or if the INCL_ARCS table
40 * is empty and it is not in the EXCL_ARCS table.
41 */
42 if (sym_id_arc_is_present (&syms[INCL_ARCS], parent, child)
43 || (syms[INCL_ARCS].len == 0
44 && !sym_id_arc_is_present (&syms[EXCL_ARCS], parent, child)))
5489fcc3 45 {
12516a37
KR
46 child->ncalls += count;
47 DBG (TALLYDEBUG,
48 printf ("[cg_tally] arc from %s to %s traversed %d times\n",
5489fcc3 49 parent->name, child->name, count));
12516a37 50 arc_add (parent, child, count);
03c35bcb
KR
51 }
52}
5489fcc3
KR
53
54
55/*
56 * Read a record from file IFP describing an arc in the function
57 * call-graph and the count of how many times the arc has been
58 * traversed. FILENAME is the name of file IFP and is provided
59 * for formatting error-messages only.
60 */
61void
12516a37 62DEFUN (cg_read_rec, (ifp, filename), FILE * ifp AND CONST char *filename)
5489fcc3 63{
12516a37
KR
64 bfd_vma from_pc, self_pc;
65 struct gmon_cg_arc_record arc;
66 int count;
5489fcc3 67
12516a37
KR
68 if (fread (&arc, sizeof (arc), 1, ifp) != 1)
69 {
70 fprintf (stderr, "%s: %s: unexpected end of file\n",
71 whoami, filename);
72 done (1);
03c35bcb 73 }
12516a37
KR
74 from_pc = get_vma (core_bfd, (bfd_byte *) arc.from_pc);
75 self_pc = get_vma (core_bfd, (bfd_byte *) arc.self_pc);
76 count = bfd_get_32 (core_bfd, (bfd_byte *) arc.count);
77 DBG (SAMPLEDEBUG,
78 printf ("[cg_read_rec] frompc 0x%lx selfpc 0x%lx count %d\n",
5489fcc3 79 from_pc, self_pc, count));
12516a37
KR
80 /* add this arc: */
81 cg_tally (from_pc, self_pc, count);
03c35bcb 82}
5489fcc3
KR
83
84
85/*
86 * Write all the arcs in the call-graph to file OFP. FILENAME is
87 * the name of OFP and is provided for formatting error-messages
88 * only.
89 */
90void
12516a37 91DEFUN (cg_write_arcs, (ofp, filename), FILE * ofp AND const char *filename)
5489fcc3 92{
12516a37
KR
93 const unsigned char tag = GMON_TAG_CG_ARC;
94 struct gmon_cg_arc_record raw_arc;
95 Arc *arc;
96 Sym *sym;
5489fcc3 97
12516a37
KR
98 for (sym = symtab.base; sym < symtab.limit; sym++)
99 {
100 for (arc = sym->cg.children; arc; arc = arc->next_child)
101 {
102 put_vma (core_bfd, arc->parent->addr, (bfd_byte *) raw_arc.from_pc);
103 put_vma (core_bfd, arc->child->addr, (bfd_byte *) raw_arc.self_pc);
104 bfd_put_32 (core_bfd, arc->count, (bfd_byte *) raw_arc.count);
105 if (fwrite (&tag, sizeof (tag), 1, ofp) != 1
106 || fwrite (&raw_arc, sizeof (raw_arc), 1, ofp) != 1)
5489fcc3 107 {
12516a37
KR
108 perror (filename);
109 done (1);
03c35bcb 110 }
12516a37
KR
111 DBG (SAMPLEDEBUG,
112 printf ("[cg_write_arcs] frompc 0x%lx selfpc 0x%lx count %d\n",
113 arc->parent->addr, arc->child->addr, arc->count));
03c35bcb
KR
114 }
115 }
116}
This page took 0.10937 seconds and 4 git commands to generate.