/* call_graph.c  -  Create call graphs.

   Copyright 2000, 2001 Free Software Foundation, Inc.

   This file is part of GNU Binutils.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.  */

#include "cg_arcs.h"
#include "call_graph.h"
#include "corefile.h"
#include "gmon_io.h"
#include "gmon_out.h"
#include "symtab.h"
#include "sym_ids.h"

extern void
DEFUN (cg_tally, (from_pc, self_pc, count),
       bfd_vma from_pc AND bfd_vma self_pc AND unsigned long count)
{
  Sym *parent;
  Sym *child;

  parent = sym_lookup (&symtab, from_pc);
  child = sym_lookup (&symtab, self_pc);

  if (child == NULL || parent == NULL)
    return;

  /* If we're doing line-by-line profiling, both the parent and the
     child will probably point to line symbols instead of function
     symbols.  For the parent this is fine, since this identifies the
     line number in the calling routing, but the child should always
     point to a function entry point, so we back up in the symbol
     table until we find it.

     For normal profiling, is_func will be set on all symbols, so this
     code will do nothing.  */
  while (child >= symtab.base && ! child->is_func)
    --child;

  if (child < symtab.base)
    return;

  /* Keep arc if it is on INCL_ARCS table or if the INCL_ARCS table
     is empty and it is not in the EXCL_ARCS table.  */
  if (sym_id_arc_is_present (&syms[INCL_ARCS], parent, child)
      || (syms[INCL_ARCS].len == 0
	  && !sym_id_arc_is_present (&syms[EXCL_ARCS], parent, child)))
    {
      child->ncalls += count;
      DBG (TALLYDEBUG,
	   printf (_("[cg_tally] arc from %s to %s traversed %lu times\n"),
		   parent->name, child->name, count));
      arc_add (parent, child, count);
    }
}

/* Read a record from file IFP describing an arc in the function
   call-graph and the count of how many times the arc has been
   traversed.  FILENAME is the name of file IFP and is provided
   for formatting error-messages only.  */

void
DEFUN (cg_read_rec, (ifp, filename), FILE * ifp AND CONST char *filename)
{
  bfd_vma from_pc, self_pc;
  unsigned int count;

  if (gmon_io_read_vma (ifp, &from_pc)
      || gmon_io_read_vma (ifp, &self_pc)
      || gmon_io_read_32 (ifp, &count))
    {
      fprintf (stderr, _("%s: %s: unexpected end of file\n"),
	       whoami, filename);
      done (1);
    }

  DBG (SAMPLEDEBUG,
       printf ("[cg_read_rec] frompc 0x%lx selfpc 0x%lx count %lu\n",
	       (unsigned long) from_pc, (unsigned long) self_pc,
	       (unsigned long) count));
  /* Add this arc:  */
  cg_tally (from_pc, self_pc, count);
}

/* Write all the arcs in the call-graph to file OFP.  FILENAME is
   the name of OFP and is provided for formatting error-messages
   only.  */

void
DEFUN (cg_write_arcs, (ofp, filename), FILE * ofp AND const char *filename)
{
  Arc *arc;
  Sym *sym;

  for (sym = symtab.base; sym < symtab.limit; sym++)
    {
      for (arc = sym->cg.children; arc; arc = arc->next_child)
	{
	  if (gmon_io_write_8 (ofp, GMON_TAG_CG_ARC)
	      || gmon_io_write_vma (ofp, arc->parent->addr)
	      || gmon_io_write_vma (ofp, arc->child->addr)
	      || gmon_io_write_32 (ofp, arc->count))
	    {
	      perror (filename);
	      done (1);
	    }
	  DBG (SAMPLEDEBUG,
	     printf ("[cg_write_arcs] frompc 0x%lx selfpc 0x%lx count %lu\n",
		     (unsigned long) arc->parent->addr,
		     (unsigned long) arc->child->addr, arc->count));
	}
    }
}
