/*
 * Input and output from/to gmon.out files.
 */
#include "cg_arcs.h"
#include "basic_blocks.h"
#include "bfd.h"
#include "corefile.h"
#include "call_graph.h"
#include "gmon_io.h"
#include "gmon_out.h"
#include "gmon.h"		/* fetch header for old format */
#include "gprof.h"
#include "hertz.h"
#include "hist.h"
#include "libiberty.h"

int gmon_input = 0;
int gmon_file_version = 0;	/* 0 == old (non-versioned) file format */

/*
 * This probably ought to be in libbfd.
 */
bfd_vma
DEFUN (get_vma, (abfd, addr), bfd * abfd AND bfd_byte * addr)
{
  switch (sizeof (char*))
    {
    case 4:
      return bfd_get_32 (abfd, addr);
    case 8:
      return bfd_get_64 (abfd, addr);
    default:
      fprintf (stderr, _("%s: bfd_vma has unexpected size of %ld bytes\n"),
	       whoami, (long) sizeof (char*));
      done (1);
    }
}


/*
 * This probably ought to be in libbfd.
 */
void
DEFUN (put_vma, (abfd, val, addr), bfd * abfd AND bfd_vma val AND bfd_byte * addr)
{
  switch (sizeof (char*))
    {
    case 4:
      bfd_put_32 (abfd, val, addr);
      break;
    case 8:
      bfd_put_64 (abfd, val, addr);
      break;
    default:
      fprintf (stderr, _("%s: bfd_vma has unexpected size of %ld bytes\n"),
	       whoami, (long) sizeof (char*));
      done (1);
    }
}


