Hello.

Following enhancement for gcov solves issues when we cannot create a file due 
to a filesystem
path length limit. Selected approach utilizes existing md5sum functions.

Patch survives make check -k RUNTESTFLAGS="gcov.exp" on x86_64-linux-gnu.

Ready for trunk?
Thanks,
Martin

>From 42393a73c0433d7de28dc560f47ff61e615718bf Mon Sep 17 00:00:00 2001
From: marxin <mli...@suse.cz>
Date: Tue, 9 Aug 2016 16:27:10 +0200
Subject: [PATCH] gcov: add new option (--hash-names) (PR gcov-profile/36412).

gcc/ChangeLog:

2016-08-09  Martin Liska  <mli...@suse.cz>

	PR gcov-profile/36412
	* doc/gcov.texi: Document --hash-names (-e).
	* gcov.c (print_usage): Add the option.
	(process_args): Process the option.
	(md5sum_to_hex): New function.
	(make_gcov_file_name): Do the md5sum and append it to a
	filename.
---
 gcc/doc/gcov.texi |  6 ++++++
 gcc/gcov.c        | 47 +++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/gcc/doc/gcov.texi b/gcc/doc/gcov.texi
index 89d8049..78c0c75 100644
--- a/gcc/doc/gcov.texi
+++ b/gcc/doc/gcov.texi
@@ -123,6 +123,7 @@ gcov [@option{-v}|@option{--version}] [@option{-h}|@option{--help}]
      [@option{-b}|@option{--branch-probabilities}]
      [@option{-c}|@option{--branch-counts}]
      [@option{-d}|@option{--display-progress}]
+     [@option{-e}|@option{--hash-names}]
      [@option{-f}|@option{--function-summaries}]
      [@option{-i}|@option{--intermediate-format}]
      [@option{-l}|@option{--long-file-names}]
@@ -171,6 +172,11 @@ be shown, unless the @option{-u} option is given.
 Write branch frequencies as the number of branches taken, rather than
 the percentage of branches taken.
 
+@item -e
+@itemx --hash-names
+For situations when a long name can potentially hit filesystem path limit,
+let's calculate md5sum of the patch and create file x.gcov##md5sum.gcov.
+
 @item -n
 @itemx --no-output
 Do not create the @command{gcov} output file.
diff --git a/gcc/gcov.c b/gcc/gcov.c
index f05ef7c..97739b7 100644
--- a/gcc/gcov.c
+++ b/gcc/gcov.c
@@ -43,6 +43,7 @@ along with Gcov; see the file COPYING3.  If not see
 
 #include <vector>
 #include <algorithm>
+#include "md5.h"
 
 using namespace std;
 
@@ -359,6 +360,11 @@ static int flag_demangled_names = 0;
 
 static int flag_long_names = 0;
 
+/* For situations when a long name can potentially hit filesystem path limit,
+   let's calculate md5sum of the patch and create file x.gcov##md5sum.gcov.  */
+
+static int flag_hash_names = 0;
+
 /* Output count information for every basic block, not merely those
    that contain line number information.  */
 
@@ -655,6 +661,8 @@ print_usage (int error_p)
   fnotice (file, "  -c, --branch-counts             Output counts of branches taken\n\
                                     rather than percentages\n");
   fnotice (file, "  -d, --display-progress          Display progress information\n");
+  fnotice (file, "  -e, --hash-names                Use hash of file path in "
+	   "file names\n");
   fnotice (file, "  -f, --function-summaries        Output summaries for each function\n");
   fnotice (file, "  -i, --intermediate-format       Output .gcov file in intermediate text format\n");
   fnotice (file, "  -l, --long-file-names           Use long output file names for included\n\
@@ -694,6 +702,7 @@ static const struct option options[] =
   { "all-blocks",           no_argument,       NULL, 'a' },
   { "branch-probabilities", no_argument,       NULL, 'b' },
   { "branch-counts",        no_argument,       NULL, 'c' },
+  { "long-file-names",      no_argument,       NULL, 'e' },
   { "intermediate-format",  no_argument,       NULL, 'i' },
   { "no-output",            no_argument,       NULL, 'n' },
   { "long-file-names",      no_argument,       NULL, 'l' },
@@ -716,8 +725,8 @@ process_args (int argc, char **argv)
 {
   int opt;
 
-  while ((opt = getopt_long (argc, argv, "abcdfhilmno:s:pruv", options, NULL)) !=
-         -1)
+  const char *opts = "abcdefhilmno:s:pruv";
+  while ((opt = getopt_long (argc, argv, opts, options, NULL)) != -1)
     {
       switch (opt)
 	{
@@ -730,6 +739,9 @@ process_args (int argc, char **argv)
 	case 'c':
 	  flag_counts = 1;
 	  break;
+	case 'e':
+	  flag_hash_names = 1;
+	  break;
 	case 'f':
 	  flag_function_summary = 1;
 	  break;
@@ -2147,6 +2159,15 @@ canonicalize_name (const char *name)
   return result;
 }
 
+/* Print hex representation of 16 bytes from SUM and write it to BUFFER.  */
+
+static void
+md5sum_to_hex (const char *sum, char *buffer)
+{
+  for (unsigned i = 0; i < 16; i++)
+    sprintf (buffer + (2 * i), "%02x", sum[i]);
+}
+
 /* Generate an output file name. INPUT_NAME is the canonicalized main
    input file and SRC_NAME is the canonicalized file name.
    LONG_OUTPUT_NAMES and PRESERVE_PATHS affect name generation.  With
@@ -2184,6 +2205,28 @@ make_gcov_file_name (const char *input_name, const char *src_name)
   ptr = mangle_name (src_name, ptr);
   strcpy (ptr, ".gcov");
 
+  if (flag_hash_names)
+    {
+      md5_ctx ctx;
+      char md5sum[16];
+      char md5sum_hex[33];
+
+      md5_init_ctx (&ctx);
+      md5_process_bytes (result, strlen (result), &ctx);
+      md5_finish_ctx (&ctx, md5sum);
+      md5sum_to_hex (md5sum, md5sum_hex);
+      free (result);
+
+      result = XNEWVEC (char, strlen (src_name) + 50);
+      ptr = result;
+      ptr = mangle_name (src_name, ptr);
+      ptr[0] = ptr[1] = '#';
+      ptr += 2;
+      memcpy (ptr, md5sum_hex, 32);
+      ptr += 32;
+      strcpy (ptr, ".gcov");
+    }
+
   return result;
 }
 
-- 
2.9.2

Reply via email to