x86: Fix x86 instruction decoder selftest to check only .text
[pandora-kernel.git] / arch / x86 / tools / test_get_len.c
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or
5  * (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15  *
16  * Copyright (C) IBM Corporation, 2009
17  */
18
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <assert.h>
23
24 #ifdef __x86_64__
25 #define CONFIG_X86_64
26 #else
27 #define CONFIG_X86_32
28 #endif
29 #define unlikely(cond) (cond)
30
31 #include <asm/insn.h>
32 #include <inat.c>
33 #include <insn.c>
34
35 /*
36  * Test of instruction analysis in general and insn_get_length() in
37  * particular.  See if insn_get_length() and the disassembler agree
38  * on the length of each instruction in an elf disassembly.
39  *
40  * Usage: objdump -d a.out | awk -f distill.awk | ./test_get_len
41  */
42
43 const char *prog;
44
45 static void usage(void)
46 {
47         fprintf(stderr, "Usage: objdump -d a.out | awk -f distill.awk |"
48                 " ./test_get_len\n");
49         exit(1);
50 }
51
52 static void malformed_line(const char *line, int line_nr)
53 {
54         fprintf(stderr, "%s: malformed line %d:\n%s", prog, line_nr, line);
55         exit(3);
56 }
57
58 #define BUFSIZE 256
59
60 int main(int argc, char **argv)
61 {
62         char line[BUFSIZE];
63         unsigned char insn_buf[16];
64         struct insn insn;
65         int insns = 0;
66
67         prog = argv[0];
68         if (argc > 1)
69                 usage();
70
71         while (fgets(line, BUFSIZE, stdin)) {
72                 char copy[BUFSIZE], *s, *tab1, *tab2;
73                 int nb = 0;
74                 unsigned int b;
75
76                 insns++;
77                 memset(insn_buf, 0, 16);
78                 strcpy(copy, line);
79                 tab1 = strchr(copy, '\t');
80                 if (!tab1)
81                         malformed_line(line, insns);
82                 s = tab1 + 1;
83                 s += strspn(s, " ");
84                 tab2 = strchr(s, '\t');
85                 if (!tab2)
86                         malformed_line(line, insns);
87                 *tab2 = '\0';   /* Characters beyond tab2 aren't examined */
88                 while (s < tab2) {
89                         if (sscanf(s, "%x", &b) == 1) {
90                                 insn_buf[nb++] = (unsigned char) b;
91                                 s += 3;
92                         } else
93                                 break;
94                 }
95                 /* Decode an instruction */
96 #ifdef __x86_64__
97                 insn_init(&insn, insn_buf, 1);
98 #else
99                 insn_init(&insn, insn_buf, 0);
100 #endif
101                 insn_get_length(&insn);
102                 if (insn.length != nb) {
103                         fprintf(stderr, "Error: %s", line);
104                         fprintf(stderr, "Error: objdump says %d bytes, but "
105                                 "insn_get_length() says %d (attr:%x)\n", nb,
106                                 insn.length, insn.attr);
107                         exit(2);
108                 }
109         }
110         fprintf(stderr, "Succeed: decoded and checked %d instructions\n",
111                 insns);
112         return 0;
113 }