struct gcov_file *gcov_find_file_no_fail(const char *name, unsigned int maxline) { struct gcov_file *f; f = gcov_find_file(name); if (!f) { f = safe_mallocz(sizeof *f); f->lines = safe_mallocz(maxline * sizeof f->lines[0]); f->instr_lines = safe_mallocz(maxline * sizeof f->instr_lines[0]); f->nr_lines = maxline; f->filename = strdup(name); f->next = gcov_files; gcov_files = f; } else { if (maxline > f->nr_lines) { f->lines = safe_realloc(f->lines, maxline * sizeof f->lines[0]); f->instr_lines = safe_realloc(f->instr_lines, maxline * sizeof f->instr_lines[0]); memset(&f->lines[f->nr_lines], 0, (maxline - f->nr_lines) * sizeof f->lines[0]); memset(&f->instr_lines[f->nr_lines], 0, (maxline - f->nr_lines) * sizeof f->instr_lines[0]); f->nr_lines = maxline; } } return f; }
void gcda_add_file(const char *name) { struct gcda_file *g; g = safe_mallocz(sizeof *g); g->name = strdup(name); g->next = gcda_files; gcda_files = g; }
void * vo_null_init(void) { vo_null_ctx *v = safe_mallocz(sizeof(vo_null_ctx)); MHEGDisplay *d = MHEGEngine_getDisplay(); XGCValues gcvals; gcvals.foreground = BlackPixel(d->dpy, DefaultScreen(d->dpy)); v->gc = XCreateGC(d->dpy, d->contents, GCForeground, &gcvals); return v; }
bool gcov_parse_counts_record(struct gcov_counts *b, struct gcov_record *rec) { unsigned int i; unsigned int pos = 0; b->nr_counts = rec->hdr.length / 2; b->counts = safe_mallocz(b->nr_counts * sizeof b->counts[0]); for (i = 0; i < b->nr_counts; i++) { b->counts[i] = rec->data.u64[pos++]; D(printf("counts[%u] = %" PRIx64 "\n", i, b->counts[i])); } return true; }
bool gcov_parse_block_record(struct gcov_ctx *ctx) { struct gcov_record *rec = &ctx->rec->rec; struct gcov_blocks *b = &ctx->rec->blocks; unsigned int i; b->nr_blocks = rec->hdr.length; b->flags = safe_mallocz(sizeof *b->flags * b->nr_blocks); D(printf("nr_blocks=%d\n", b->nr_blocks)); for (i = 0; i < b->nr_blocks; i++) { b->flags[i] = rec->data.u32[i]; D(printf("flags=%x\n", b->flags[i])); } return true; }
serLineT* serAddLine ( char* dev, int line, int mode ) { char fulldev[64]; serDevT* serdev; serLineT* serline; //allow for either full paths or /dev relative paths... if ( dev[0] == '/' ) { if ( strlen(dev) >= 64 ) { loggerf ( LOGGER_NOTE, "serAddLine(): dev too long\n" ); return NULL; } strcpy ( fulldev, dev ); } else { strcpy ( fulldev, "/dev/" ); if ( strlen(dev)+strlen(fulldev) >= 64 ) { loggerf ( LOGGER_NOTE, "serAddLine(): dev too long\n" ); return NULL; } strcat ( fulldev, dev ); } //make sure only one line bit is set... if ( line & (line-1) ) { loggerf ( LOGGER_NOTE, "serAddLine(): more than one line bit set\n" ); return NULL; } //try and find an existing device in the list... serdev = serDevHead; while ( serdev != NULL ) { if ( strcmp ( serdev->dev, fulldev ) == 0 ) break; serdev = serdev->next; } if ( serdev == NULL ) { //no existing device - create a new one.. serdev = safe_mallocz ( sizeof(serDevT) ); serdev->next = serDevHead; serDevHead = serdev; strcpy ( serdev->dev, fulldev ); serdev->mode = mode; serdev->modemlines = 0; serdev->fd = -1; } //make sure we're using it in the same mode... if ( serdev->mode != mode ) { loggerf ( LOGGER_NOTE, "serAddLine(): cannot add line for same device with different mode\n" ); return NULL; } //make sure we're not already monitoring this line... if ( serdev->modemlines & line ) { loggerf ( LOGGER_NOTE, "serAddLine(): cannot add modem status line more than once\n" ); return NULL; } //ok - we've got a valid device/line/mode combo... serdev->modemlines |= line; //create a new line entry... serline = safe_mallocz ( sizeof(serLineT) ); serline->next = serLineHead; serLineHead = serline; serline->dev = serdev; serline->line = line; return serline; }
void gcov_test(void **store, const char *gcno, const char *gcda, const char *gcov_strip, const char *gcov_prefix) { struct gcov_summary prog_sum, obj_sum; struct gcov_ctx ctx; struct gcov_record_ir *rec; memset(&ctx, 0, sizeof ctx); ctx.store = store; ctx.gcov_strip = gcov_strip; ctx.gcov_prefix = gcov_prefix; ctx.rec = safe_mallocz(sizeof *rec + MAX_RECORD_SIZE); rec = ctx.rec; ctx.fd = open(gcno, O_RDONLY); if (ctx.fd < 0) { perror(gcno); goto err; } gcov_read_file_header(ctx.fd, &ctx.file_hdr); /* We dont support counter merge:ing at the moment. */ ctx.fd_out = -1; if (gcda) { ctx.fd_out = open(gcda, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); if (ctx.fd_out < 0) { perror(gcda); goto err; } } ctx.file_hdr.magic = GCOV_DATA_MAGIC; safe_write(ctx.fd_out, &ctx.file_hdr, sizeof ctx.file_hdr); while (1) { bool parsed; if (!gcov_read_record(ctx.fd, &rec->rec)) break; if (rec->rec.hdr.tag == GCOV_TAG_FUNCTION) { /* Process previous func state. */ if (rec->blocks.nr_blocks) { gcov_process_func(&ctx); } gcov_reset_func_state(&ctx); } parsed = gcov_parse_record(&ctx); if (!parsed) break; switch (rec->rec.hdr.tag) { case GCOV_TAG_FUNCTION: { rec->rec.hdr.length = 2; if (ctx.file_hdr.version >= 0x34303665) rec->rec.hdr.length += 1; safe_write(ctx.fd_out, &rec->rec, sizeof rec->rec.hdr + rec->rec.hdr.length * 4); break; } case GCOV_TAG_LINES: if (rec->nr_arcs == rec->nr_lines) { gcov_process_func(&ctx); } break; default: break; } } if (rec->blocks.nr_blocks) { gcov_process_func(&ctx); } gcov_reset_func_state(&ctx); obj_sum.checksum = 0; obj_sum.count_summary[0].num = 1; obj_sum.count_summary[0].runs = 1; obj_sum.count_summary[0].sum = 1; obj_sum.count_summary[0].max = 1; obj_sum.count_summary[0].sum_max = 1; prog_sum.checksum = 0; prog_sum.count_summary[0].num = 1; prog_sum.count_summary[0].runs = 1; prog_sum.count_summary[0].sum = 1; prog_sum.count_summary[0].max = 1; prog_sum.count_summary[0].sum_max = 1; gcov_emit_summary(ctx.fd_out, GCOV_TAG_OBJECT_SUMMARY, &obj_sum); gcov_emit_summary(ctx.fd_out, GCOV_TAG_PROGRAM_SUMMARY, &prog_sum); /* eof. */ rec->rec.hdr.tag = 0; rec->rec.hdr.length = 0; safe_write(ctx.fd_out, &rec->rec, sizeof rec->rec.hdr + rec->rec.hdr.length * 4); err: free(ctx.rec); close(ctx.fd); close(ctx.fd_out); }
void gcov_process_func(struct gcov_ctx *ctx) { struct gcov_record_ir *rec = ctx->rec; uint64_t off; struct sym *s; unsigned int num_counts = 0; unsigned int i; for (i = 0; i < rec->nr_arcs; i++) { struct gcov_arcs *arc = &rec->arcs[i]; unsigned int a; for (a = 0; a < arc->nr_arcs; a++) { if (!(arc->arcs[a].flags & GCOV_ARC_ON_TREE)) num_counts++; } } s = sym_lookup_by_name(ctx->store, rec->func.name); D(printf("Process func %s %s:%d s=%p counts=%d\n", rec->func.name, rec->func.source, rec->func.lineno, s, num_counts)); if (s) sym_show("s", s); if (!num_counts) return; rec->counts.nr_counts = num_counts; rec->counts.counts = safe_mallocz(num_counts * sizeof rec->counts.counts[0]); if (s && s->linemap && s->cov) { for (off = 0; off < (s->size / 4); off++) { struct sym_src_loc *loc; loc = &s->linemap->locs[off]; if (!loc->filename) continue; do { unsigned int block_nr; uint64_t v = 0; if (s->cov_ent) v = s->cov_ent->counter[off]; block_nr = gcov_match_line(ctx, loc, off == 0); if (block_nr >= 0 && block_nr < rec->counts.nr_counts && !rec->counts.counts[block_nr]) { rec->counts.counts[block_nr] = v; } /* FIXME: Prologue??? */ if (off == 0) rec->counts.counts[0] = v; loc = loc->next; } while (loc); } } gcov_emit_counts(ctx->fd_out, &rec->counts); }