/* Gcc offline profile processing tool support. */
/* Copyright (C) 2014-2022 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 struct gcov_info *gcov_profile_merge (struct gcov_info*,
					     struct gcov_info*, int, int);
extern struct gcov_info *gcov_profile_merge_stream (const char *, 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, 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, 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;
  struct gcov_info *merged_profile;

  d1_profile = gcov_read_profile_dir (d1, 0);
  d2_profile = gcov_read_profile_dir (d2, 0);

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

  if (merged_profile)
    gcov_output_files (out, merged_profile);
  else if (verbose)
    fnotice (stdout, "no profile files were merged\n");

  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 ATTRIBUTE_NORETURN
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);
}

/* Usage message for profile merge-stream.  */

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

  fnotice (file, "  merge-stream [options] [<file>]       Merge coverage stream file (or stdin)\n"
		 "                                        and coverage file contents\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_stream_options[] =
{
  { "verbose",                no_argument,       NULL, 'v' },
  { "weight",                 required_argument, NULL, 'w' },
  { 0, 0, 0, 0 }
};

/* Print merge-stream usage and exit.  */

static void ATTRIBUTE_NORETURN
merge_stream_usage (void)
{
  fnotice (stderr, "Merge-stream subcomand usage:");
  print_merge_stream_usage_message (true);
  exit (FATAL_EXIT_CODE);
}

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

static int
do_merge_stream (int argc, char **argv)
{
  int opt;
  int w1 = 1, w2 = 1;
  struct gcov_info *merged_profile;

  optind = 0;
  while ((opt = getopt_long (argc, argv, "vw:",
			     merge_stream_options, NULL)) != -1)
    {
      switch (opt)
	{
	case 'v':
	  verbose = true;
	  gcov_set_verbose ();
	  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_stream_usage ();
	}
    }

  if (argc - optind > 1)
    merge_stream_usage ();

  merged_profile = gcov_profile_merge_stream (argv[optind], w1, w2);

  if (merged_profile)
    gcov_do_dump (merged_profile, 0, -1);
  else if (verbose)
    fnotice (stdout, "no profile files were merged\n");

  return 0;
}

/* 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 ATTRIBUTE_NORETURN
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_merge_stream_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 2022 Free Software Foundation, Inc.\n",
           _("(C)"));
  fnotice (stdout,
	   _("This is free software; see the source for copying conditions.  There is NO\n\
warranty; not even for MERCHANTABILITY or 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, "merge-stream"))
    return do_merge_stream (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);
}
