diff options
Diffstat (limited to 'compiler-rt/lib/profile/InstrProfilingExtras.c')
| -rw-r--r-- | compiler-rt/lib/profile/InstrProfilingExtras.c | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/compiler-rt/lib/profile/InstrProfilingExtras.c b/compiler-rt/lib/profile/InstrProfilingExtras.c index 87006e8900c..bf727068050 100644 --- a/compiler-rt/lib/profile/InstrProfilingExtras.c +++ b/compiler-rt/lib/profile/InstrProfilingExtras.c @@ -8,6 +8,7 @@ \*===----------------------------------------------------------------------===*/ #include "InstrProfiling.h" +#include <string.h> static void __llvm_profile_write_file_with_name(const char *OutputName) { FILE *OutputFile; @@ -29,16 +30,60 @@ void __llvm_profile_set_filename(const char *Filename) { CurrentFilename = Filename; } +int getpid(void); void __llvm_profile_write_file(void) { - const char *Filename = CurrentFilename; + char *AllocatedFilename = NULL; + int I, J; + +#define MAX_PID_SIZE 16 + char PidChars[MAX_PID_SIZE] = { 0 }; + int PidLength = 0; + int NumPids = 0; + // Get the filename. + const char *Filename = CurrentFilename; #define UPDATE_FILENAME(NextFilename) \ if (!Filename || !Filename[0]) Filename = NextFilename UPDATE_FILENAME(getenv("LLVM_PROFILE_FILE")); UPDATE_FILENAME("default.profdata"); #undef UPDATE_FILENAME + // Check the filename for "%p", which indicates a pid-substitution. + for (I = 0; Filename[I]; ++I) + if (Filename[I] == '%' && Filename[++I] == 'p') + if (!NumPids++) { + PidLength = snprintf(PidChars, MAX_PID_SIZE, "%d", getpid()); + if (PidLength <= 0) + return; + } + if (NumPids) { + // Allocate enough space for the substituted filename. + AllocatedFilename = (char*)malloc(I + NumPids*(PidLength - 2) + 1); + if (!AllocatedFilename) + return; + + // Construct the new filename. + for (I = 0, J = 0; Filename[I]; ++I) + if (Filename[I] == '%') { + if (Filename[++I] == 'p') { + memcpy(AllocatedFilename + J, PidChars, PidLength); + J += PidLength; + } + // Drop any unknown substitutions. + } else + AllocatedFilename[J++] = Filename[I]; + AllocatedFilename[J] = 0; + + // Actually use the computed name. + Filename = AllocatedFilename; + } + + // Write the file. __llvm_profile_write_file_with_name(Filename); + + // Free the filename. + if (AllocatedFilename) + free(AllocatedFilename); } void __llvm_profile_register_write_file_atexit(void) { |

