1 /*===-- CommonProfiling.c - Profiling support library support -------------===*\
3 |* The LLVM Compiler Infrastructure
5 |* This file is distributed under the University of Illinois Open Source
6 |* License. See LICENSE.TXT for details.
8 |*===----------------------------------------------------------------------===*|
10 |* This file implements functions used by the various different types of
11 |* profiling implementations.
13 \*===----------------------------------------------------------------------===*/
15 #include "Profiling.h"
17 #include <sys/types.h>
25 static char *SavedArgs
= 0;
26 static unsigned SavedArgsLength
= 0;
28 static const char *OutputFilename
= "llvmprof.out";
30 /* save_arguments - Save argc and argv as passed into the program for the file
33 int save_arguments(int argc
, const char **argv
) {
35 if (SavedArgs
|| !argv
) return argc
; /* This can be called multiple times */
37 /* Check to see if there are any arguments passed into the program for the
38 * profiler. If there are, strip them off and remember their settings.
40 while (argc
> 1 && !strncmp(argv
[1], "-llvmprof-", 10)) {
41 /* Ok, we have an llvmprof argument. Remove it from the arg list and decide
44 const char *Arg
= argv
[1];
45 memmove(&argv
[1], &argv
[2], (argc
-1)*sizeof(char*));
48 if (!strcmp(Arg
, "-llvmprof-output")) {
50 puts("-llvmprof-output requires a filename argument!");
52 OutputFilename
= strdup(argv
[1]);
53 memmove(&argv
[1], &argv
[2], (argc
-1)*sizeof(char*));
57 printf("Unknown option to the profiler runtime: '%s' - ignored.\n", Arg
);
61 for (Length
= 0, i
= 0; i
!= (unsigned)argc
; ++i
)
62 Length
+= strlen(argv
[i
])+1;
64 SavedArgs
= (char*)malloc(Length
);
65 for (Length
= 0, i
= 0; i
!= (unsigned)argc
; ++i
) {
66 unsigned Len
= strlen(argv
[i
]);
67 memcpy(SavedArgs
+Length
, argv
[i
], Len
);
69 SavedArgs
[Length
++] = ' ';
72 SavedArgsLength
= Length
;
79 * Retrieves the file descriptor for the profile file.
82 static int OutFile
= -1;
84 /* If this is the first time this function is called, open the output file
85 * for appending, creating it if it does not already exist.
88 OutFile
= open(OutputFilename
, O_CREAT
| O_WRONLY
, 0666);
89 lseek(OutFile
, 0, SEEK_END
); /* O_APPEND prevents seeking */
91 fprintf(stderr
, "LLVM profiling runtime: while opening '%s': ",
97 /* Output the command line arguments to the file. */
99 int PTy
= ArgumentInfo
;
101 write(OutFile
, &PTy
, sizeof(int));
102 write(OutFile
, &SavedArgsLength
, sizeof(unsigned));
103 write(OutFile
, SavedArgs
, SavedArgsLength
);
104 /* Pad out to a multiple of four bytes */
105 if (SavedArgsLength
& 3)
106 write(OutFile
, &Zeros
, 4-(SavedArgsLength
&3));
112 /* write_profiling_data - Write a raw block of profiling counters out to the
113 * llvmprof.out file. Note that we allow programs to be instrumented with
114 * multiple different kinds of instrumentation. For this reason, this function
115 * may be called more than once.
117 void write_profiling_data(enum ProfilingType PT
, unsigned *Start
,
118 unsigned NumElements
) {
120 int outFile
= getOutFile();
122 /* Write out this record! */
124 if( write(outFile
, &PTy
, sizeof(int)) < 0 ||
125 write(outFile
, &NumElements
, sizeof(unsigned)) < 0 ||
126 write(outFile
, Start
, NumElements
*sizeof(unsigned)) < 0 ) {
127 fprintf(stderr
,"error: unable to write to output file.");