]> git.karo-electronics.de Git - mv-sheeva.git/blob - arch/x86/tools/test_get_len.c
Merge commit 'tracing/core' into tracing/kprobes
[mv-sheeva.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 #define unlikely(cond) (cond)
25
26 #include <asm/insn.h>
27 #include <inat.c>
28 #include <insn.c>
29
30 /*
31  * Test of instruction analysis in general and insn_get_length() in
32  * particular.  See if insn_get_length() and the disassembler agree
33  * on the length of each instruction in an elf disassembly.
34  *
35  * Usage: objdump -d a.out | awk -f distill.awk | ./test_get_len
36  */
37
38 const char *prog;
39
40 static void usage(void)
41 {
42         fprintf(stderr, "Usage: objdump -d a.out | awk -f distill.awk |"
43                 " %s [y|n](64bit flag)\n", prog);
44         exit(1);
45 }
46
47 static void malformed_line(const char *line, int line_nr)
48 {
49         fprintf(stderr, "%s: malformed line %d:\n%s", prog, line_nr, line);
50         exit(3);
51 }
52
53 #define BUFSIZE 256
54
55 int main(int argc, char **argv)
56 {
57         char line[BUFSIZE];
58         unsigned char insn_buf[16];
59         struct insn insn;
60         int insns = 0;
61         int x86_64 = 0;
62
63         prog = argv[0];
64         if (argc > 2)
65                 usage();
66
67         if (argc == 2 && argv[1][0] == 'y')
68                 x86_64 = 1;
69
70         while (fgets(line, BUFSIZE, stdin)) {
71                 char copy[BUFSIZE], *s, *tab1, *tab2;
72                 int nb = 0;
73                 unsigned int b;
74
75                 insns++;
76                 memset(insn_buf, 0, 16);
77                 strcpy(copy, line);
78                 tab1 = strchr(copy, '\t');
79                 if (!tab1)
80                         malformed_line(line, insns);
81                 s = tab1 + 1;
82                 s += strspn(s, " ");
83                 tab2 = strchr(s, '\t');
84                 if (!tab2)
85                         malformed_line(line, insns);
86                 *tab2 = '\0';   /* Characters beyond tab2 aren't examined */
87                 while (s < tab2) {
88                         if (sscanf(s, "%x", &b) == 1) {
89                                 insn_buf[nb++] = (unsigned char) b;
90                                 s += 3;
91                         } else
92                                 break;
93                 }
94                 /* Decode an instruction */
95                 insn_init(&insn, insn_buf, x86_64);
96                 insn_get_length(&insn);
97                 if (insn.length != nb) {
98                         fprintf(stderr, "Error: %s", line);
99                         fprintf(stderr, "Error: objdump says %d bytes, but "
100                                 "insn_get_length() says %d (attr:%x)\n", nb,
101                                 insn.length, insn.attr);
102                         exit(2);
103                 }
104         }
105         fprintf(stderr, "Succeed: decoded and checked %d instructions\n",
106                 insns);
107         return 0;
108 }