/* Gcc offline profile processing tool support. */
/* Copyright (C) 2014-2019 Free Software Foundation, Inc.
   Contributed by Rong Xu <xur@google.com>.

This file is part of GCC.

GCC 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 3, or (at your option) any later
version.

GCC 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.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "intl.h"
#include "diagnostic.h"
#include "version.h"
#include "gcov-io.h"
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#if HAVE_FTW_H
#include <ftw.h>
#endif
#include <getopt.h>

extern int gcov_profile_merge (struct gcov_info*, struct gcov_info*, int, int);
extern int gcov_profile_overlap (struct gcov_info*, struct gcov_info*);
extern int gcov_profile_normalize (struct gcov_info*, gcov_type);
extern int gcov_profile_scale (struct gcov_info*, float, int, int);
extern struct gcov_info* gcov_read_profile_dir (const char*, int);
extern void gcov_do_dump (struct gcov_info *, int);
extern const char *gcov_get_filename (struct gcov_info *list);
extern void gcov_set_verbose (void);

/* Set to verbose output mode.  */
static bool verbose;

#if HAVE_FTW_H

/* Remove file NAME if it has a gcda suffix. */

static int
unlink_gcda_file (const char *name,
                  const struct stat *status ATTRIBUTE_UNUSED,
                  int type ATTRIBUTE_UNUSED,
                  struct FTW *ftwbuf ATTRIBUTE_UNUSED)
{
  int ret = 0;
  int len = strlen (name);
  int len1 = strlen (GCOV_DATA_SUFFIX);

  if (len > len1 && !strncmp (len -len1 + name, GCOV_DATA_SUFFIX, len1))
    ret = remove (name);

  if (ret)
    fatal_error (input_location, "error in removing %s", name);

  return ret;
}
#endif

/* Remove the gcda files in PATH recursively.  */

static int
unlink_profile_dir (const char *path ATTRIBUTE_UNUSED)
{
#if HAVE_FTW_H
    return nftw(path, unlink_gcda_file, 64, FTW_DEPTH | FTW_PHYS);
#else
    return -1;
#endif
}

/* Output GCOV_INFO lists PROFILE to directory OUT. Note that
   we will remove all the gcda files in OUT.  */

static void
gcov_output_files (const char *out, struct gcov_info *profile)
{
  char *pwd;
  int ret;

  /* Try to make directory if it doesn't already exist.  */
  if (access (out, F_OK) == -1)
    {
      if (mkdir (out, S_IRWXU | S_IRWXG | S_IRWXO) == -1 && errno != EEXIST)
        fatal_error (input_location, "Cannot make directory %s", out);
    } else
      unlink_profile_dir (out);

  /* Output new profile.  */
  pwd = getcwd (NULL, 0);

  if (pwd == NULL)
    fatal_error (input_location, "Cannot get current directory name");

  ret = chdir (out);
  if (ret)
    fatal_error (input_location, "Cannot change directory to %s", out);

  /* Verify that output file does not exist (either was removed by
     unlink_profile_data or removed by user).  */
  const char *filename = gcov_get_filename (profile);

  if (access (filename, F_OK) != -1)
    fatal_error (input_location, "output file %s already exists in folder %s",
		 filename, out);

  gcov_do_dump (profile, 0);

  ret = chdir (pwd);
  if (ret)
    fatal_error (input_location, "Cannot change directory to %s", pwd);

  free (pwd);
}

/* Merging profile D1 and D2 with weight as W1 and W2, respectively.
   The result profile is written to directory OUT.
   Return 0 on success.  */

static int
profile_merge (const char *d1, const char *d2, const char *out, int w1, int w2)
{
  struct gcov_info *d1_profile;
  struct gcov_info *d2_profile;
  int ret;

  d1_profile = gcov_read_profile_dir (d1, 0);
  if (!d1_profile)
    return 1;

  if (d2)
    {
      d2_profile = gcov_read_profile_dir (d2, 0);
      if (!d2_profile)
        return 1;

      /* The actual merge: we overwrite to d1_profile.  */
      ret = gcov_profile_merge (d1_profile, d2_profile, w1, w2);

      if (ret)
        return ret;
    }

  gcov_output_files (out, d1_profile);

  return 0;
}