void
DEFUN (gmon_out_read, (filename), const char *filename)
{
  FILE *ifp;
  struct gmon_hdr ghdr;
  unsigned char tag;
  int nhist = 0, narcs = 0, nbbs = 0;

  /* open gmon.out file: */

  if (strcmp (filename, "-") == 0)
    {
      ifp = stdin;
    }
  else
    {
      ifp = fopen (filename, FOPEN_RB);
      if (!ifp)
	{
	  perror (filename);
	  done (1);
	}
    }
  if (fread (&ghdr, sizeof (struct gmon_hdr), 1, ifp) != 1)
    {
      fprintf (stderr, _("%s: file too short to be a gmon file\n"),
	       filename);
      done (1);
    }

  if ((file_format == FF_MAGIC) ||
      (file_format == FF_AUTO && !strncmp (&ghdr.cookie[0], GMON_MAGIC, 4)))
    {
      if (file_format == FF_MAGIC && strncmp (&ghdr.cookie[0], GMON_MAGIC, 4))
	{
	  fprintf (stderr, _("%s: file `%s' has bad magic cookie\n"),
		   whoami, filename);
	  done (1);
	}

      /* right magic, so it's probably really a new gmon.out file */

      gmon_file_version = bfd_get_32 (core_bfd, (bfd_byte *) ghdr.version);
      if (gmon_file_version != GMON_VERSION && gmon_file_version != 0)
	{
	  fprintf (stderr,
		   _("%s: file `%s' has unsupported version %d\n"),
		   whoami, filename, gmon_file_version);
	  done (1);
	}

      /* read in all the records: */
      while (fread (&tag, sizeof (tag), 1, ifp) == 1)
	{
	  switch (tag)
	    {
	    case GMON_TAG_TIME_HIST:
	      ++nhist;
	      gmon_input |= INPUT_HISTOGRAM;
	      hist_read_rec (ifp, filename);
	      break;

	    case GMON_TAG_CG_ARC:
	      ++narcs;
	      gmon_input |= INPUT_CALL_GRAPH;
	      cg_read_rec (ifp, filename);
	      break;

	    case GMON_TAG_BB_COUNT:
	      ++nbbs;
	      gmon_input |= INPUT_BB_COUNTS;
	      bb_read_rec (ifp, filename);
	      break;

	    default:
	      fprintf (stderr,
		       _("%s: %s: found bad tag %d (file corrupted?)\n"),
		       whoami, filename, tag);
	      done (1);
	    }
	}
    }
  else if (file_format == FF_AUTO
	   || file_format == FF_BSD
	   || file_format == FF_BSD44)
    {
      struct hdr
      {
	bfd_vma low_pc;
	bfd_vma high_pc;
	int ncnt;
      };
      int i, samp_bytes, header_size;
      unsigned long count;
      bfd_vma from_pc, self_pc;
      struct raw_arc raw_arc;
      struct raw_phdr raw;
      static struct hdr h;
      UNIT raw_bin_count;
      struct hdr tmp;

      /*
       * Information from a gmon.out file is in two parts: an array of
       * sampling hits within pc ranges, and the arcs.
       */
      gmon_input = INPUT_HISTOGRAM | INPUT_CALL_GRAPH;

      /*
       * This fseek() ought to work even on stdin as long as it's
       * not an interactive device (heck, is there anybody who would
       * want to type in a gmon.out at the terminal?).
       */
      if (fseek (ifp, 0, SEEK_SET) < 0)
	{
	  perror (filename);
	  done (1);
	}
      if (fread (&raw, 1, sizeof (struct raw_phdr), ifp)
	  != sizeof (struct raw_phdr))
	{
	  fprintf (stderr, _("%s: file too short to be a gmon file\n"),
		   filename);
	  done (1);
	}
      tmp.low_pc = get_vma (core_bfd, (bfd_byte *) &raw.low_pc[0]);
      tmp.high_pc = get_vma (core_bfd, (bfd_byte *) &raw.high_pc[0]);
      tmp.ncnt = bfd_get_32 (core_bfd, (bfd_byte *) &raw.ncnt[0]);

      if (bfd_get_32 (core_bfd, (bfd_byte *) &raw.version[0])
	  == GMONVERSION)
	{
	  int profrate;

	  /* 4.4BSD format header.  */

	  profrate = bfd_get_32 (core_bfd, (bfd_byte *) &raw.profrate[0]);
	  if (!s_highpc)
	    hz = profrate;
	  else if (hz != profrate)
	    {
	      fprintf (stderr,
		       _("%s: profiling rate incompatible with first gmon file\n"),
		       filename);
	      done (1);
	    }

	  header_size = sizeof (struct raw_phdr);
	}
      else
	{
	  /* old style BSD format.  */
	  if (file_format == FF_BSD44)
	    {
	      fprintf (stderr, _("%s: file `%s' has bad magic cookie\n"),
		       whoami, filename);
	      done (1);
	    }

	  if (fseek (ifp, sizeof (struct old_raw_phdr), SEEK_SET) < 0)
	    {
	      perror (filename);
	      done (1);
	    }

	  header_size = sizeof (struct old_raw_phdr);
	}

      if (s_highpc && (tmp.low_pc != h.low_pc ||
		       tmp.high_pc != h.high_pc || tmp.ncnt != h.ncnt))
	{
	  fprintf (stderr, _("%s: incompatible with first gmon file\n"),
		   filename);
	  done (1);
	}
      h = tmp;
      s_lowpc = (bfd_vma) h.low_pc;
      s_highpc = (bfd_vma) h.high_pc;
      lowpc = (bfd_vma) h.low_pc / sizeof (UNIT);
      highpc = (bfd_vma) h.high_pc / sizeof (UNIT);
      samp_bytes = h.ncnt - header_size;
      hist_num_bins = samp_bytes / sizeof (UNIT);
      DBG (SAMPLEDEBUG,
	   printf ("[gmon_out_read] lowpc 0x%lx highpc 0x%lx ncnt %d\n",
		   (unsigned long) h.low_pc, (unsigned long) h.high_pc,
		   h.ncnt);
	   printf ("[gmon_out_read]   s_lowpc 0x%lx   s_highpc 0x%lx\n",
		   (unsigned long) s_lowpc, (unsigned long) s_highpc);
	   printf ("[gmon_out_read]     lowpc 0x%lx     highpc 0x%lx\n",
		   (unsigned long) lowpc, (unsigned long) highpc);
	   printf ("[gmon_out_read] samp_bytes %d hist_num_bins %d\n",
		   samp_bytes, hist_num_bins));

      /* Make sure that we have sensible values.  */
      if (samp_bytes < 0 || lowpc > highpc)
        {
          fprintf (stderr, 
	    _("%s: file '%s' does not appear to be in gmon.out format\n"),
	    whoami, filename);
          done (1);
        }

      if (hist_num_bins)
	{
	  ++nhist;
	}

      if (!hist_sample)
	{
	  hist_sample =
	    (int *) xmalloc (hist_num_bins * sizeof (hist_sample[0]));
	  memset (hist_sample, 0, hist_num_bins * sizeof (hist_sample[0]));
	}

      for (i = 0; i < hist_num_bins; ++i)
	{
	  if (fread (raw_bin_count, sizeof (raw_bin_count), 1, ifp) != 1)
	    {
	      fprintf (stderr,
		       _("%s: unexpected EOF after reading %d/%d bins\n"),
		       whoami, --i, hist_num_bins);
	      done (1);
	    }
	  hist_sample[i] += bfd_get_16 (core_bfd, (bfd_byte *) raw_bin_count);
	}

      /*
       * The rest of the file consists of a bunch of <from,self,count>
       * tuples:
       */
      while (fread (&raw_arc, sizeof (raw_arc), 1, ifp) == 1)
	{
	  ++narcs;
	  from_pc = get_vma (core_bfd, (bfd_byte *) raw_arc.from_pc);
	  self_pc = get_vma (core_bfd, (bfd_byte *) raw_arc.self_pc);
	  count = bfd_get_32 (core_bfd, (bfd_byte *) raw_arc.count);
	  DBG (SAMPLEDEBUG,
	     printf ("[gmon_out_read] frompc 0x%lx selfpc 0x%lx count %lu\n",
		     (unsigned long) from_pc, (unsigned long) self_pc, count));
	  /* add this arc: */
	  cg_tally (from_pc, self_pc, count);
	}
      fclose (ifp);

      if (hz == HZ_WRONG)
	{
	  /*
	   * How many ticks per second?  If we can't tell, report
	   * time in ticks.
	   */
	  hz = hertz ();
	  if (hz == HZ_WRONG)
	    {
	      hz = 1;
	      fprintf (stderr, _("time is in ticks, not seconds\n"));
	    }
	}
    }
  else
    {
      fprintf (stderr, _("%s: don't know how to deal with file format %d\n"),
	       whoami, file_format);
      done (1);
    }

  if (output_style & STYLE_GMON_INFO)
    {
      printf (_("File `%s' (version %d) contains:\n"),
	      filename, gmon_file_version);
      printf (_("\t%d histogram record%s\n"),
	      nhist, nhist == 1 ? "" : "s");
      printf (_("\t%d call-graph record%s\n"),
	      narcs, narcs == 1 ? "" : "s");
      printf (_("\t%d basic-block count record%s\n"),
	      nbbs, nbbs == 1 ? "" : "s");
      first_output = FALSE;
    }
}


