static void write_gcda(char *addr, struct gcov_info* gi) { const char* filename = SKIBOOT_ADDR(addr, gi->filename); int fd; u32 fn; struct gcov_fn_info *fn_info; struct gcov_fn_info **functions; struct gcov_ctr_info *ctr_info; u32 ctr; u32 cv; printf("Writing %s\n", filename); fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR); write_u32(fd, GCOV_DATA_MAGIC); write_u32(fd, be32toh(gi->version)); write_u32(fd, be32toh(gi->stamp)); //printf("nfunctions: %d \n", be32toh(gi->n_functions)); for(fn = 0; fn < be32toh(gi->n_functions); fn++) { functions = (struct gcov_fn_info**) SKIBOOT_ADDR(addr, gi->functions); fn_info = (struct gcov_fn_info*) SKIBOOT_ADDR(addr, functions[fn]); write_u32(fd, GCOV_TAG_FUNCTION); write_u32(fd, GCOV_TAG_FUNCTION_LENGTH); write_u32(fd, be32toh(fn_info->ident)); write_u32(fd, be32toh(fn_info->lineno_checksum)); write_u32(fd, be32toh(fn_info->cfg_checksum)); ctr_info = (struct gcov_ctr_info*) ((char*)fn_info + sizeof(struct gcov_fn_info)); for(ctr = 0; ctr < GCOV_COUNTERS; ctr++) { if (!counter_active(gi, ctr)) continue; write_u32(fd, (GCOV_TAG_FOR_COUNTER(ctr))); write_u32(fd, be32toh(ctr_info->num)*2); /* printf(" ctr %d gcov_ctr_info->num %u\n", * ctr, be32toh(ctr_info->num)); */ for(cv = 0; cv < be32toh(ctr_info->num); cv++) { gcov_type *ctrv = (gcov_type *) SKIBOOT_ADDR(addr, ctr_info->values); //printf("%lx\n", be64toh(ctrv[cv])); write_u64(fd, be64toh(ctrv[cv])); } ctr_info++; } } close(fd); }
static inline int next_type(const struct gcov_info *info, int *type) { while ( ++*type < XENCOV_COUNTERS && !counter_active(info, *type) ) continue; return *type; }