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) {
}
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;
}
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);