void
DEFUN (gmon_out_write, (filename), const char *filename)
{
  FILE *ofp;
  struct gmon_hdr ghdr;

  ofp = fopen (filename, FOPEN_WB);
  if (!ofp)
    {
      perror (filename);
      done (1);
    }

  if (file_format == FF_AUTO || file_format == FF_MAGIC)
    {
      /* write gmon header: */

      memcpy (&ghdr.cookie[0], GMON_MAGIC, 4);
      bfd_put_32 (core_bfd, GMON_VERSION, (bfd_byte *) ghdr.version);
      if (fwrite (&ghdr, sizeof (ghdr), 1, ofp) != 1)
	{
	  perror (filename);
	  done (1);
	}

      /* write execution time histogram if we have one: */
      if (gmon_input & INPUT_HISTOGRAM)
	{
	  hist_write_hist (ofp, filename);
	}

      /* write call graph arcs if we have any: */
      if (gmon_input & INPUT_CALL_GRAPH)
	{
	  cg_write_arcs (ofp, filename);
	}

      /* write basic-block info if we have it: */
      if (gmon_input & INPUT_BB_COUNTS)
	{
	  bb_write_blocks (ofp, filename);
	}
    }
  else if (file_format == FF_BSD || file_format == FF_BSD44)
    {
      struct raw_arc raw_arc;
      UNIT raw_bin_count;
      struct raw_phdr h;
      int i;
      Arc *arc;
      Sym *sym;

      memset (&h, 0, sizeof h);
      put_vma (core_bfd, s_lowpc, (bfd_byte *) &h.low_pc);
      put_vma (core_bfd, s_highpc, (bfd_byte *) &h.high_pc);
      bfd_put_32 (core_bfd,
		  hist_num_bins * sizeof (UNIT) + sizeof (struct raw_phdr),
		  (bfd_byte *) &h.ncnt);

      /* Write header.  Use new style BSD format is explicitly
         specified, or if the profiling rate is non-standard;
         otherwise, use the old BSD format.  */
      if (file_format == FF_BSD44
	  || hz != hertz ())
	{
	  bfd_put_32 (core_bfd, GMONVERSION, (bfd_byte *) &h.version);
	  bfd_put_32 (core_bfd, hz, (bfd_byte *) &h.profrate);
	  if (fwrite (&h, sizeof (struct raw_phdr), 1, ofp) != 1)
	    {
	      perror (filename);
	      done (1);
	    }
	}
      else
	{
	  if (fwrite (&h, sizeof (struct old_raw_phdr), 1, ofp) != 1)
	    {
	      perror (filename);
	      done (1);
	    }
	}

      /* dump the samples: */

      for (i = 0; i < hist_num_bins; ++i)
	{
	  bfd_put_16 (core_bfd, hist_sample[i], (bfd_byte *) & raw_bin_count[0]);
	  if (fwrite (&raw_bin_count[0], sizeof (raw_bin_count), 1, ofp) != 1)
	    {
	      perror (filename);
	      done (1);
	    }
	}

      /* dump the normalized raw arc information: */

      for (sym = symtab.base; sym < symtab.limit; ++sym)
	{
	  for (arc = sym->cg.children; arc; arc = arc->next_child)
	    {
	      put_vma (core_bfd, arc->parent->addr,
		       (bfd_byte *) raw_arc.from_pc);
	      put_vma (core_bfd, arc->child->addr,
		       (bfd_byte *) raw_arc.self_pc);
	      bfd_put_32 (core_bfd, arc->count, (bfd_byte *) raw_arc.count);
	      if (fwrite (&raw_arc, sizeof (raw_arc), 1, ofp) != 1)
		{
		  perror (filename);
		  done (1);
		}
	      DBG (SAMPLEDEBUG,
		   printf ("[dumpsum] frompc 0x%lx selfpc 0x%lx count %lu\n",
			   (unsigned long) arc->parent->addr,
			   (unsigned long) arc->child->addr, arc->count));
	    }
	}
      fclose (ofp);
    }
  else
    {
      fprintf (stderr, _("%s: don't know how to deal with file format %d\n"),
	       whoami, file_format);
      done (1);
    }
}
