예제 #1
0
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;
}
예제 #2
0
int main(int argc, char *argv[])
{
	struct pttc_options options;
	const char *prog;
	int errcode, i;

	prog = argv[0];
	memset(&options, 0, sizeof(options));

	/* default is to override the auto-detected value during
	 * pt_configure with default spec behavior. options.cpu is
	 * zeroed above.
	 */
	options.use_cpu = 1;

	for (i = 1; i < argc;) {
		const char *arg;

		arg = argv[i++];

		if (strcmp(arg, "--help") == 0 || strcmp(arg, "-h") == 0) {
			help(prog);
			return 0;
		}
		if (strcmp(arg, "--version") == 0) {
			version(prog);
			return 0;
		}
		if (strcmp(arg, "--cpu") == 0) {
			arg = argv[i++];

			/* keep the auto-detected values from pt_configure.  */
			if (strcmp(arg, "auto") == 0) {
				options.use_cpu = 0;
				continue;
			}

			/* use the value in options.cpu, instead of
			 * auto-detected.
			 */
			options.use_cpu = 1;

			if (strcmp(arg, "none") == 0) {
				memset(&options.cpu, 0, sizeof(options.cpu));
				continue;
			}

			errcode = pt_cpu_parse(&options.cpu, arg);
			if (errcode < 0) {
				fprintf(stderr,
					"%s: cpu must be specified as f/m[/s].\n",
					prog);
				return 1;
			}
			continue;
		}

		if (arg[0] == '-') {
			fprintf(stderr, "%s: unrecognized option '%s'.\n",
				prog, arg);
			return 1;
		}

		if (options.pttfile) {
			fprintf(stderr,
				"%s: only one pttfile can be specified.\n",
				prog);
			return 1;
		}
		options.pttfile = arg;
	}

	if (!options.pttfile) {
		fprintf(stderr, "%s: no pttfile specified.\n", prog);
		fprintf(stderr, "Try '%s -h' for more information.\n", prog);
		return 1;
	}

	return pttc_main(&options);
}