/* Usage message for profile merge.  */

static void
print_merge_usage_message (int error_p)
{
  FILE *file = error_p ? stderr : stdout;

  fnotice (file, "  merge [options] <dir1> <dir2>         Merge coverage file contents\n");
  fnotice (file, "    -o, --output <dir>                  Output directory\n");
  fnotice (file, "    -v, --verbose                       Verbose mode\n");
  fnotice (file, "    -w, --weight <w1,w2>                Set weights (float point values)\n");
}

static const struct option merge_options[] =
{
  { "verbose",                no_argument,       NULL, 'v' },
  { "output",                 required_argument, NULL, 'o' },
  { "weight",                 required_argument, NULL, 'w' },
  { 0, 0, 0, 0 }
};

/* Print merge usage and exit.  */

static void
merge_usage (void)
{
  fnotice (stderr, "Merge subcomand usage:");
  print_merge_usage_message (true);
  exit (FATAL_EXIT_CODE);
}

/* Driver for profile merge sub-command.  */

static int
do_merge (int argc, char **argv)
{
  int opt;
  const char *output_dir = 0;
  int w1 = 1, w2 = 1;

  optind = 0;
  while ((opt = getopt_long (argc, argv, "vo:w:", merge_options, NULL)) != -1)
    {
      switch (opt)
        {
        case 'v':
          verbose = true;
          gcov_set_verbose ();
          break;
        case 'o':
          output_dir = optarg;
          break;
        case 'w':
          sscanf (optarg, "%d,%d", &w1, &w2);
          if (w1 < 0 || w2 < 0)
	    fatal_error (input_location, "weights need to be non-negative");
          break;
        default:
          merge_usage ();
        }
    }

  if (output_dir == NULL)
    output_dir = "merged_profile";

  if (argc - optind != 2)
    merge_usage ();

  return profile_merge (argv[optind], argv[optind+1], output_dir, w1, w2);
}

/* If N_VAL is no-zero, normalize the profile by setting the largest counter
   counter value to N_VAL and scale others counters proportionally.
   Otherwise, multiply the all counters by SCALE.  */

static int
profile_rewrite (const char *d1, const char *out, int64_t n_val,
                 float scale, int n, int d)
{
  struct gcov_info * d1_profile;

  d1_profile = gcov_read_profile_dir (d1, 0);
  if (!d1_profile)
    return 1;

  if (n_val)
    gcov_profile_normalize (d1_profile, (gcov_type) n_val);
  else
    gcov_profile_scale (d1_profile, scale, n, d);

  gcov_output_files (out, d1_profile);
  return 0;
}

/* Usage function for profile rewrite.  */

static void
print_rewrite_usage_message (int error_p)
{
  FILE *file = error_p ? stderr : stdout;

  fnotice (file, "  rewrite [options] <dir>               Rewrite coverage file contents\n");
  fnotice (file, "    -n, --normalize <int64_t>           Normalize the profile\n");
  fnotice (file, "    -o, --output <dir>                  Output directory\n");
  fnotice (file, "    -s, --scale <float or simple-frac>  Scale the profile counters\n");
  fnotice (file, "    -v, --verbose                       Verbose mode\n");
}

static const struct option rewrite_options[] =
{
  { "verbose",                no_argument,       NULL, 'v' },
  { "output",                 required_argument, NULL, 'o' },
  { "scale",                  required_argument, NULL, 's' },
  { "normalize",              required_argument, NULL, 'n' },
  { 0, 0, 0, 0 }
};

/* Print profile rewrite usage and exit.  */

static void
rewrite_usage (void)
{
  fnotice (stderr, "Rewrite subcommand usage:");
  print_rewrite_usage_message (true);
  exit (FATAL_EXIT_CODE);
}

/* Driver for profile rewrite sub-command. */

