Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Release 1.0
[palacios.git] / misc / decoder_test / XED2 / examples / xed.cpp
1 /*BEGIN_LEGAL 
2 Intel Open Source License 
3
4 Copyright (c) 2002-2007 Intel Corporation 
5 All rights reserved. 
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are
8 met:
9
10 Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.  Redistributions
12 in binary form must reproduce the above copyright notice, this list of
13 conditions and the following disclaimer in the documentation and/or
14 other materials provided with the distribution.  Neither the name of
15 the Intel Corporation nor the names of its contributors may be used to
16 endorse or promote products derived from this software without
17 specific prior written permission.
18  
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
23 ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 END_LEGAL */
31 /// @file xed.cpp
32 /// @author Mark Charney   <mark.charney@intel.com>
33
34
35 ////////////////////////////////////////////////////////////////////////////
36 extern "C" {
37 #include "xed-interface.h"
38 #include "xed-immdis.h"
39 #include "xed-portability.h"
40 #include "xed-examples-util.h"
41 //void xed_decode_traverse_dump_profile();
42 }
43
44 #include "xed-disas-elf.H"
45 #include "xed-disas-macho.H"
46 #include "xed-disas-pecoff.H"
47 #include "xed-disas-raw.H"
48 #include "xed-enc-lang.H"
49
50 #include <vector>
51 #include <iostream>
52 #include <iomanip>
53 #include <sstream>
54
55 using namespace std;
56
57
58 int main(int argc, char** argv);
59
60 ////////////////////////////////////////////////////////////////////////////
61
62 static xed_uint_t disas_decode(const xed_state_t* dstate,
63                            const char* decode_text,
64                            xed_decoded_inst_t* xedd) {
65     xed_uint8_t hex_decode_text[XED_MAX_INSTRUCTION_BYTES];
66     xed_uint_t bytes = xed_convert_ascii_to_hex(decode_text, hex_decode_text,XED_MAX_INSTRUCTION_BYTES);
67     return  disas_decode_binary(dstate, hex_decode_text, bytes, xedd);
68 }
69
70
71 static unsigned int disas_decode_encode(const xed_state_t* dstate,
72                                         const char* decode_text,
73                                         xed_decoded_inst_t* xedd) {
74     xed_uint8_t hex_decode_text[XED_MAX_INSTRUCTION_BYTES];
75     xed_uint_t bytes = xed_convert_ascii_to_hex(decode_text,
76                                             hex_decode_text, 
77                                             XED_MAX_INSTRUCTION_BYTES);
78     return disas_decode_encode_binary(dstate, hex_decode_text, bytes, xedd);
79 }
80
81 static unsigned int disas_encode(const xed_state_t* dstate,
82                                  const char* encode_text) {
83     unsigned int olen=0;
84     ascii_encode_request_t areq;
85     areq.dstate = *dstate;
86     areq.command = encode_text;
87     xed_encoder_request_t req = parse_encode_request(areq);
88     char buf[5000];
89     xed_encode_request_print(&req, buf, 5000);
90     printf("Request: %s", buf);
91
92     
93     //for(xed_uint_t i=0;i< xed_encoder_request_operand_order_entries(&req);i++)
94     //   printf("REQUEST OPERAND ORDER ARRAY %d %s\n", 
95     //           i, xed_operand_enum_t2str( xed_encoder_request_get_operand_order(&req,i) ) );
96     xed_uint8_t array[XED_MAX_INSTRUCTION_BYTES];
97     unsigned int ilen = XED_MAX_INSTRUCTION_BYTES;
98     xed_error_enum_t r = xed_encode(&req, array, ilen, &olen);
99     if (r != XED_ERROR_NONE)     {
100         printf("Could not encode: %s\n", encode_text);
101         printf("Error code was: %s\n", xed_error_enum_t2str(r));
102         xedex_derror("Dieing");
103     }
104     else if (CLIENT_VERBOSE)   {
105         char buf2[100];
106         xed_print_hex_line(buf2,array, olen);
107         printf("Encodable! %s\n", buf2);
108     }
109     return olen;
110 }
111
112 static void no_comments(char* buf) {
113     size_t len = strlen(buf);
114     for(size_t i=0;i<len;i++) {
115         if (buf[i] == ';' || buf[i] == '#') {
116             buf[i]= 0; // stomp on it
117             return;
118         }
119     }
120 }
121
122
123 #include <fstream>
124 static void xed_assemble(const xed_state_t* dstate,
125                          const char* encode_file_name) {
126     ifstream infile(encode_file_name);
127     if (!infile) {
128         printf("Could not open %s\n", encode_file_name);
129         xedex_derror("Dieing");
130     }
131     char buf[1024];
132     while(infile.getline(buf,sizeof(buf))) {
133         printf("; %s\n",buf);
134         no_comments(buf);
135         if (strlen(buf) == 0)
136             continue;
137         unsigned int olen=0;
138         ascii_encode_request_t areq;
139         areq.dstate = *dstate;
140         areq.command = buf;
141         xed_encoder_request_t req = parse_encode_request(areq);
142  
143         xed_uint8_t array[XED_MAX_INSTRUCTION_BYTES];
144         unsigned int ilen = XED_MAX_INSTRUCTION_BYTES;
145         xed_error_enum_t r = xed_encode(&req, array, ilen, &olen);
146         if (r != XED_ERROR_NONE)     {
147             printf("Could not encode: %s\n", buf);
148             printf("Error code was: %s\n", xed_error_enum_t2str(r));
149             xedex_derror("Dieing");
150         }
151         printf("      .byte ");
152         for(unsigned int i=0;i<olen;i++) {
153             if (i > 0)
154                 printf(", ");
155             printf("0x%02x",array[i]);
156         }
157         printf("\n");
158     }
159 }
160
161 static void usage(char* prog) {
162     unsigned int i;
163     static const char* usage_msg[] = {
164       "One of the following is required:",
165       "\t-i input_file             (decode file)",
166       "\t-ir raw_input_file        (decode a raw unformatted binary file)",
167       "\t-ide input_file           (decode/encode file)",
168       "\t-d hex-string             (decode one instruction, must be last)",
169       "\t-e instruction            (encode, must be last)",
170       "\t-ie file-to-assemble      (assemble the contents of the file)",
171       "\t-de hex-string            (decode-then-encode, must be last)",
172       " ",
173       "Optional arguments:",
174       "\t-v verbosity  (0=quiet, 1=errors, 2=useful-info, 3=trace, 5=very verbose)",
175       "\t-xv xed-engine-verbosity  (0...99)",
176       "\t-s target section for file disassembly (PECOFF and ELF formats only)",
177
178       "\t-n number-of-instructions-to-decode (default 100M, accepts K/M/G qualifiers)",
179       "\t-I            (Intel syntax for disassembly)",
180       "\t-A            (ATT SYSV syntax for disassembly)",
181       "\t-16           (for LEGACY_16 mode)",
182       "\t-32           (for LEGACY_32 mode, default)",
183       "\t-64           (for LONG_64 mode w/64b addressing -- optional on windows/linux)",
184       "\t-a32          (32b addressing, default, not in LONG_64 mode)",
185       "\t-a16          (16b addressing, not in LONG_64 mode)",
186       "\t-s32          (32b stack addressing, default, not in LONG_64 mode)",
187       "\t-s16          (16b stack addressing, not in LONG_64 mode)",
188 //    " ",
189 //    "\t-nofeedback   (turn off feedback for builds that actually use feedback)",
190       " ",
191       0
192     };      
193
194     cerr << "Usage: " << prog << " [options]" << endl;
195     for(i=0; usage_msg[i]  ; i++)
196         cerr << "\t" << usage_msg[i] << endl;
197 }
198  
199 #if 1
200 void test_immdis() {
201     char buf[1000];
202     xed_int64_t sv;
203     xed_immdis_t i;
204     xed_uint64_t v = 0x11223344;
205     xed_uint32_t uv =0;
206
207     xed_immdis_init(&i,8);
208     xed_immdis_add_shortest_width_signed(&i,v,4);
209     xed_immdis_print(&i,buf,1000);
210     printf("%s\n",buf);
211
212     xed_immdis_zero(&i);
213     xed_immdis_add_shortest_width_unsigned(&i,uv,5);
214     xed_immdis_print(&i,buf,1000);
215     printf("%s\n",buf);
216
217     xed_immdis_zero(&i);
218
219     sv = 0x90;
220     xed_immdis_add_shortest_width_signed(&i,sv,5);
221     xed_immdis_print(&i,buf,1000);
222     printf("%s\n",buf);
223     
224     xed_immdis_zero(&i);
225
226     sv = -128;
227     xed_immdis_add_shortest_width_signed(&i,sv,5);
228     xed_immdis_print(&i,buf,1000);
229     printf("%s\n",buf);
230     
231     xed_immdis_zero(&i);
232
233     sv = -127;
234     xed_immdis_add_shortest_width_signed(&i,sv,5);
235     xed_immdis_print(&i,buf,1000);
236     printf("%s\n",buf);
237     
238     xed_immdis_zero(&i);
239     uv = 0x80000000;
240     xed_immdis_add_shortest_width_unsigned(&i,uv,5);
241     xed_immdis_print(&i,buf,1000);
242     printf("%s\n",buf);
243     
244 #if !defined(_MSC_VER) // MSVS6 VC98 chokes on the LL. Just punt on MS compilers
245     xed_immdis_zero(&i);
246
247     sv = 0xffffffff81223344LL;
248     xed_immdis_add_shortest_width_signed(&i,sv,4);
249     xed_immdis_print(&i,buf,1000);
250     printf("%s\n",buf);
251         v = 0x1122334455667788ULL;
252     xed_immdis_zero(&i);
253     xed_immdis_add_shortest_width_signed(&i,sv,4);
254     xed_immdis_print(&i,buf,1000);
255     printf("%s\n",buf);
256     #endif
257
258     v = 0x11223344;
259     xed_immdis_zero(&i);
260     xed_immdis_add_shortest_width_signed(&i,v,4);
261     xed_immdis_print(&i,buf,1000);
262     printf("%s\n",buf);
263     
264     v = 0x112233;
265     xed_immdis_zero(&i);
266     xed_immdis_add_shortest_width_signed(&i,v,4);
267
268     xed_immdis_print(&i,buf,1000);
269     printf("%s\n",buf);
270     
271     v = 0x1122;
272     xed_immdis_zero(&i);
273     xed_immdis_add_shortest_width_signed(&i,v,4);
274
275     xed_immdis_print(&i,buf,1000);
276     printf("%s\n",buf);
277     
278     v = 0x11;
279     xed_immdis_zero(&i);
280     xed_immdis_add_shortest_width_signed(&i,v,4);
281
282     xed_immdis_print(&i,buf,1000);
283     printf("%s\n",buf);
284     
285
286     v = 0x1122;
287     xed_immdis_zero(&i);
288     xed_immdis_add_shortest_width_signed(&i,v,3);
289
290     xed_immdis_print(&i,buf,1000);
291     printf("%s\n",buf);
292     
293     v = 0xffff;
294     xed_immdis_zero(&i);
295     xed_immdis_add_shortest_width_signed(&i,v,2);
296
297     xed_immdis_print(&i,buf,1000);
298     printf("%s\n",buf);
299     
300     v = 0xff00;
301     xed_immdis_zero(&i);
302     xed_immdis_add_shortest_width_signed(&i,v,2);
303     xed_immdis_print(&i,buf,1000);
304     printf("%s\n",buf);
305     
306
307     v = 0xff77;
308     xed_immdis_zero(&i);
309     xed_immdis_add_shortest_width_signed(&i,v,7);
310     xed_immdis_print(&i,buf,1000);
311     printf("%s\n",buf);
312     
313     v = 0xff7777;
314     xed_immdis_zero(&i);
315     xed_immdis_add_shortest_width_signed(&i,v,5);
316     xed_immdis_print(&i,buf,1000);
317     printf("%s\n",buf);
318     
319     v = 0xff8000;
320     xed_immdis_zero(&i);
321     xed_immdis_add_shortest_width_signed(&i,v,7);
322     xed_immdis_print(&i,buf,1000);
323     printf("%s\n",buf);
324     
325     exit(1);
326 }
327 #endif
328
329
330 void remove_spaces(string& s) {
331     string::size_type i,p=0,len = s.size();
332     for(i=0;i<len;i++)
333         if (s[i] != ' ')
334             s[p++]=s[i];
335     s = s.substr(0,p);
336 }
337
338 void test_argc(int i, int argc) {
339     if (i+1 >= argc)
340         xedex_derror("Need more arguments. Use \"xed -help\" for usage.");
341 }
342
343 int main(int argc,     char** argv) {
344     xed_bool_t sixty_four_bit = false;
345     xed_bool_t decode_only = true;
346     char* input_file_name = 0;
347     string decode_text("");
348     string encode_text("");
349     xed_state_t dstate;
350     xed_bool_t encode = false;
351     unsigned int ninst = 100*1000*1000; // FIXME: should use maxint...
352     xed_bool_t decode_encode = false;
353     int i,j;
354     unsigned int loop_decode = 0;
355     xed_bool_t decode_raw = false;
356     xed_bool_t assemble  = false;
357     char* target_section = 0;
358     xed_state_init(&dstate,
359                    XED_MACHINE_MODE_LEGACY_32,
360                    XED_ADDRESS_WIDTH_32b, 
361                    XED_ADDRESS_WIDTH_32b);
362
363
364     client_verbose = 3;
365     xed_set_verbosity( client_verbose );
366     for( i=1;i<argc;i++)    {
367         if (strcmp(argv[i],"-d")==0)         {
368             test_argc(i,argc);
369             for(j=i+1; j< argc;j++) 
370                 decode_text = decode_text + argv[j];
371             break; // leave the i=1...argc loop
372         }
373         else if (strcmp(argv[i],"-de")==0)        {
374             test_argc(i,argc);
375             decode_encode = true;
376             for(j=i+1; j< argc;j++) 
377                 decode_text = decode_text + argv[j];
378             break; // leave the i=1...argc loop
379         }
380         else if (strcmp(argv[i],"-i")==0)        {
381             test_argc(i,argc);
382             input_file_name = argv[i+1];
383             i++;
384         }
385         else if (strcmp(argv[i],"-s")==0)        {
386             test_argc(i,argc);
387             target_section = argv[i+1];
388             i++;
389         }
390         else if (strcmp(argv[i],"-ir")==0)        {
391             test_argc(i,argc);
392             input_file_name = argv[i+1];
393             decode_raw = true;
394             i++;
395         }
396         else if (strcmp(argv[i],"-ie")==0)        {
397             test_argc(i,argc);
398             input_file_name = argv[i+1];
399             assemble = true;
400             i++;
401         }
402         else if (strcmp(argv[i],"-ide")==0)        {
403             test_argc(i,argc);
404             input_file_name = argv[i+1];
405             decode_only = false;
406             i++;
407         }
408         else if (strcmp(argv[i],"-n") ==0)         {
409             test_argc(i,argc);
410             ninst = STATIC_CAST(unsigned int,xed_atoi_general(argv[i+1],1000));
411             i++;
412         }
413         else if (strcmp(argv[i],"-loop") ==0)         {
414             test_argc(i,argc);
415             loop_decode = STATIC_CAST(unsigned int,xed_atoi_general(argv[i+1],1000));
416             i++;
417         }
418         else if (strcmp(argv[i],"-v") ==0)         {
419             test_argc(i,argc);
420             client_verbose = STATIC_CAST(int,xed_atoi_general(argv[i+1],1000));
421             xed_set_verbosity(client_verbose);
422
423             i++;
424         }
425         else if (strcmp(argv[i],"-xv") ==0)        {
426             test_argc(i,argc);
427             unsigned int xed_engine_verbose = STATIC_CAST(unsigned int,xed_atoi_general(argv[i+1],1000));
428             xed_set_verbosity(xed_engine_verbose);
429             i++;
430         }
431         else if (strcmp(argv[i],"-A")==0)        {
432             att_syntax = true;
433             xed_syntax = intel_syntax = false;
434         }
435         else if (strcmp(argv[i],"-I")==0)        {
436             intel_syntax = true;
437             xed_syntax = att_syntax = false;
438         }
439         else if (strcmp(argv[i],"-X") == 0)  {  // undocumented
440             xed_syntax = true;
441             intel_syntax = true;
442             att_syntax = true;
443         }
444         else if (strcmp(argv[i],"-16")==0)         {
445             sixty_four_bit = false;
446             dstate.mmode = XED_MACHINE_MODE_LEGACY_16;
447         }
448         else if (strcmp(argv[i],"-32")==0) { // default
449             sixty_four_bit = false;
450             dstate.mmode = XED_MACHINE_MODE_LEGACY_32;
451         }
452         else if (strcmp(argv[i],"-64")==0)         {
453             sixty_four_bit = true;
454             dstate.mmode = XED_MACHINE_MODE_LONG_64;
455             dstate.addr_width = XED_ADDRESS_WIDTH_64b;
456         }
457         else if (strcmp(argv[i],"-a32")==0) 
458             dstate.addr_width = XED_ADDRESS_WIDTH_32b;
459         else if (strcmp(argv[i],"-a16")==0) 
460             dstate.addr_width = XED_ADDRESS_WIDTH_16b;
461         else if (strcmp(argv[i],"-s32")==0) 
462             dstate.stack_addr_width = XED_ADDRESS_WIDTH_32b;
463         else if (strcmp(argv[i],"-s16")==0) 
464             dstate.stack_addr_width = XED_ADDRESS_WIDTH_16b;
465         else if (strcmp(argv[i],"-ti") ==0)        {
466             client_verbose = 5;
467             xed_set_verbosity(5);
468             test_immdis();
469             exit(1);
470         }
471         else if (strcmp(argv[i],"-e") ==0)         {
472             encode = true;
473             test_argc(i,argc);
474             // merge the rest of the args in to the encode_text string.
475             for( j = i+1; j< argc; j++ ) 
476                 encode_text = encode_text + argv[j] + " ";
477             break;  // leave the loop
478         }
479         else          {
480             usage(argv[0]);
481             exit(1);
482         }
483     }
484     if (!encode)     {
485         if (input_file_name == 0 && decode_text == "")        {
486             cerr << "ERROR: required argument(s) were missing" << endl;
487             usage(argv[0]);
488             exit(1);
489         }
490     }
491     if (CLIENT_VERBOSE2)
492         printf("Initializing XED tables...\n");
493     xed_tables_init();
494     if (CLIENT_VERBOSE2)
495         printf("Done initialing XED tables.\n");
496
497     printf("#XED version: [%s]\n", xed_get_version());
498     xed_decoded_inst_t xedd;
499     xed_decoded_inst_zero_set_mode(&xedd, &dstate);
500
501     xed_uint_t retval_okay = 1;
502     unsigned int obytes=0;
503     if (assemble) {
504         xed_assemble(&dstate, input_file_name);
505     }
506     else if (decode_encode)     {
507         obytes = disas_decode_encode(&dstate, decode_text.c_str(), &xedd);
508         retval_okay = (obytes != 0) ? 1 : 0;
509     }
510     else if (encode) 
511         obytes = disas_encode(&dstate, encode_text.c_str());
512     else if (decode_text != "") {
513         if (loop_decode) {
514             unsigned int k;
515             for(k=0;k<loop_decode;k++) {
516                 retval_okay = disas_decode(&dstate, decode_text.c_str(), &xedd);
517                 xed_decoded_inst_zero_set_mode(&xedd, &dstate);
518                 //xed_decode_traverse_dump_profile();
519             }
520         }
521         else {
522             remove_spaces(decode_text);
523             const char* p = decode_text.c_str();
524             int remaining = static_cast<int>(decode_text.size() / 2); // 2 bytes per nibble
525             do {
526                 retval_okay = disas_decode(&dstate, p, &xedd);
527                 unsigned int  len = xed_decoded_inst_get_length(&xedd);
528                 p+=len*2;
529                 remaining -= len;
530             }
531             while(retval_okay && remaining > 0);
532         }
533     }
534     else if (decode_raw) {
535         xed_disas_raw(input_file_name, &dstate, ninst, sixty_four_bit, decode_only);
536     }
537     else     {
538
539 #if defined(XED_MAC_OSX_FILE_READER)
540         xed_disas_macho(input_file_name, &dstate, ninst, sixty_four_bit, decode_only);
541 #elif defined(XED_ELF_READER)
542         xed_disas_elf(input_file_name, &dstate, ninst, sixty_four_bit, decode_only, 
543                       target_section);
544 #elif defined(XED_PECOFF_FILE_READER)
545         xed_disas_pecoff(input_file_name, &dstate, ninst, sixty_four_bit, decode_only, 
546                          target_section);
547 #else
548         xedex_derror("No PECOFF, ELF or MACHO support compiled in");
549 #endif
550     }
551     //xed_decode_traverse_dump_profile();
552
553     if (retval_okay==0) 
554         exit(1);
555     return 0;
556     (void) obytes;
557 }
558  
559
560 ////////////////////////////////////////////////////////////////////////////