Write and read FIRM profiling information in little-endian format.
authorManuel Mohr <manuel.mohr@kit.edu>
Mon, 5 Dec 2011 11:59:35 +0000 (12:59 +0100)
committerManuel Mohr <manuel.mohr@kit.edu>
Mon, 5 Dec 2011 12:05:00 +0000 (13:05 +0100)
ir/ir/irprofile.c
support/libfirmprof/instrument.c

index e16b70a..352455c 100644 (file)
@@ -510,8 +510,9 @@ static unsigned int *
 parse_profile(const char *filename, unsigned int num_blocks)
 {
        unsigned int *result = NULL;
-       char buf[8];
-       size_t ret;
+       char          buf[8];
+       size_t        ret;
+       unsigned int  i;
 
        FILE *f = fopen(filename, "rb");
        if (!f) {
@@ -527,9 +528,22 @@ parse_profile(const char *filename, unsigned int num_blocks)
        }
 
        result = XMALLOCN(unsigned int, num_blocks);
-       if (fread(result, sizeof(unsigned int) * num_blocks, 1, f) < 1) {
+
+       /* The profiling output format is defined to be a sequence of integer
+        * values stored little endian format. */
+       for (i = 0; i < num_blocks; ++i) {
+               char bytes[4];
+
+               if ((ret = fread(bytes, 4, 1, f)) < 1)
+                       break;
+
+               result[i] = (bytes[0] <<  0) | (bytes[1] <<  8)
+                         | (bytes[2] << 16) | (bytes[3] << 24);
+       }
+
+       if (ret < 1) {
                DBG((dbg, LEVEL_4, "Failed to read counters... (size: %u)\n",
-                   sizeof(unsigned int) * num_blocks));
+                       sizeof(unsigned int) * num_blocks));
                xfree(result);
                result = NULL;
        }
index b387b83..b3e9fe6 100644 (file)
@@ -19,17 +19,39 @@ typedef struct _profile_counter_t {
 
 static profile_counter_t *counters = NULL;
 
+/**
+ * Write counter values to profiling output file.
+ * We define our output format to be a sequence of 32-bit unsigned integer
+ * values stored in little endian format.
+ */
+void write_little_endian(unsigned *counter, unsigned len, FILE *f)
+{
+       unsigned i;
+
+       for (i = 0; i < len; ++i) {
+               unsigned v = counter[i];
+               char     bytes[4];
+
+               bytes[0] = ((v >>  0) & 0xff);
+               bytes[1] = ((v >>  8) & 0xff);
+               bytes[2] = ((v >> 16) & 0xff);
+               bytes[3] = ((v >> 24) & 0xff);
+
+               fwrite(bytes, 4, 1, f);
+       }
+}
+
 static void write_profiles(void)
 {
        profile_counter_t *counter = counters;
-       while(counter != NULL) {
+       while (counter != NULL) {
                profile_counter_t *next = counter->next;
                FILE *f = fopen(counter->filename, "wb");
                if (f == NULL) {
                        perror("Warning: couldn't open file for writing profiling data");
                } else {
                        fputs("firmprof", f);
-                       fwrite(counter->counters, counter->len * sizeof(unsigned), 1, f);
+                       write_little_endian(counter->counters, counter->len, f);
                        fclose(f);
                }
                free(counter);