]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/udis86/lib/contrib/udcli/udcli.c
Update
[l4.git] / l4 / pkg / udis86 / lib / contrib / udcli / udcli.c
1 /* udis86 - udcli/udcli.c
2  *
3  * Copyright (c) 2002-2013 Vivek Thampi
4  * All rights reserved.
5  * 
6  * Redistribution and use in source and binary forms, with or without modification, 
7  * are permitted provided that the following conditions are met:
8  * 
9  *     * Redistributions of source code must retain the above copyright notice, 
10  *       this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above copyright notice, 
12  *       this list of conditions and the following disclaimer in the documentation 
13  *       and/or other materials provided with the distribution.
14  * 
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
18  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 
19  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
22  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
24  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <ctype.h>
30 #ifdef _MSC_VER
31 #include "..\udis86.h"
32 #define PACKAGE_STRING "udis86 pre-1.8"
33 #else
34 #include <udis86.h>
35 #include <config.h>
36 #endif
37
38 #if defined(__APPLE__)
39 # define FMT64 "ll" 
40 #elif defined(__amd64__) || defined(__x86_64__)
41 # define FMT64 "l" 
42 # else
43 # define FMT64 "ll" 
44 #endif
45
46 #if defined(__DJGPP__) || defined(_WIN32)
47 # include <io.h>
48 # include <fcntl.h>
49 #endif 
50
51 #ifdef __DJGPP__
52 # include <unistd.h>  /* for isatty() */
53 # define _setmode setmode
54 # define _fileno fileno
55 # define _O_BINARY O_BINARY
56 #endif
57
58 /* help string */
59 static char help[] = 
60 {
61   "Usage: %s [-option[s]] file\n"
62   "Options:\n"
63   "    -16      : Set the disassembly mode to 16 bits. \n"
64   "    -32      : Set the disassembly mode to 32 bits. (default)\n"
65   "    -64      : Set the disassembly mode to 64 bits.\n"
66   "    -intel   : Set the output to INTEL (NASM like) syntax. (default)\n"
67   "    -att     : Set the output to AT&T (GAS like) syntax.\n"
68   "    -v <v>   : Set vendor. <v> = {intel, amd}.\n"
69   "    -o <pc>  : Set the value of program counter to <pc>. (default = 0)\n"
70   "    -s <n>   : Set the number of bytes to skip before disassembly to <n>.\n"
71   "    -c <n>   : Set the number of bytes to disassemble to <n>.\n"
72   "    -x       : Set the input mode to whitespace separated 8-bit numbers in\n"
73   "               hexadecimal representation. Example: 0f 01 ae 00\n"
74   "    -noff    : Do not display the offset of instructions.\n"
75   "    -nohex   : Do not display the hexadecimal code of instructions.\n"
76   "    -h       : Display this help message.\n"
77   "    --version: Show version.\n"
78   "\n"
79   "Udcli is a front-end to the Udis86 Disassembler Library.\n" 
80   "http://udis86.sourceforge.net/\n"
81 };
82
83 FILE* fptr = NULL;
84 uint64_t o_skip = 0;
85 uint64_t o_count = 0;
86 unsigned char o_do_count= 0;
87 unsigned char o_do_off = 1;
88 unsigned char o_do_hex = 1;
89 unsigned char o_do_x = 0;
90 unsigned o_vendor = UD_VENDOR_AMD;
91
92 int input_hook_x(ud_t* u);
93 int input_hook_file(ud_t* u);
94
95 int main(int argc, char **argv)
96 {
97   char *prog_path = *argv;
98   char *s;
99   ud_t ud_obj;
100
101   /* initialize */
102   ud_init(&ud_obj);
103   ud_set_mode(&ud_obj, 32);
104   ud_set_syntax(&ud_obj, UD_SYN_INTEL);
105
106 #ifdef __DJGPP__
107   if ( !isatty( fileno( stdin ) ) )
108 #endif
109 #if defined(__DJGPP) || defined(_WIN32)
110   _setmode(_fileno(stdin), _O_BINARY);
111 #endif  
112
113   fptr = stdin;
114
115   argv++;
116
117   /* loop through the args */
118   while(--argc > 0) {
119     if (strcmp(*argv, "-h") == 0) {
120         printf(help, prog_path);
121         exit(EXIT_SUCCESS);
122     } else if (strcmp(*argv,"-16") == 0) {
123                 ud_set_mode(&ud_obj, 16);
124         } else if (strcmp(*argv,"-32") == 0) {
125                 ud_set_mode(&ud_obj, 32);
126         } else if (strcmp(*argv,"-64") == 0) {
127                 ud_set_mode(&ud_obj, 64);
128         } else if (strcmp(*argv,"-intel") == 0)
129                 ud_set_syntax(&ud_obj, UD_SYN_INTEL);
130         else if (strcmp(*argv,"-att") == 0)
131                 ud_set_syntax(&ud_obj, UD_SYN_ATT);
132         else if (strcmp(*argv,"-noff") == 0)
133                 o_do_off = 0;
134         else if (strcmp(*argv,"-nohex") == 0)
135                 o_do_hex = 0;
136         else if (strcmp(*argv,"-x") == 0)
137                 o_do_x = 1;
138         else if (strcmp(*argv,"-s") == 0)
139                 if (--argc) {
140                         s = *(++argv);
141                         if (sscanf(s, "%"  FMT64 "u", &o_skip) == 0)
142                                 fprintf(stderr, "Invalid value given for -s.\n");
143                 } else { 
144                         fprintf(stderr, "No value given for -s.\n");
145                         printf(help, prog_path);
146                         exit(EXIT_FAILURE);
147                 }
148         else if (strcmp(*argv,"-c") == 0)
149                 if (--argc) {
150                         o_do_count= 1;
151                         s = *(++argv);
152                         if (sscanf(s, "%" FMT64 "u", &o_count) == 0)
153                                 fprintf(stderr, "Invalid value given for -c.\n");
154                 } else { 
155                         fprintf(stderr, "No value given for -c.\n");
156                         printf(help, prog_path);
157                         exit(EXIT_FAILURE);
158                 }
159         else if (strcmp(*argv,"-v") == 0)
160                 if (--argc) {
161                         s = *(++argv);
162                         if (*s == 'i')
163                                 ud_set_vendor(&ud_obj, UD_VENDOR_INTEL);
164                 } else { 
165                         fprintf(stderr, "No value given for -v.\n");
166                         printf(help, prog_path);
167                         exit(EXIT_FAILURE);
168                 }
169         else if (strcmp(*argv,"-o") == 0) {
170                 if (--argc) {
171                         uint64_t pc = 0;
172                         s = *(++argv);
173                         if (sscanf(s, "%" FMT64 "x", &pc) == 0)
174                                 fprintf(stderr, "Invalid value given for -o.\n");
175                         ud_set_pc(&ud_obj, pc);
176                 } else { 
177                         fprintf(stderr, "No value given for -o.\n");
178                         printf(help, prog_path);
179                         exit(EXIT_FAILURE);
180                 }
181         } else if ( strcmp( *argv, "--version" ) == 0 ) {
182                 fprintf(stderr, "%s\n", PACKAGE_STRING );
183                 exit(0);
184         } else if((*argv)[0] == '-') {
185                 fprintf(stderr, "Invalid option %s.\n", *argv);
186                 printf(help, prog_path);
187                 exit(EXIT_FAILURE);
188         } else {
189                 static int i = 0;
190                 s = *argv;
191                 if (i) {
192                         fprintf(stderr, "Multiple files specified.\n");
193                         exit(EXIT_FAILURE);
194                 } else i = 1;
195                 if ((fptr = fopen(s, "rb")) == NULL) {
196                         fprintf(stderr, "Failed to open file: %s.\n", s);
197                                 exit(EXIT_FAILURE);
198                 }
199         }
200         argv++;
201   }
202
203   if (o_do_x)
204         ud_set_input_hook(&ud_obj, input_hook_x);
205   else  ud_set_input_hook(&ud_obj, input_hook_file);    
206
207   if (o_skip) {
208         o_count += o_skip;
209         ud_input_skip(&ud_obj, o_skip);
210   }
211
212   /* disassembly loop */
213   while (ud_disassemble(&ud_obj)) {
214         if (o_do_off)
215                 printf("%016" FMT64 "x ", ud_insn_off(&ud_obj));
216         if (o_do_hex) {
217                 const char* hex1, *hex2;
218                 hex1 = ud_insn_hex(&ud_obj);
219                 hex2 = hex1 + 16;
220                 printf("%-16.16s %-24s", hex1, ud_insn_asm(&ud_obj));
221                 if (strlen(hex1) > 16) {
222                         printf("\n");
223                         if (o_do_off)
224                                 printf("%15s -", "");
225                         printf("%-16s", hex2);
226                 }
227         } 
228         else printf(" %-24s", ud_insn_asm(&ud_obj));
229
230         printf("\n");
231   }
232   
233   exit(EXIT_SUCCESS);
234   return 0;
235 }
236
237 int input_hook_x(ud_t* u)
238 {
239   unsigned int c, i;
240
241   if (o_do_count) {
242         if (! o_count)
243                 return UD_EOI;
244         else --o_count;
245   }
246
247   i = fscanf(fptr, "%x", &c);
248
249   if (i == EOF)
250         return UD_EOI;
251   if (i == 0) {
252         fprintf(stderr, "Error: Invalid input, should be in hexadecimal form (8-bit).\n");
253         return UD_EOI;
254   }
255   if (c > 0xFF)
256         fprintf(stderr, "Warning: Casting non-8-bit input (%x), to %x.\n", c, c & 0xFF);
257   return (int) (c & 0xFF);
258 }       
259
260 int input_hook_file(ud_t* u)
261 {
262   int c;
263
264   if (o_do_count) {
265           if (! o_count) {
266                 return -1;
267           } else o_count -- ;
268   }
269
270   if ((c = fgetc(fptr)) == EOF)
271         return UD_EOI;
272   return c;
273 }