diff options
-rw-r--r-- | SDKs/darwin/usr/include/stdio.h | 13 | ||||
-rw-r--r-- | lib/profile/GCDAProfiling.c | 96 |
2 files changed, 93 insertions, 16 deletions
diff --git a/SDKs/darwin/usr/include/stdio.h b/SDKs/darwin/usr/include/stdio.h index 3b560369f..744138806 100644 --- a/SDKs/darwin/usr/include/stdio.h +++ b/SDKs/darwin/usr/include/stdio.h @@ -51,11 +51,24 @@ typedef __SIZE_TYPE__ size_t; # define stderr __stderrp extern FILE *__stderrp; +#ifndef SEEK_SET +#define SEEK_SET 0 /* set file offset to offset */ +#endif +#ifndef SEEK_CUR +#define SEEK_CUR 1 /* set file offset to current plus offset */ +#endif +#ifndef SEEK_END +#define SEEK_END 2 /* set file offset to EOF plus offset */ +#endif + int fclose(FILE *); int fflush(FILE *); FILE *fopen(const char * restrict, const char * restrict) __asm(__FOPEN_NAME); int fprintf(FILE * restrict, const char * restrict, ...); size_t fwrite(const void * restrict, size_t, size_t, FILE * restrict) __asm(__FWRITE_NAME); +size_t fread(void * __restrict, size_t, size_t, FILE * __restrict); +long ftell(FILE *); +int fseek(FILE *, long, int); #endif /* __STDIO_H__ */ diff --git a/lib/profile/GCDAProfiling.c b/lib/profile/GCDAProfiling.c index 8f92a9154..ba2e12aeb 100644 --- a/lib/profile/GCDAProfiling.c +++ b/lib/profile/GCDAProfiling.c @@ -66,6 +66,24 @@ static void write_string(const char *s) { fwrite("\0\0\0\0", 4 - (strlen(s) % 4), 1, output_file); } +static uint32_t read_int32() { + uint32_t tmp; + + if (fread(&tmp, 1, 4, output_file) != 4) + return (uint32_t)-1; + + return tmp; +} + +static uint64_t read_int64() { + uint64_t tmp; + + if (fread(&tmp, 1, 8, output_file) != 8) + return (uint64_t)-1; + + return tmp; +} + static char *mangle_filename(const char *orig_filename) { char *filename = 0; int prefix_len = 0; @@ -129,15 +147,24 @@ static void recursive_mkdir(char *filename) { */ void llvm_gcda_start_file(const char *orig_filename) { char *filename = mangle_filename(orig_filename); - output_file = fopen(filename, "w+b"); + char buffer[13]; + + /* Try just opening the file. */ + output_file = fopen(filename, "r+b"); if (!output_file) { - recursive_mkdir(filename); + /* Try opening the file, creating it if necessary. */ output_file = fopen(filename, "w+b"); if (!output_file) { - fprintf(stderr, "profiling:%s: cannot open\n", filename); - free(filename); - return; + /* Try creating the directories first then opening the file. */ + recursive_mkdir(filename); + output_file = fopen(filename, "w+b"); + if (!output_file) { + /* Bah! It's hopeless. */ + fprintf(stderr, "profiling:%s: cannot open\n", filename); + free(filename); + return; + } } } @@ -148,11 +175,11 @@ void llvm_gcda_start_file(const char *orig_filename) { fwrite("adcg*404MVLL", 12, 1, output_file); #endif + free(filename); + #ifdef DEBUG_GCDAPROFILING - printf("llvmgcda: [%s]\n", orig_filename); + fprintf(stderr, "llvmgcda: [%s]\n", orig_filename); #endif - - free(filename); } /* Given an array of pointers to counters (counters), increment the n-th one, @@ -175,14 +202,14 @@ void llvm_gcda_increment_indirect_counter(uint32_t *predecessor, #ifdef DEBUG_GCDAPROFILING else fprintf(stderr, - "llvmgcda: increment_indirect_counter counters=%x, pred=%u\n", - state_table_row, *predecessor); + "llvmgcda: increment_indirect_counter counters=%08llx, pred=%u\n", + *counter, *predecessor); #endif } void llvm_gcda_emit_function(uint32_t ident, const char *function_name) { #ifdef DEBUG_GCDAPROFILING - printf("llvmgcda: function id=%x\n", ident); + fprintf(stderr, "llvmgcda: function id=0x%08x\n", ident); #endif if (!output_file) return; @@ -197,18 +224,55 @@ 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; + uint64_t *old_ctrs = NULL; + uint32_t val = 0; + long pos = 0; - /* Counter #1 (arcs) tag */ if (!output_file) return; + + pos = ftell(output_file); + val = read_int32(); + + fprintf(stderr, "Read: 0x%08x\n", val); + + if (val != (uint32_t)-1) { + /* There are counters present in the file. Merge them. */ + uint32_t j; + + if (val != 0x01a10000) { + fprintf(stderr, "profiling: invalid magic number (0x%08x)\n", val); + return; + } + + val = read_int32(); + if (val == (uint32_t)-1 || val / 2 != num_counters) { + fprintf(stderr, "profiling: invalid number of counters (%d)\n", val); + return; + } + + old_ctrs = malloc(sizeof(uint64_t) * num_counters); + + for (j = 0; j < num_counters; ++j) { + old_ctrs[j] = read_int64(); + fprintf(stderr, "old counter[%d]: %lld\n", j, old_ctrs[j]); + } + } + + /* Reset for writing. */ + fseek(output_file, pos, SEEK_SET); + + /* Counter #1 (arcs) tag */ fwrite("\0\0\xa1\1", 4, 1, output_file); write_int32(num_counters * 2); for (i = 0; i < num_counters; ++i) - write_int64(counters[i]); + write_int64(counters[i] + (old_ctrs ? old_ctrs[i] : 0)); + + free(old_ctrs); #ifdef DEBUG_GCDAPROFILING - printf("llvmgcda: %u arcs\n", num_counters); + fprintf(stderr, "llvmgcda: %u arcs\n", num_counters); for (i = 0; i < num_counters; ++i) - printf("llvmgcda: %llu\n", (unsigned long long)counters[i]); + fprintf(stderr, "llvmgcda: %llu\n", (unsigned long long)counters[i]); #endif } @@ -220,6 +284,6 @@ void llvm_gcda_end_file() { output_file = NULL; #ifdef DEBUG_GCDAPROFILING - printf("llvmgcda: -----\n"); + fprintf(stderr, "llvmgcda: -----\n"); #endif } |