gcov: add new option (--hash-filenames) (PR
authorMartin Liska <mliska@suse.cz>
Tue, 16 Aug 2016 14:14:18 +0000 (16:14 +0200)
committerMartin Liska <marxin@gcc.gnu.org>
Tue, 16 Aug 2016 14:14:18 +0000 (14:14 +0000)
PR gcov-profile/36412
* doc/gcov.texi: Document --hash-filenames(-x).
* gcov.c (print_usage): Add the option.
(process_args): Process the option, sort options alphabetically.
(md5sum_to_hex): New function.
(make_gcov_file_name): Do the md5sum and append it to a
filename.

From-SVN: r239503

gcc/ChangeLog
gcc/doc/gcov.texi
gcc/gcov.c

index e2d39a8792d156d0f4926058d898f583e658ea4a..df133208b2c90b720df26d504ad1f42e62f1811e 100644 (file)
@@ -1,3 +1,13 @@
+2016-08-16  Martin Liska  <mliska@suse.cz>
+
+       PR gcov-profile/36412
+       * doc/gcov.texi: Document --hash-filenames(-x).
+       * gcov.c (print_usage): Add the option.
+       (process_args): Process the option, sort options alphabetically.
+       (md5sum_to_hex): New function.
+       (make_gcov_file_name): Do the md5sum and append it to a
+       filename.
+
 2016-08-16  Bin Cheng  <bin.cheng@arm.com>
 
        PR tree-optimization/69848
index df58df8ab61a33c0c99987322dd7f962a52893a6..a0a7af78900b4db8bd3e1fe135759f6d9c4526fc 100644 (file)
@@ -133,6 +133,7 @@ gcov [@option{-v}|@option{--version}] [@option{-h}|@option{--help}]
      [@option{-r}|@option{--relative-only}]
      [@option{-s}|@option{--source-prefix} @var{directory}]
      [@option{-u}|@option{--unconditional-branches}]
+     [@option{-x}|@option{--hash-filenames}]
      @var{files}
 @c man end
 @c man begin SEEALSO
@@ -278,6 +279,16 @@ branch:28,nottaken
 Display demangled function names in output. The default is to show
 mangled function names.
 
+@item -x
+@itemx --hash-filenames
+By default, gcov uses the full pathname of the source files to to create
+an output filename.  This can lead to long filenames that can overflow
+filesystem limits.  This option creates names of the form
+@file{@var{source-file}##@var{md5}.gcov},
+where the @var{source-file} component is the final filename part and
+the @var{md5} component is calculated from the full mangled name that
+would have been used otherwise.
+
 @end table
 
 @command{gcov} should be run with the current directory the same as that
index 30fc167a0b34436e7954f8a7ea1dbd334fd90e95..da0bc9777afe1b16da498a6885bf1060ba078851 100644 (file)
@@ -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 path and append it to a file name.  */
+
+static int flag_hash_filenames = 0;
+
 /* Output count information for every basic block, not merely those
    that contain line number information.  */
 
@@ -667,6 +673,7 @@ print_usage (int error_p)
   fnotice (file, "  -s, --source-prefix DIR         Source prefix to elide\n");
   fnotice (file, "  -u, --unconditional-branches    Show unconditional branch counts too\n");
   fnotice (file, "  -v, --version                   Print version number, then exit\n");
+  fnotice (file, "  -x, --hash-filenames            Hash long pathnames\n");
   fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n",
           bug_report_url);
   exit (status);
@@ -706,6 +713,7 @@ static const struct option options[] =
   { "source-prefix",        required_argument, NULL, 's' },
   { "unconditional-branches", no_argument,     NULL, 'u' },
   { "display-progress",     no_argument,       NULL, 'd' },
+  { "hash-filenames",      no_argument,       NULL, 'x' },
   { 0, 0, 0, 0 }
 };
 
@@ -716,8 +724,8 @@ process_args (int argc, char **argv)
 {
   int opt;
 
-  while ((opt = getopt_long (argc, argv, "abcdfhilmno:s:pruv", options, NULL)) !=
-         -1)
+  const char *opts = "abcdfhilmno:prs:uvx";
+  while ((opt = getopt_long (argc, argv, opts, options, NULL)) != -1)
     {
       switch (opt)
        {
@@ -770,6 +778,9 @@ process_args (int argc, char **argv)
           break;
        case 'v':
          print_version ();
+       case 'x':
+         flag_hash_filenames = 1;
+         break;
          /* print_version will exit.  */
        default:
          print_usage (true);
@@ -2147,6 +2158,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 +2204,30 @@ make_gcov_file_name (const char *input_name, const char *src_name)
   ptr = mangle_name (src_name, ptr);
   strcpy (ptr, ".gcov");
 
+  /* When hashing filenames, we shorten them by only using the filename
+     component and appending a hash of the full (mangled) pathname.  */
+  if (flag_hash_filenames)
+    {
+      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;
 }