diff options
-rw-r--r-- | arch/x86/tools/Makefile | 9 | ||||
-rw-r--r-- | arch/x86/tools/test_get_len.c | 74 |
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 @@ | |||
1 | PHONY += posttest | 1 | PHONY += posttest |
2 | |||
3 | ifeq ($(KBUILD_VERBOSE),1) | ||
4 | postest_verbose = -v | ||
5 | else | ||
6 | postest_verbose = | ||
7 | endif | ||
8 | |||
2 | quiet_cmd_posttest = TEST $@ | 9 | quiet_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 | ||
5 | posttest: $(obj)/test_get_len vmlinux | 12 | posttest: $(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 | ||
38 | const char *prog; | 39 | const char *prog; |
40 | static int verbose; | ||
41 | static int x86_64; | ||
39 | 42 | ||
40 | static void usage(void) | 43 | static 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 | ||
59 | static 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 | |||
70 | static 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 | |||
88 | static 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 | ||
55 | int main(int argc, char **argv) | 111 | int 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 | } |