tools/perf/util/capstone.c

Source file repositories/reference/linux-study-clean/tools/perf/util/capstone.c

File Facts

System
Linux kernel
Corpus path
tools/perf/util/capstone.c
Extension
.c
Size
13744 bytes
Lines
572
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct find_file_offset_data {
	u64 ip;
	u64 offset;
};

/* This will be called for each PHDR in an ELF binary */
static int find_file_offset(u64 start, u64 len, u64 pgoff, void *arg)
{
	struct find_file_offset_data *data = arg;

	if (start <= data->ip && data->ip < start + len) {
		data->offset = pgoff + data->ip - start;
		return 1;
	}
	return 0;
}

int symbol__disassemble_capstone(const char *filename __maybe_unused,
				 struct symbol *sym __maybe_unused,
				 struct annotate_args *args __maybe_unused)
{
	struct annotation *notes = symbol__annotation(sym);
	struct map *map = args->ms->map;
	struct dso *dso = map__dso(map);
	u64 start = map__rip_2objdump(map, sym->start);
	u64 offset;
	int i, count, free_count;
	bool is_64bit = false;
	bool needs_cs_close = false;
	/* Malloc-ed buffer containing instructions read from disk. */
	u8 *code_buf = NULL;
	/* Pointer to code to be disassembled. */
	const u8 *buf;
	u64 buf_len;
	csh handle;
	struct cs_insn *insn = NULL;
	char disasm_buf[512];
	struct disasm_line *dl;
	bool disassembler_style = false;

	if (args->options->objdump_path)
		return -1;

	buf = dso__read_symbol(dso, filename, map, sym,
			       &code_buf, &buf_len, &is_64bit);
	if (buf == NULL)
		return errno;

	/* add the function address and name */
	scnprintf(disasm_buf, sizeof(disasm_buf), "%#"PRIx64" <%s>:",
		  start, sym->name);

	args->offset = -1;
	args->line = disasm_buf;
	args->line_nr = 0;
	args->fileloc = NULL;
	args->ms->sym = sym;

	dl = disasm_line__new(args);
	if (dl == NULL)
		goto err;

	annotation_line__add(&dl->al, &notes->src->source);

	if (!args->options->disassembler_style ||
	    !strcmp(args->options->disassembler_style, "att"))
		disassembler_style = true;

	if (capstone_init(maps__machine(thread__maps(args->ms->thread)), &handle, is_64bit,
			  disassembler_style) < 0)
		goto err;

	needs_cs_close = true;

	free_count = count = perf_cs_disasm(handle, buf, buf_len, start, buf_len, &insn);
	for (i = 0, offset = 0; i < count; i++) {
		int printed;

		printed = scnprintf(disasm_buf, sizeof(disasm_buf),
				    "       %-7s %s",
				    insn[i].mnemonic, insn[i].op_str);
		print_capstone_detail(&insn[i], disasm_buf + printed,
				      sizeof(disasm_buf) - printed, args,
				      start + offset);

		args->offset = offset;
		args->line = disasm_buf;

		dl = disasm_line__new(args);
		if (dl == NULL)

Annotation

Implementation Notes