static int
do_rewrite (int argc, char **argv)
{
  int opt;
  int ret;
  const char *output_dir = 0;
  int64_t normalize_val = 0;
  float scale = 0.0;
  int numerator = 1;
  int denominator = 1;
  int do_scaling = 0;

  optind = 0;
  while ((opt = getopt_long (argc, argv, "vo:s:n:", rewrite_options, NULL)) != -1)
    {
      switch (opt)
        {
        case 'v':
          verbose = true;
          gcov_set_verbose ();
          break;
        case 'o':
          output_dir = optarg;
          break;
        case 'n':
          if (!do_scaling)
#if defined(INT64_T_IS_LONG)
	    normalize_val = strtol (optarg, (char **)NULL, 10);
#else
	    normalize_val = strtoll (optarg, (char **)NULL, 10);
#endif
          else
            fnotice (stderr, "scaling cannot co-exist with normalization,"
                " skipping\n");
          break;
        case 's':
          ret = 0;
          do_scaling = 1;
          if (strstr (optarg, "/"))
            {
              ret = sscanf (optarg, "%d/%d", &numerator, &denominator);
              if (ret == 2)
                {
                  if (numerator < 0 || denominator <= 0)
                    {
                      fnotice (stderr, "incorrect format in scaling, using 1/1\n");
                      denominator = 1;
                      numerator = 1;
                    }
                }
            }
          if (ret != 2)
            {
              ret = sscanf (optarg, "%f", &scale);
              if (ret != 1)
                fnotice (stderr, "incorrect format in scaling, using 1/1\n");
              else
                denominator = 0;
            }

          if (scale < 0.0)
	    fatal_error (input_location, "scale needs to be non-negative");

          if (normalize_val != 0)
            {
              fnotice (stderr, "normalization cannot co-exist with scaling\n");
              normalize_val = 0;
            }
          break;
        default:
          rewrite_usage ();
        }
    }

  if (output_dir == NULL)
    output_dir = "rewrite_profile";

  if (argc - optind == 1)
    {
      if (denominator > 0)
        ret = profile_rewrite (argv[optind],  output_dir, 0, 0.0, numerator, denominator);
      else
        ret = profile_rewrite (argv[optind],  output_dir, normalize_val, scale, 0, 0);
    }
  else
    rewrite_usage ();

  return ret;
}

/* Driver function to computer the overlap score b/w profile D1 and D2.
   Return 1 on error and 0 if OK.  */

static int
profile_overlap (const char *d1, const char *d2)
{
  struct gcov_info *d1_profile;
  struct gcov_info *d2_profile;

  d1_profile = gcov_read_profile_dir (d1, 0);
  if (!d1_profile)
    return 1;

  if (d2)
    {
      d2_profile = gcov_read_profile_dir (d2, 0);
      if (!d2_profile)
        return 1;

      return gcov_profile_overlap (d1_profile, d2_profile);
    }

  return 1;
}

/* Usage message for profile overlap.  */

static void
print_overlap_usage_message (int error_p)
{
  FILE *file = error_p ? stderr : stdout;

  fnotice (file, "  overlap [options] <dir1> <dir2>       Compute the overlap of two profiles\n");
  fnotice (file, "    -f, --function                      Print function level info\n");
  fnotice (file, "    -F, --fullname                      Print full filename\n");
  fnotice (file, "    -h, --hotonly                       Only print info for hot objects/functions\n");
  fnotice (file, "    -o, --object                        Print object level info\n");
  fnotice (file, "    -t <float>, --hot_threshold <float> Set the threshold for hotness\n");
  fnotice (file, "    -v, --verbose                       Verbose mode\n");
}

static const struct option overlap_options[] =
{
  { "verbose",                no_argument,       NULL, 'v' },
  { "function",               no_argument,       NULL, 'f' },
  { "fullname",               no_argument,       NULL, 'F' },
  { "object",                 no_argument,       NULL, 'o' },
  { "hotonly",                no_argument,       NULL, 'h' },
  { "hot_threshold",          required_argument, NULL, 't' },
  { 0, 0, 0, 0 }
};

/* Print overlap usage and exit.  */

static void ATTRIBUTE_NORETURN
overlap_usage (void)
{
  fnotice (stderr, "Overlap subcomand usage:");
  print_overlap_usage_message (true);
  exit (FATAL_EXIT_CODE);
}

