aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/tools
diff options
context:
space:
mode:
authorMasami Hiramatsu <mhiramat@redhat.com>2009-11-16 18:06:18 -0500
committerIngo Molnar <mingo@elte.hu>2009-11-17 01:16:48 -0500
commitd65ff75fbe6f8ac7c17f18e4108521898468822c (patch)
treecd118586583d8699afb5153514224a9fd5c0268a /arch/x86/tools
parent444a2a3bcd6d5bed5c823136f68fcc93c0fe283f (diff)
x86: Add verbose option to insn decoder test
Add verbose option to insn decoder test. This dumps decoded instruction when building kernel with V=1. Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com> Cc: systemtap <systemtap@sources.redhat.com> Cc: DLE <dle-develop@lists.sourceforge.net> Cc: Stephen Rothwell <sfr@canb.auug.org.au> Cc: Randy Dunlap <rdunlap@xenotime.net> Cc: Jim Keniston <jkenisto@us.ibm.com> Cc: Stephen Rothwell <sfr@canb.auug.org.au> LKML-Reference: <20091116230618.5250.18762.stgit@harusame> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/tools')
-rw-r--r--arch/x86/tools/Makefile9
-rw-r--r--arch/x86/tools/test_get_len.c74
2 files changed, 71 insertions, 12 deletions
diff --git a/arch/x86/tools/Makefile b/arch/x86/tools/Makefile
index 5e295d95dc25..4688f90ce5a2 100644
--- a/arch/x86/tools/Makefile
+++ b/arch/x86/tools/Makefile
@@ -1,6 +1,13 @@
1PHONY += posttest 1PHONY += posttest
2
3ifeq ($(KBUILD_VERBOSE),1)
4 postest_verbose = -v
5else
6 postest_verbose =
7endif
8
2quiet_cmd_posttest = TEST $@ 9quiet_cmd_posttest = TEST $@
3 cmd_posttest = $(OBJDUMP) -d -j .text $(objtree)/vmlinux | awk -f $(srctree)/arch/x86/tools/distill.awk | $(obj)/test_get_len $(CONFIG_64BIT) 10 cmd_posttest = $(OBJDUMP) -d -j .text $(objtree)/vmlinux | awk -f $(srctree)/arch/x86/tools/distill.awk | $(obj)/test_get_len -$(CONFIG_64BIT) $(posttest_verbose)
4 11
5posttest: $(obj)/test_get_len vmlinux 12posttest: $(obj)/test_get_len vmlinux
6 $(call cmd,posttest) 13 $(call cmd,posttest)
diff --git a/arch/x86/tools/test_get_len.c b/arch/x86/tools/test_get_len.c
index 376d33852191..5743e5128d35 100644
--- a/arch/x86/tools/test_get_len.c
+++ b/arch/x86/tools/test_get_len.c
@@ -20,6 +20,7 @@
20#include <stdio.h> 20#include <stdio.h>
21#include <string.h> 21#include <string.h>
22#include <assert.h> 22#include <assert.h>
23#include <unistd.h>
23 24
24#define unlikely(cond) (cond) 25#define unlikely(cond) (cond)
25 26
@@ -36,11 +37,16 @@
36 */ 37 */
37 38
38const char *prog; 39const char *prog;
40static int verbose;
41static int x86_64;
39 42
40static void usage(void) 43static void usage(void)
41{ 44{
42 fprintf(stderr, "Usage: objdump -d a.out | awk -f distill.awk |" 45 fprintf(stderr, "Usage: objdump -d a.out | awk -f distill.awk |"
43 " %s [y|n](64bit flag)\n", prog); 46 " %s [-y|-n] [-v] \n", prog);
47 fprintf(stderr, "\t-y 64bit mode\n");
48 fprintf(stderr, "\t-n 32bit mode\n");
49 fprintf(stderr, "\t-v verbose mode\n");
44 exit(1); 50 exit(1);
45} 51}
46 52
@@ -50,6 +56,56 @@ static void malformed_line(const char *line, int line_nr)
50 exit(3); 56 exit(3);
51} 57}
52 58
59static void dump_field(FILE *fp, const char *name, const char *indent,
60 struct insn_field *field)
61{
62 fprintf(fp, "%s.%s = {\n", indent, name);
63 fprintf(fp, "%s\t.value = %d, bytes[] = {%x, %x, %x, %x},\n",
64 indent, field->value, field->bytes[0], field->bytes[1],
65 field->bytes[2], field->bytes[3]);
66 fprintf(fp, "%s\t.got = %d, .nbytes = %d},\n", indent,
67 field->got, field->nbytes);
68}
69
70static void dump_insn(FILE *fp, struct insn *insn)
71{
72 fprintf(fp, "Instruction = { \n");
73 dump_field(fp, "prefixes", "\t", &insn->prefixes);
74 dump_field(fp, "rex_prefix", "\t", &insn->rex_prefix);
75 dump_field(fp, "vex_prefix", "\t", &insn->vex_prefix);
76 dump_field(fp, "opcode", "\t", &insn->opcode);
77 dump_field(fp, "modrm", "\t", &insn->modrm);
78 dump_field(fp, "sib", "\t", &insn->sib);
79 dump_field(fp, "displacement", "\t", &insn->displacement);
80 dump_field(fp, "immediate1", "\t", &insn->immediate1);
81 dump_field(fp, "immediate2", "\t", &insn->immediate2);
82 fprintf(fp, "\t.attr = %x, .opnd_bytes = %d, .addr_bytes = %d,\n",
83 insn->attr, insn->opnd_bytes, insn->addr_bytes);
84 fprintf(fp, "\t.length = %d, .x86_64 = %d, .kaddr = %p}\n",
85 insn->length, insn->x86_64, insn->kaddr);
86}
87
88static void parse_args(int argc, char **argv)
89{
90 int c;
91 prog = argv[0];
92 while ((c = getopt(argc, argv, "ynv")) != -1) {
93 switch (c) {
94 case 'y':
95 x86_64 = 1;
96 break;
97 case 'n':
98 x86_64 = 0;
99 break;
100 case 'v':
101 verbose = 1;
102 break;
103 default:
104 usage();
105 }
106 }
107}
108
53#define BUFSIZE 256 109#define BUFSIZE 256
54 110
55int main(int argc, char **argv) 111int main(int argc, char **argv)
@@ -57,15 +113,9 @@ int main(int argc, char **argv)
57 char line[BUFSIZE]; 113 char line[BUFSIZE];
58 unsigned char insn_buf[16]; 114 unsigned char insn_buf[16];
59 struct insn insn; 115 struct insn insn;
60 int insns = 0; 116 int insns = 0, c;
61 int x86_64 = 0;
62
63 prog = argv[0];
64 if (argc > 2)
65 usage();
66 117
67 if (argc == 2 && argv[1][0] == 'y') 118 parse_args(argc, argv);
68 x86_64 = 1;
69 119
70 while (fgets(line, BUFSIZE, stdin)) { 120 while (fgets(line, BUFSIZE, stdin)) {
71 char copy[BUFSIZE], *s, *tab1, *tab2; 121 char copy[BUFSIZE], *s, *tab1, *tab2;
@@ -97,8 +147,10 @@ int main(int argc, char **argv)
97 if (insn.length != nb) { 147 if (insn.length != nb) {
98 fprintf(stderr, "Error: %s", line); 148 fprintf(stderr, "Error: %s", line);
99 fprintf(stderr, "Error: objdump says %d bytes, but " 149 fprintf(stderr, "Error: objdump says %d bytes, but "
100 "insn_get_length() says %d (attr:%x)\n", nb, 150 "insn_get_length() says %d\n", nb,
101 insn.length, insn.attr); 151 insn.length);
152 if (verbose)
153 dump_insn(stderr, &insn);
102 exit(2); 154 exit(2);
103 } 155 }
104 } 156 }