[Profile] track ownership of filename pattern string

Make sure runtime copy and owns the string when passed
in from external users of runtime API.

llvm-svn: 277507
diff --git a/compiler-rt/lib/profile/InstrProfilingFile.c b/compiler-rt/lib/profile/InstrProfilingFile.c
index 6b4b9cd..70953ac 100644
--- a/compiler-rt/lib/profile/InstrProfilingFile.c
+++ b/compiler-rt/lib/profile/InstrProfilingFile.c
@@ -63,6 +63,9 @@
 typedef struct lprofFilename {
   /* File name string possibly with %p or %h specifiers. */
   const char *FilenamePat;
+  /* A flag indicating if FilenamePat's memory is allocated
+   * by runtime. */
+  unsigned OwnsFilenamePat;
   const char *ProfilePathPrefix;
   char PidChars[MAX_PID_SIZE];
   char Hostname[COMPILER_RT_MAX_HOSTLEN];
@@ -79,7 +82,7 @@
   ProfileNameSpecifier PNS;
 } lprofFilename;
 
-lprofFilename lprofCurFilename = {0, 0, {0}, {0}, 0, 0, 0, PNS_unknown};
+lprofFilename lprofCurFilename = {0, 0, 0, {0}, {0}, 0, 0, 0, PNS_unknown};
 
 int getpid(void);
 static int getCurFilenameLength();
@@ -250,6 +253,9 @@
 
 static const char *DefaultProfileName = "default.profraw";
 static void resetFilenameToDefault(void) {
+  if (lprofCurFilename.FilenamePat && lprofCurFilename.OwnsFilenamePat) {
+    free((void *)lprofCurFilename.FilenamePat);
+  }
   memset(&lprofCurFilename, 0, sizeof(lprofCurFilename));
   lprofCurFilename.FilenamePat = DefaultProfileName;
   lprofCurFilename.PNS = PNS_default;
@@ -265,7 +271,8 @@
 
 /* Parses the pattern string \p FilenamePat and stores the result to
  * lprofcurFilename structure. */
-static int parseFilenamePattern(const char *FilenamePat) {
+static int parseFilenamePattern(const char *FilenamePat,
+                                unsigned CopyFilenamePat) {
   int NumPids = 0, NumHosts = 0, I;
   char *PidChars = &lprofCurFilename.PidChars[0];
   char *Hostname = &lprofCurFilename.Hostname[0];
@@ -276,7 +283,16 @@
     free((void *)lprofCurFilename.ProfilePathPrefix);
   memset(&lprofCurFilename, 0, sizeof(lprofCurFilename));
 
-  lprofCurFilename.FilenamePat = FilenamePat;
+  if (lprofCurFilename.FilenamePat && lprofCurFilename.OwnsFilenamePat) {
+    free((void *)lprofCurFilename.FilenamePat);
+  }
+
+  if (!CopyFilenamePat)
+    lprofCurFilename.FilenamePat = FilenamePat;
+  else {
+    lprofCurFilename.FilenamePat = strdup(FilenamePat);
+    lprofCurFilename.OwnsFilenamePat = 1;
+  }
   /* Check the filename for "%p", which indicates a pid-substitution. */
   for (I = 0; FilenamePat[I]; ++I)
     if (FilenamePat[I] == '%') {
@@ -319,7 +335,8 @@
 }
 
 static void parseAndSetFilename(const char *FilenamePat,
-                                ProfileNameSpecifier PNS) {
+                                ProfileNameSpecifier PNS,
+                                unsigned CopyFilenamePat) {
 
   const char *OldFilenamePat = lprofCurFilename.FilenamePat;
   ProfileNameSpecifier OldPNS = lprofCurFilename.PNS;
@@ -336,7 +353,7 @@
   }
 
   /* When PNS >= OldPNS, the last one wins. */
-  if (!FilenamePat || parseFilenamePattern(FilenamePat))
+  if (!FilenamePat || parseFilenamePattern(FilenamePat, CopyFilenamePat))
     resetFilenameToDefault();
   lprofCurFilename.PNS = PNS;
 
@@ -483,7 +500,7 @@
     PNS = PNS_default;
   }
 
-  parseAndSetFilename(SelectedPat, PNS);
+  parseAndSetFilename(SelectedPat, PNS, 0);
 }
 
 /* This API is directly called by the user application code. It has the
@@ -492,7 +509,7 @@
  */
 COMPILER_RT_VISIBILITY
 void __llvm_profile_set_filename(const char *FilenamePat) {
-  parseAndSetFilename(FilenamePat, PNS_runtime_api);
+  parseAndSetFilename(FilenamePat, PNS_runtime_api, 1);
 }
 
 /* The public API for writing profile data into the file with name