int overlap_func_level;
int overlap_obj_level;
int overlap_hot_only;
int overlap_use_fullname;
double overlap_hot_threshold = 0.005;

/* Driver for profile overlap sub-command.  */

static int
do_overlap (int argc, char **argv)
{
  int opt;
  int ret;

  optind = 0;
  while ((opt = getopt_long (argc, argv, "vfFoht:", overlap_options, NULL)) != -1)
    {
      switch (opt)
        {
        case 'v':
          verbose = true;
          gcov_set_verbose ();
          break;
        case 'f':
          overlap_func_level = 1;
          break;
        case 'F':
          overlap_use_fullname = 1;
          break;
        case 'o':
          overlap_obj_level = 1;
          break;
        case 'h':
          overlap_hot_only = 1;
          break;
        case 't':
          overlap_hot_threshold = atof (optarg);
          break;
        default:
          overlap_usage ();
        }
    }

  if (argc - optind == 2)
    ret = profile_overlap (argv[optind], argv[optind+1]);
  else
    overlap_usage ();

  return ret;
}


/* Print a usage message and exit.  If ERROR_P is nonzero, this is an error,
   otherwise the output of --help.  */

static void
print_usage (int error_p)
{
  FILE *file = error_p ? stderr : stdout;
  int status = error_p ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;

  fnotice (file, "Usage: %s [OPTION]... SUB_COMMAND [OPTION]...\n\n", progname);
  fnotice (file, "Offline tool to handle gcda counts\n\n");
  fnotice (file, "  -h, --help                            Print this help, then exit\n");
  fnotice (file, "  -v, --version                         Print version number, then exit\n");
  print_merge_usage_message (error_p);
  print_rewrite_usage_message (error_p);
  print_overlap_usage_message (error_p);
  fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n",
           bug_report_url);
  exit (status);
}

/* Print version information and exit.  */

static void
print_version (void)
{
  fnotice (stdout, "%s %s%s\n", progname, pkgversion_string, version_string);
  fnotice (stdout, "Copyright %s 2019 Free Software Foundation, Inc.\n",
           _("(C)"));
  fnotice (stdout,
           _("This is free software; see the source for copying conditions.\n"
             "There is NO warranty; not even for MERCHANTABILITY or \n"
             "FITNESS FOR A PARTICULAR PURPOSE.\n\n"));
  exit (SUCCESS_EXIT_CODE);
}

static const struct option options[] =
{
  { "help",                 no_argument,       NULL, 'h' },
  { "version",              no_argument,       NULL, 'v' },
  { 0, 0, 0, 0 }
};

/* Process args, return index to first non-arg.  */

static int
process_args (int argc, char **argv)
{
  int opt;

  while ((opt = getopt_long (argc, argv, "+hv", options, NULL)) != -1)
    {
      switch (opt)
        {
        case 'h':
          print_usage (false);
          /* Print_usage will exit.  */
	  /* FALLTHRU */
        case 'v':
          print_version ();
          /* Print_version will exit.  */
	  /* FALLTHRU */
        default:
          print_usage (true);
          /* Print_usage will exit.  */
        }
    }

  return optind;
}

/* Main function for gcov-tool.  */

int
main (int argc, char **argv)
{
  const char *p;
  const char *sub_command;

  p = argv[0] + strlen (argv[0]);
  while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
    --p;
  progname = p;

  xmalloc_set_program_name (progname);

  /* Unlock the stdio streams.  */
  unlock_std_streams ();

  gcc_init_libintl ();

  diagnostic_initialize (global_dc, 0);

  /* Handle response files.  */
  expandargv (&argc, &argv);

  process_args (argc, argv);
  if (optind >= argc)
    print_usage (true);

  sub_command = argv[optind];

  if (!strcmp (sub_command, "merge"))
    return do_merge (argc - optind, argv + optind);
  else if (!strcmp (sub_command, "rewrite"))
    return do_rewrite (argc - optind, argv + optind);
  else if (!strcmp (sub_command, "overlap"))
    return do_overlap (argc - optind, argv + optind);

  print_usage (true);
}
