int pttc_main(const struct pttc_options *options) { int errcode; enum { buflen = 1024 }; uint8_t buf[buflen]; struct pt_config conf; pt_config_init(&conf); conf.cpu = options->cpu; conf.begin = buf; conf.end = buf+buflen; /* apply errata for the chosen cpu. */ errcode = pt_cpu_errata(&conf.errata, &conf.cpu); if (errcode < 0) { fprintf(stderr, "fatal: errata configuration failed %d: %s\n", errcode, pt_errstr(pt_errcode(errcode))); return errcode; } errcode = parse(options->pttfile, &conf); if (errcode < 0 && errcode != -err_run) fprintf(stderr, "fatal: %s\n", errstr[-errcode]); return -errcode; }
void arch_ptAnalyze(honggfuzz_t * hfuzz, fuzzer_t * fuzzer) { struct perf_event_mmap_page *pem = (struct perf_event_mmap_page *)fuzzer->linux.perfMmapBuf; struct pt_config ptc; pt_config_init(&ptc); ptc.begin = &fuzzer->linux.perfMmapAux[pem->aux_tail]; ptc.end = &fuzzer->linux.perfMmapAux[pem->aux_head - 1]; int errcode = pt_cpu_errata(&ptc.errata, &ptc.cpu); if (errcode < 0) { LOG_F("pt_errata() failed: %s", pt_errstr(errcode)); } struct pt_packet_decoder *ptd = pt_pkt_alloc_decoder(&ptc); if (ptd == NULL) { LOG_F("pt_pkt_alloc_decoder() failed"); } defer { pt_pkt_free_decoder(ptd); }; errcode = pt_pkt_sync_forward(ptd); if (errcode < 0) { LOG_W("pt_pkt_sync_forward() failed: %s", pt_errstr(errcode)); return; } struct pt_last_ip last_ip; pt_last_ip_init(&last_ip); for (;;) { struct pt_packet packet; errcode = pt_pkt_next(ptd, &packet, sizeof(packet)); if (errcode == -pte_eos) { break; } if (errcode < 0) { LOG_W("pt_pkt_next() failed: %s", pt_errstr(errcode)); break; } perf_ptAnalyzePkt(hfuzz, fuzzer, &packet, &ptc, &last_ip); } }
static struct ptunit_result tfix_init(struct test_fixture *tfix) { struct pt_config *config; uint8_t *buffer; int errcode; config = &tfix->config; buffer = tfix->buffer; memset(buffer, 0, sizeof(tfix->buffer)); pt_config_init(config); config->begin = buffer; config->end = buffer + sizeof(tfix->buffer); errcode = pt_pkt_decoder_init(&tfix->decoder, config); ptu_int_eq(errcode, 0); return ptu_passed(); }
extern int main(int argc, char *argv[]) { struct pt_image_section_cache *iscache; struct ptxed_decoder decoder; struct ptxed_options options; struct ptxed_stats stats; struct pt_config config; struct pt_image *image; const char *prog; int errcode, i; if (!argc) { help(""); return 1; } prog = argv[0]; iscache = NULL; image = NULL; memset(&decoder, 0, sizeof(decoder)); decoder.type = pdt_block_decoder; memset(&options, 0, sizeof(options)); memset(&stats, 0, sizeof(stats)); pt_config_init(&config); iscache = pt_iscache_alloc(NULL); if (!iscache) { fprintf(stderr, "%s: failed to allocate image section cache.\n", prog); goto err; } image = pt_image_alloc(NULL); if (!image) { fprintf(stderr, "%s: failed to allocate image.\n", prog); goto err; } for (i = 1; i < argc;) { char *arg; arg = argv[i++]; if (strcmp(arg, "--help") == 0 || strcmp(arg, "-h") == 0) { help(prog); goto out; } if (strcmp(arg, "--version") == 0) { version(prog); goto out; } if (strcmp(arg, "--pt") == 0) { if (argc <= i) { fprintf(stderr, "%s: --pt: missing argument.\n", prog); goto out; } arg = argv[i++]; if (ptxed_have_decoder(&decoder)) { fprintf(stderr, "%s: duplicate pt sources: %s.\n", prog, arg); goto err; } errcode = pt_cpu_errata(&config.errata, &config.cpu); if (errcode < 0) goto err; errcode = load_pt(&config, arg, prog); if (errcode < 0) goto err; switch (decoder.type) { case pdt_insn_decoder: decoder.variant.insn = pt_insn_alloc_decoder(&config); if (!decoder.variant.insn) { fprintf(stderr, "%s: failed to create " "decoder.\n", prog); goto err; } errcode = pt_insn_set_image(decoder.variant.insn, image); if (errcode < 0) { fprintf(stderr, "%s: failed to set image.\n", prog); goto err; } break; case pdt_block_decoder: decoder.variant.block = pt_blk_alloc_decoder(&config); if (!decoder.variant.block) { fprintf(stderr, "%s: failed to create " "decoder.\n", prog); goto err; } errcode = pt_blk_set_image(decoder.variant.block, image); if (errcode < 0) { fprintf(stderr, "%s: failed to set image.\n", prog); goto err; } break; } continue; } if (strcmp(arg, "--raw") == 0) { if (argc <= i) { fprintf(stderr, "%s: --raw: missing argument.\n", prog); goto out; } arg = argv[i++]; errcode = load_raw(iscache, image, arg, prog); if (errcode < 0) goto err; continue; } #if defined(FEATURE_ELF) if (strcmp(arg, "--elf") == 0) { uint64_t base; if (argc <= i) { fprintf(stderr, "%s: --elf: missing argument.\n", prog); goto out; } arg = argv[i++]; base = 0ull; errcode = extract_base(arg, &base); if (errcode < 0) goto err; errcode = load_elf(iscache, image, arg, base, prog, options.track_image); if (errcode < 0) goto err; continue; } #endif /* defined(FEATURE_ELF) */ if (strcmp(arg, "--att") == 0) { options.att_format = 1; continue; } if (strcmp(arg, "--no-inst") == 0) { options.dont_print_insn = 1; continue; } if (strcmp(arg, "--quiet") == 0 || strcmp(arg, "-q") == 0) { options.quiet = 1; continue; } if (strcmp(arg, "--offset") == 0) { options.print_offset = 1; continue; } if (strcmp(arg, "--time") == 0) { options.print_time = 1; continue; } if (strcmp(arg, "--raw-insn") == 0) { options.print_raw_insn = 1; continue; } if (strcmp(arg, "--stat") == 0) { options.print_stats = 1; continue; } if (strcmp(arg, "--stat:insn") == 0) { stats.flags |= ptxed_stat_insn; continue; } if (strcmp(arg, "--stat:blocks") == 0) { stats.flags |= ptxed_stat_blocks; continue; } if (strcmp(arg, "--cpu") == 0) { /* override cpu information before the decoder * is initialized. */ if (ptxed_have_decoder(&decoder)) { fprintf(stderr, "%s: please specify cpu before the pt source file.\n", prog); goto err; } if (argc <= i) { fprintf(stderr, "%s: --cpu: missing argument.\n", prog); goto out; } arg = argv[i++]; if (strcmp(arg, "auto") == 0) { errcode = pt_cpu_read(&config.cpu); if (errcode < 0) { fprintf(stderr, "%s: error reading cpu: %s.\n", prog, pt_errstr(pt_errcode(errcode))); return 1; } continue; } if (strcmp(arg, "none") == 0) { memset(&config.cpu, 0, sizeof(config.cpu)); continue; } errcode = pt_cpu_parse(&config.cpu, arg); if (errcode < 0) { fprintf(stderr, "%s: cpu must be specified as f/m[/s]\n", prog); goto err; } continue; } if (strcmp(arg, "--mtc-freq") == 0) { if (!get_arg_uint8(&config.mtc_freq, "--mtc-freq", argv[i++], prog)) goto err; continue; } if (strcmp(arg, "--nom-freq") == 0) { if (!get_arg_uint8(&config.nom_freq, "--nom-freq", argv[i++], prog)) goto err; continue; } if (strcmp(arg, "--cpuid-0x15.eax") == 0) { if (!get_arg_uint32(&config.cpuid_0x15_eax, "--cpuid-0x15.eax", argv[i++], prog)) goto err; continue; } if (strcmp(arg, "--cpuid-0x15.ebx") == 0) { if (!get_arg_uint32(&config.cpuid_0x15_ebx, "--cpuid-0x15.ebx", argv[i++], prog)) goto err; continue; } if (strcmp(arg, "--verbose") == 0 || strcmp(arg, "-v") == 0) { options.track_image = 1; continue; } if (strcmp(arg, "--insn-decoder") == 0) { if (ptxed_have_decoder(&decoder)) { fprintf(stderr, "%s: please specify %s before the pt " "source file.\n", arg, prog); goto err; } decoder.type = pdt_insn_decoder; continue; } if (strcmp(arg, "--block-decoder") == 0) { if (ptxed_have_decoder(&decoder)) { fprintf(stderr, "%s: please specify %s before the pt " "source file.\n", arg, prog); goto err; } decoder.type = pdt_block_decoder; continue; } if (strcmp(arg, "--block:show-blocks") == 0) { options.track_blocks = 1; continue; } if (strcmp(arg, "--block:end-on-call") == 0) { config.flags.variant.block.end_on_call = 1; continue; } fprintf(stderr, "%s: unknown option: %s.\n", prog, arg); goto err; } if (!ptxed_have_decoder(&decoder)) { fprintf(stderr, "%s: no pt file.\n", prog); goto err; } xed_tables_init(); /* If we didn't select any statistics, select them all depending on the * decoder type. */ if (options.print_stats && !stats.flags) { stats.flags |= ptxed_stat_insn; if (decoder.type == pdt_block_decoder) stats.flags |= ptxed_stat_blocks; } decode(&decoder, iscache, &options, options.print_stats ? &stats : NULL); if (options.print_stats) print_stats(&stats); out: ptxed_free_decoder(&decoder); pt_image_free(image); pt_iscache_free(iscache); return 0; err: ptxed_free_decoder(&decoder); pt_image_free(image); pt_iscache_free(iscache); return 1; }