diff options
| author | Adrian Hunter <adrian.hunter@intel.com> | 2015-08-13 03:14:55 -0400 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-08-17 10:11:36 -0400 |
| commit | 237fae79f50d2d0c7bdeb039bc2c87fc6d52c7e7 (patch) | |
| tree | 5f1f7e4b16547526c955a7f05db793c6d92daae5 | |
| parent | a4e925905c98fb83538c164878946d77d0df1433 (diff) | |
perf tools: Add Intel PT instruction decoder
Add support for decoding instructions for Intel Processor Trace. The
kernel x86 instruction decoder is copied for this.
This essentially provides intel_pt_get_insn() which takes a binary
buffer, uses the kernel's x86 instruction decoder to get details of the
instruction and then categorizes it for consumption by an Intel PT
decoder.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/1439450095-30122-1-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
| -rw-r--r-- | tools/build/Makefile.build | 2 | ||||
| -rw-r--r-- | tools/perf/.gitignore | 1 | ||||
| -rw-r--r-- | tools/perf/Makefile.perf | 12 | ||||
| -rw-r--r-- | tools/perf/util/intel-pt-decoder/Build | 12 | ||||
| -rw-r--r-- | tools/perf/util/intel-pt-decoder/gen-insn-attr-x86.awk | 386 | ||||
| -rw-r--r-- | tools/perf/util/intel-pt-decoder/inat.c | 96 | ||||
| -rw-r--r-- | tools/perf/util/intel-pt-decoder/inat.h | 221 | ||||
| -rw-r--r-- | tools/perf/util/intel-pt-decoder/insn.c | 594 | ||||
| -rw-r--r-- | tools/perf/util/intel-pt-decoder/insn.h | 201 | ||||
| -rw-r--r-- | tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c | 246 | ||||
| -rw-r--r-- | tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.h | 65 | ||||
| -rw-r--r-- | tools/perf/util/intel-pt-decoder/x86-opcode-map.txt | 970 |
12 files changed, 2803 insertions, 3 deletions
diff --git a/tools/build/Makefile.build b/tools/build/Makefile.build index faca2bf6a430..8120af9c0341 100644 --- a/tools/build/Makefile.build +++ b/tools/build/Makefile.build | |||
| @@ -57,6 +57,8 @@ quiet_cmd_cc_i_c = CPP $@ | |||
| 57 | quiet_cmd_cc_s_c = AS $@ | 57 | quiet_cmd_cc_s_c = AS $@ |
| 58 | cmd_cc_s_c = $(CC) $(c_flags) -S -o $@ $< | 58 | cmd_cc_s_c = $(CC) $(c_flags) -S -o $@ $< |
| 59 | 59 | ||
| 60 | quiet_cmd_gen = GEN $@ | ||
| 61 | |||
| 60 | # Link agregate command | 62 | # Link agregate command |
| 61 | # If there's nothing to link, create empty $@ object. | 63 | # If there's nothing to link, create empty $@ object. |
| 62 | quiet_cmd_ld_multi = LD $@ | 64 | quiet_cmd_ld_multi = LD $@ |
diff --git a/tools/perf/.gitignore b/tools/perf/.gitignore index 09db62ba5786..3d1bb802dbf4 100644 --- a/tools/perf/.gitignore +++ b/tools/perf/.gitignore | |||
| @@ -29,3 +29,4 @@ config.mak.autogen | |||
| 29 | *.pyc | 29 | *.pyc |
| 30 | *.pyo | 30 | *.pyo |
| 31 | .config-detected | 31 | .config-detected |
| 32 | util/intel-pt-decoder/inat-tables.c | ||
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 4b58daeff881..d9863cb96f59 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf | |||
| @@ -76,6 +76,12 @@ include config/utilities.mak | |||
| 76 | # | 76 | # |
| 77 | # Define NO_AUXTRACE if you do not want AUX area tracing support | 77 | # Define NO_AUXTRACE if you do not want AUX area tracing support |
| 78 | 78 | ||
| 79 | # As per kernel Makefile, avoid funny character set dependencies | ||
| 80 | unexport LC_ALL | ||
| 81 | LC_COLLATE=C | ||
| 82 | LC_NUMERIC=C | ||
| 83 | export LC_COLLATE LC_NUMERIC | ||
| 84 | |||
| 79 | ifeq ($(srctree),) | 85 | ifeq ($(srctree),) |
| 80 | srctree := $(patsubst %/,%,$(dir $(shell pwd))) | 86 | srctree := $(patsubst %/,%,$(dir $(shell pwd))) |
| 81 | srctree := $(patsubst %/,%,$(dir $(srctree))) | 87 | srctree := $(patsubst %/,%,$(dir $(srctree))) |
| @@ -135,6 +141,7 @@ INSTALL = install | |||
| 135 | FLEX = flex | 141 | FLEX = flex |
| 136 | BISON = bison | 142 | BISON = bison |
| 137 | STRIP = strip | 143 | STRIP = strip |
| 144 | AWK = awk | ||
| 138 | 145 | ||
| 139 | LIB_DIR = $(srctree)/tools/lib/api/ | 146 | LIB_DIR = $(srctree)/tools/lib/api/ |
| 140 | TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/ | 147 | TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/ |
| @@ -289,7 +296,7 @@ strip: $(PROGRAMS) $(OUTPUT)perf | |||
| 289 | 296 | ||
| 290 | PERF_IN := $(OUTPUT)perf-in.o | 297 | PERF_IN := $(OUTPUT)perf-in.o |
| 291 | 298 | ||
| 292 | export srctree OUTPUT RM CC LD AR CFLAGS V BISON FLEX | 299 | export srctree OUTPUT RM CC LD AR CFLAGS V BISON FLEX AWK |
| 293 | build := -f $(srctree)/tools/build/Makefile.build dir=. obj | 300 | build := -f $(srctree)/tools/build/Makefile.build dir=. obj |
| 294 | 301 | ||
| 295 | $(PERF_IN): $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h FORCE | 302 | $(PERF_IN): $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h FORCE |
| @@ -565,7 +572,8 @@ clean: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean config-clean | |||
| 565 | $(Q)find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete | 572 | $(Q)find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete |
| 566 | $(Q)$(RM) $(OUTPUT).config-detected | 573 | $(Q)$(RM) $(OUTPUT).config-detected |
| 567 | $(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 perf-read-vdsox32 | 574 | $(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 perf-read-vdsox32 |
| 568 | $(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)FEATURE-DUMP $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* | 575 | $(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)FEATURE-DUMP $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* \ |
| 576 | $(OUTPUT)util/intel-pt-decoder/inat-tables.c | ||
| 569 | $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean | 577 | $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean |
| 570 | $(python-clean) | 578 | $(python-clean) |
| 571 | 579 | ||
diff --git a/tools/perf/util/intel-pt-decoder/Build b/tools/perf/util/intel-pt-decoder/Build index 9d67381a9bd3..5a46ce13c1f8 100644 --- a/tools/perf/util/intel-pt-decoder/Build +++ b/tools/perf/util/intel-pt-decoder/Build | |||
| @@ -1 +1,11 @@ | |||
| 1 | libperf-$(CONFIG_AUXTRACE) += intel-pt-pkt-decoder.o | 1 | libperf-$(CONFIG_AUXTRACE) += intel-pt-pkt-decoder.o intel-pt-insn-decoder.o |
| 2 | |||
| 3 | inat_tables_script = util/intel-pt-decoder/gen-insn-attr-x86.awk | ||
| 4 | inat_tables_maps = util/intel-pt-decoder/x86-opcode-map.txt | ||
| 5 | |||
| 6 | $(OUTPUT)util/intel-pt-decoder/inat-tables.c: $(inat_tables_script) $(inat_tables_maps) | ||
| 7 | @$(call echo-cmd,gen)$(AWK) -f $(inat_tables_script) $(inat_tables_maps) > $@ || rm -f $@ | ||
| 8 | |||
| 9 | $(OUTPUT)util/intel-pt-decoder/intel-pt-insn-decoder.o: util/intel-pt-decoder/inat.c $(OUTPUT)util/intel-pt-decoder/inat-tables.c | ||
| 10 | |||
| 11 | CFLAGS_intel-pt-insn-decoder.o += -I$(OUTPUT)util/intel-pt-decoder -Wno-override-init | ||
diff --git a/tools/perf/util/intel-pt-decoder/gen-insn-attr-x86.awk b/tools/perf/util/intel-pt-decoder/gen-insn-attr-x86.awk new file mode 100644 index 000000000000..517567347aac --- /dev/null +++ b/tools/perf/util/intel-pt-decoder/gen-insn-attr-x86.awk | |||
| @@ -0,0 +1,386 @@ | |||
| 1 | #!/bin/awk -f | ||
| 2 | # gen-insn-attr-x86.awk: Instruction attribute table generator | ||
| 3 | # Written by Masami Hiramatsu <mhiramat@redhat.com> | ||
| 4 | # | ||
| 5 | # Usage: awk -f gen-insn-attr-x86.awk x86-opcode-map.txt > inat-tables.c | ||
| 6 | |||
| 7 | # Awk implementation sanity check | ||
| 8 | function check_awk_implement() { | ||
| 9 | if (sprintf("%x", 0) != "0") | ||
| 10 | return "Your awk has a printf-format problem." | ||
| 11 | return "" | ||
| 12 | } | ||
| 13 | |||
| 14 | # Clear working vars | ||
| 15 | function clear_vars() { | ||
| 16 | delete table | ||
| 17 | delete lptable2 | ||
| 18 | delete lptable1 | ||
| 19 | delete lptable3 | ||
| 20 | eid = -1 # escape id | ||
| 21 | gid = -1 # group id | ||
| 22 | aid = -1 # AVX id | ||
| 23 | tname = "" | ||
| 24 | } | ||
| 25 | |||
| 26 | BEGIN { | ||
| 27 | # Implementation error checking | ||
| 28 | awkchecked = check_awk_implement() | ||
| 29 | if (awkchecked != "") { | ||
| 30 | print "Error: " awkchecked > "/dev/stderr" | ||
| 31 | print "Please try to use gawk." > "/dev/stderr" | ||
| 32 | exit 1 | ||
| 33 | } | ||
| 34 | |||
| 35 | # Setup generating tables | ||
| 36 | print "/* x86 opcode map generated from x86-opcode-map.txt */" | ||
| 37 | print "/* Do not change this code. */\n" | ||
| 38 | ggid = 1 | ||
| 39 | geid = 1 | ||
| 40 | gaid = 0 | ||
| 41 | delete etable | ||
| 42 | delete gtable | ||
| 43 | delete atable | ||
| 44 | |||
| 45 | opnd_expr = "^[A-Za-z/]" | ||
| 46 | ext_expr = "^\\(" | ||
| 47 | sep_expr = "^\\|$" | ||
| 48 | group_expr = "^Grp[0-9A-Za-z]+" | ||
| 49 | |||
| 50 | imm_expr = "^[IJAOL][a-z]" | ||
| 51 | imm_flag["Ib"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)" | ||
| 52 | imm_flag["Jb"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)" | ||
| 53 | imm_flag["Iw"] = "INAT_MAKE_IMM(INAT_IMM_WORD)" | ||
| 54 | imm_flag["Id"] = "INAT_MAKE_IMM(INAT_IMM_DWORD)" | ||
| 55 | imm_flag["Iq"] = "INAT_MAKE_IMM(INAT_IMM_QWORD)" | ||
| 56 | imm_flag["Ap"] = "INAT_MAKE_IMM(INAT_IMM_PTR)" | ||
| 57 | imm_flag["Iz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)" | ||
| 58 | imm_flag["Jz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)" | ||
| 59 | imm_flag["Iv"] = "INAT_MAKE_IMM(INAT_IMM_VWORD)" | ||
| 60 | imm_flag["Ob"] = "INAT_MOFFSET" | ||
| 61 | imm_flag["Ov"] = "INAT_MOFFSET" | ||
| 62 | imm_flag["Lx"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)" | ||
| 63 | |||
| 64 | modrm_expr = "^([CDEGMNPQRSUVW/][a-z]+|NTA|T[012])" | ||
| 65 | force64_expr = "\\([df]64\\)" | ||
| 66 | rex_expr = "^REX(\\.[XRWB]+)*" | ||
| 67 | fpu_expr = "^ESC" # TODO | ||
| 68 | |||
| 69 | lprefix1_expr = "\\((66|!F3)\\)" | ||
| 70 | lprefix2_expr = "\\(F3\\)" | ||
| 71 | lprefix3_expr = "\\((F2|!F3|66\\&F2)\\)" | ||
| 72 | lprefix_expr = "\\((66|F2|F3)\\)" | ||
| 73 | max_lprefix = 4 | ||
| 74 | |||
| 75 | # All opcodes starting with lower-case 'v' or with (v1) superscript | ||
| 76 | # accepts VEX prefix | ||
| 77 | vexok_opcode_expr = "^v.*" | ||
| 78 | vexok_expr = "\\(v1\\)" | ||
| 79 | # All opcodes with (v) superscript supports *only* VEX prefix | ||
| 80 | vexonly_expr = "\\(v\\)" | ||
| 81 | |||
| 82 | prefix_expr = "\\(Prefix\\)" | ||
| 83 | prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ" | ||
| 84 | prefix_num["REPNE"] = "INAT_PFX_REPNE" | ||
| 85 | prefix_num["REP/REPE"] = "INAT_PFX_REPE" | ||
| 86 | prefix_num["XACQUIRE"] = "INAT_PFX_REPNE" | ||
| 87 | prefix_num["XRELEASE"] = "INAT_PFX_REPE" | ||
| 88 | prefix_num["LOCK"] = "INAT_PFX_LOCK" | ||
| 89 | prefix_num["SEG=CS"] = "INAT_PFX_CS" | ||
| 90 | prefix_num["SEG=DS"] = "INAT_PFX_DS" | ||
| 91 | prefix_num["SEG=ES"] = "INAT_PFX_ES" | ||
