summaryrefslogtreecommitdiffstats
path: root/lib/profile/GCDAProfiling.c
diff options
context:
space:
mode:
authorandrew <andrew@FreeBSD.org>2012-07-30 10:58:13 +0000
committerandrew <andrew@FreeBSD.org>2012-07-30 10:58:13 +0000
commitcfeab007a554034f0b3ab4a677cf9dd2696c12f9 (patch)
tree40cc44a3d02ed86de24f2117a55680e4f0eb01a0 /lib/profile/GCDAProfiling.c
parent07af089f1449ec5506ca7ede5b593e11a0f48603 (diff)
downloadFreeBSD-src-cfeab007a554034f0b3ab4a677cf9dd2696c12f9.zip
FreeBSD-src-cfeab007a554034f0b3ab4a677cf9dd2696c12f9.tar.gz
Import compiler-rt r160957.
Diffstat (limited to 'lib/profile/GCDAProfiling.c')
-rw-r--r--lib/profile/GCDAProfiling.c93
1 files changed, 59 insertions, 34 deletions
diff --git a/lib/profile/GCDAProfiling.c b/lib/profile/GCDAProfiling.c
index fd506e9..8f92a91 100644
--- a/lib/profile/GCDAProfiling.c
+++ b/lib/profile/GCDAProfiling.c
@@ -49,10 +49,8 @@ static void write_int32(uint32_t i) {
}
static void write_int64(uint64_t i) {
- uint32_t lo, hi;
- lo = i >> 0;
- hi = i >> 32;
-
+ uint32_t lo = i >> 0;
+ uint32_t hi = i >> 32;
write_int32(lo);
write_int32(hi);
}
@@ -69,39 +67,55 @@ static void write_string(const char *s) {
}
static char *mangle_filename(const char *orig_filename) {
- /* TODO: handle GCOV_PREFIX_STRIP */
- const char *prefix;
char *filename = 0;
-
- prefix = getenv("GCOV_PREFIX");
+ int prefix_len = 0;
+ int prefix_strip = 0;
+ int level = 0;
+ const char *fname = orig_filename, *ptr = NULL;
+ const char *prefix = getenv("GCOV_PREFIX");
+ const char *tmp = getenv("GCOV_PREFIX_STRIP");
if (!prefix)
return strdup(orig_filename);
- filename = malloc(strlen(prefix) + 1 + strlen(orig_filename) + 1);
+ if (tmp) {
+ prefix_strip = atoi(tmp);
+
+ /* Negative GCOV_PREFIX_STRIP values are ignored */
+ if (prefix_strip < 0)
+ prefix_strip = 0;
+ }
+
+ prefix_len = strlen(prefix);
+ filename = malloc(prefix_len + 1 + strlen(orig_filename) + 1);
strcpy(filename, prefix);
- strcat(filename, "/");
- strcat(filename, orig_filename);
+
+ if (prefix[prefix_len - 1] != '/')
+ strcat(filename, "/");
+
+ for (ptr = fname + 1; *ptr != '\0' && level < prefix_strip; ++ptr) {
+ if (*ptr != '/') continue;
+ fname = ptr;
+ ++level;
+ }
+
+ strcat(filename, fname);
return filename;
}
-static void recursive_mkdir(const char *filename) {
- char *pathname;
- int i, e;
+static void recursive_mkdir(char *filename) {
+ int i;
- for (i = 1, e = strlen(filename); i != e; ++i) {
- if (filename[i] == '/') {
- pathname = malloc(i + 1);
- strncpy(pathname, filename, i);
- pathname[i] = '\0';
+ for (i = 1; filename[i] != '\0'; ++i) {
+ if (filename[i] != '/') continue;
+ filename[i] = '\0';
#ifdef _WIN32
- _mkdir(pathname);
+ _mkdir(filename);
#else
- mkdir(pathname, 0750); /* some of these will fail, ignore it. */
+ mkdir(filename, 0755); /* Some of these will fail, ignore it. */
#endif
- free(pathname);
- }
+ filename[i] = '/';
}
}
@@ -114,10 +128,18 @@ static void recursive_mkdir(const char *filename) {
* started at a time.
*/
void llvm_gcda_start_file(const char *orig_filename) {
- char *filename;
- filename = mangle_filename(orig_filename);
- recursive_mkdir(filename);
- output_file = fopen(filename, "wb");
+ char *filename = mangle_filename(orig_filename);
+ output_file = fopen(filename, "w+b");
+
+ if (!output_file) {
+ recursive_mkdir(filename);
+ output_file = fopen(filename, "w+b");
+ if (!output_file) {
+ fprintf(stderr, "profiling:%s: cannot open\n", filename);
+ free(filename);
+ return;
+ }
+ }
/* gcda file, version 404*, stamp LLVM. */
#ifdef __APPLE__
@@ -152,8 +174,9 @@ void llvm_gcda_increment_indirect_counter(uint32_t *predecessor,
++*counter;
#ifdef DEBUG_GCDAPROFILING
else
- printf("llvmgcda: increment_indirect_counter counters=%x, pred=%u\n",
- state_table_row, *predecessor);
+ fprintf(stderr,
+ "llvmgcda: increment_indirect_counter counters=%x, pred=%u\n",
+ state_table_row, *predecessor);
#endif
}
@@ -161,6 +184,7 @@ void llvm_gcda_emit_function(uint32_t ident, const char *function_name) {
#ifdef DEBUG_GCDAPROFILING
printf("llvmgcda: function id=%x\n", ident);
#endif
+ if (!output_file) return;
/* function tag */
fwrite("\0\0\0\1", 4, 1, output_file);
@@ -173,23 +197,24 @@ void llvm_gcda_emit_function(uint32_t ident, const char *function_name) {
void llvm_gcda_emit_arcs(uint32_t num_counters, uint64_t *counters) {
uint32_t i;
- /* counter #1 (arcs) tag */
+
+ /* Counter #1 (arcs) tag */
+ if (!output_file) return;
fwrite("\0\0\xa1\1", 4, 1, output_file);
write_int32(num_counters * 2);
- for (i = 0; i < num_counters; ++i) {
+ for (i = 0; i < num_counters; ++i)
write_int64(counters[i]);
- }
#ifdef DEBUG_GCDAPROFILING
printf("llvmgcda: %u arcs\n", num_counters);
- for (i = 0; i < num_counters; ++i) {
+ for (i = 0; i < num_counters; ++i)
printf("llvmgcda: %llu\n", (unsigned long long)counters[i]);
- }
#endif
}
void llvm_gcda_end_file() {
/* Write out EOF record. */
+ if (!output_file) return;
fwrite("\0\0\0\0\0\0\0\0", 8, 1, output_file);
fclose(output_file);
output_file = NULL;
OpenPOWER on IntegriCloud