When using -fprofile-generate=/some/path mangle absolute path of file (PR lto/85759).
authorMartin Liska <mliska@suse.cz>
Fri, 29 Jun 2018 14:03:36 +0000 (16:03 +0200)
committerMartin Liska <marxin@gcc.gnu.org>
Fri, 29 Jun 2018 14:03:36 +0000 (14:03 +0000)
2018-06-29  Martin Liska  <mliska@suse.cz>

PR lto/85759
* coverage.c (coverage_init): Mangle full path name.
* doc/invoke.texi: Document the change.
* gcov-io.c (mangle_path): New.
* gcov-io.h (mangle_path): Likewise.
* gcov.c (mangle_name): Use mangle_path for path mangling.

From-SVN: r262251

gcc/ChangeLog
gcc/coverage.c
gcc/doc/invoke.texi
gcc/gcov-io.c
gcc/gcov-io.h
gcc/gcov.c

index a76fea967828ee21a6b653af926790ac2859b8b7..a0da66e69324210c02b401d1952004bb5b55a747 100644 (file)
@@ -1,3 +1,12 @@
+2018-06-29  Martin Liska  <mliska@suse.cz>
+
+       PR lto/85759
+       * coverage.c (coverage_init): Mangle full path name.
+       * doc/invoke.texi: Document the change.
+       * gcov-io.c (mangle_path): New.
+       * gcov-io.h (mangle_path): Likewise.
+       * gcov.c (mangle_name): Use mangle_path for path mangling.
+
 2018-06-29  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        * config/arm/arm.c (output_move_double): Don't allow STRD instructions
index 350cc4559c5caea387269b66cea8655995851eae..9c9d3dbd39e96554f7cdecf281f3b59f703ea2db 100644 (file)
@@ -1220,8 +1220,24 @@ coverage_init (const char *filename)
     g->get_passes ()->get_pass_profile ()->static_pass_number;
   g->get_dumps ()->dump_start (profile_pass_num, NULL);
 
-  if (!profile_data_prefix && !IS_ABSOLUTE_PATH (filename))
-    profile_data_prefix = getpwd ();
+  if (!IS_ABSOLUTE_PATH (filename))
+    {
+      /* When a profile_data_prefix is provided, then mangle full path
+        of filename in order to prevent file path clashing.  */
+      if (profile_data_prefix)
+       {
+#if HAVE_DOS_BASED_FILE_SYSTEM
+         const char separator = "\\";
+#else
+         const char *separator = "/";
+#endif
+         filename = concat (getpwd (), separator, filename, NULL);
+         filename = mangle_path (filename);
+         len = strlen (filename);
+       }
+      else
+       profile_data_prefix = getpwd ();
+    }
 
   if (profile_data_prefix)
     prefix_len = strlen (profile_data_prefix);
index 248e6039722c2f8351c29871f826259cfdf20437..0180bec183e5586a48f520f6a0003df7e2ccbef5 100644 (file)
@@ -11352,6 +11352,9 @@ and used by @option{-fprofile-use} and @option{-fbranch-probabilities}
 and its related options.  Both absolute and relative paths can be used.
 By default, GCC uses the current directory as @var{path}, thus the
 profile data file appears in the same directory as the object file.
+In order to prevent filename clashing, if object file name is not an absolute
+path, we mangle absolute path of @file{@var{sourcename}.gcda} file and
+use it as file name of a @file{.gcda} file.
 
 When an executable is run in a massive parallel environment, it is recommended
 to save profile to different folders.  That can be done with variables
index e07ae76420bf321984023ad5b6449fdd23f95c5d..311e4d014bf4ac339f0608c4e001f91e46ed74c9 100644 (file)
@@ -566,6 +566,55 @@ gcov_read_counter (void)
   return value;
 }
 
+/* Mangle filename path of BASE and output new allocated pointer with
+   mangled path.  */
+
+char *
+mangle_path (char const *base)
+{
+  /* Convert '/' to '#', convert '..' to '^',
+     convert ':' to '~' on DOS based file system.  */
+  const char *probe;
+  char *buffer = (char *)xmalloc (strlen (base) + 10);
+  char *ptr = buffer;
+
+#if HAVE_DOS_BASED_FILE_SYSTEM
+  if (base[0] && base[1] == ':')
+    {
+      ptr[0] = base[0];
+      ptr[1] = '~';
+      ptr += 2;
+      base += 2;
+    }
+#endif
+  for (; *base; base = probe)
+    {
+      size_t len;
+
+      for (probe = base; *probe; probe++)
+       if (*probe == '/')
+         break;
+      len = probe - base;
+      if (len == 2 && base[0] == '.' && base[1] == '.')
+       *ptr++ = '^';
+      else
+       {
+         memcpy (ptr, base, len);
+         ptr += len;
+       }
+      if (*probe)
+       {
+         *ptr++ = '#';
+         probe++;
+       }
+    }
+
+  /* Terminate the string.  */
+  *ptr = '\0';
+
+  return buffer;
+}
+
 /* We need to expose the below function when compiling for gcov-tool.  */
 
 #if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
index 56391defab36be0173d6f4c23c99bb927625db88..7a11f0aec7f00cf0a92d887c8d802cf430cbc04c 100644 (file)
@@ -371,6 +371,7 @@ GCOV_LINKAGE void gcov_read_summary (struct gcov_summary *) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE const char *gcov_read_string (void);
 GCOV_LINKAGE void gcov_sync (gcov_position_t /*base*/,
                             gcov_unsigned_t /*length */);
+char *mangle_path (char const *base);
 
 #if !IN_GCOV
 /* Available outside gcov */
index 2114a43d14082171783fa3db00f0d574807004d0..ad2de4d5b22206a439d1a1671e776e7fe36b15e5 100644 (file)
@@ -2461,42 +2461,7 @@ mangle_name (char const *base, char *ptr)
       ptr += len;
     }
   else
-    {
-      /* Convert '/' to '#', convert '..' to '^',
-        convert ':' to '~' on DOS based file system.  */
-      const char *probe;
-
-#if HAVE_DOS_BASED_FILE_SYSTEM
-      if (base[0] && base[1] == ':')
-       {
-         ptr[0] = base[0];
-         ptr[1] = '~';
-         ptr += 2;
-         base += 2;
-       }
-#endif
-      for (; *base; base = probe)
-       {
-         size_t len;
-
-         for (probe = base; *probe; probe++)
-           if (*probe == '/')
-             break;
-         len = probe - base;
-         if (len == 2 && base[0] == '.' && base[1] == '.')
-           *ptr++ = '^';
-         else
-           {
-             memcpy (ptr, base, len);
-             ptr += len;
-           }
-         if (*probe)
-           {
-             *ptr++ = '#';
-             probe++;
-           }
-       }
-    }
+    ptr = mangle_path (base);
 
   return ptr;
 }