ran "indent -gnu"; have not fixed block comment style
[platform/upstream/binutils.git] / gprof / call_graph.c
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
9 extern void
10 DEFUN (cg_tally, (from_pc, self_pc, count),
11        bfd_vma from_pc AND bfd_vma self_pc AND int count)
12 {
13   Sym *parent;
14   Sym *child;
15
16   parent = sym_lookup (&symtab, from_pc);
17   child = sym_lookup (&symtab, self_pc);
18
19   /*
20    * Keep arc if it is on INCL_ARCS table or if the INCL_ARCS table
21    * is empty and it is not in the EXCL_ARCS table.
22    */
23   if (sym_id_arc_is_present (&syms[INCL_ARCS], parent, child)
24       || (syms[INCL_ARCS].len == 0
25           && !sym_id_arc_is_present (&syms[EXCL_ARCS], parent, child)))
26     {
27       child->ncalls += count;
28       DBG (TALLYDEBUG,
29            printf ("[cg_tally] arc from %s to %s traversed %d times\n",
30                    parent->name, child->name, count));
31       arc_add (parent, child, count);
32     }                           /* if */
33 }                               /* cg_tally */
34
35
36 /*
37  * Read a record from file IFP describing an arc in the function
38  * call-graph and the count of how many times the arc has been
39  * traversed.  FILENAME is the name of file IFP and is provided
40  * for formatting error-messages only.
41  */
42 void
43 DEFUN (cg_read_rec, (ifp, filename), FILE * ifp AND CONST char *filename)
44 {
45   bfd_vma from_pc, self_pc;
46   struct gmon_cg_arc_record arc;
47   int count;
48
49   if (fread (&arc, sizeof (arc), 1, ifp) != 1)
50     {
51       fprintf (stderr, "%s: %s: unexpected end of file\n",
52                whoami, filename);
53       done (1);
54     }                           /* if */
55   from_pc = get_vma (core_bfd, (bfd_byte *) arc.from_pc);
56   self_pc = get_vma (core_bfd, (bfd_byte *) arc.self_pc);
57   count = bfd_get_32 (core_bfd, (bfd_byte *) arc.count);
58   DBG (SAMPLEDEBUG,
59        printf ("[cg_read_rec] frompc 0x%lx selfpc 0x%lx count %d\n",
60                from_pc, self_pc, count));
61   /* add this arc: */
62   cg_tally (from_pc, self_pc, count);
63 }                               /* cg_read_rec */
64
65
66 /*
67  * Write all the arcs in the call-graph to file OFP.  FILENAME is
68  * the name of OFP and is provided for formatting error-messages
69  * only.
70  */
71 void
72 DEFUN (cg_write_arcs, (ofp, filename), FILE * ofp AND const char *filename)
73 {
74   const unsigned char tag = GMON_TAG_CG_ARC;
75   struct gmon_cg_arc_record raw_arc;
76   Arc *arc;
77   Sym *sym;
78
79   for (sym = symtab.base; sym < symtab.limit; sym++)
80     {
81       for (arc = sym->cg.children; arc; arc = arc->next_child)
82         {
83           put_vma (core_bfd, arc->parent->addr, (bfd_byte *) raw_arc.from_pc);
84           put_vma (core_bfd, arc->child->addr, (bfd_byte *) raw_arc.self_pc);
85           bfd_put_32 (core_bfd, arc->count, (bfd_byte *) raw_arc.count);
86           if (fwrite (&tag, sizeof (tag), 1, ofp) != 1
87               || fwrite (&raw_arc, sizeof (raw_arc), 1, ofp) != 1)
88             {
89               perror (filename);
90               done (1);
91             }                   /* if */
92           DBG (SAMPLEDEBUG,
93              printf ("[cg_write_arcs] frompc 0x%lx selfpc 0x%lx count %d\n",
94                      arc->parent->addr, arc->child->addr, arc->count));
95         }                       /* for */
96     }                           /* for */
97 }                               /* cg_write_arcs */
98
99 /*** end of call_graph.c ***/