2 Intel Open Source License
4 Copyright (c) 2002-2007 Intel Corporation
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are
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.
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.
32 /// @author Mark Charney <mark.charney@intel.com>
35 ////////////////////////////////////////////////////////////////////////////
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();
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"
58 int main(int argc, char** argv);
60 ////////////////////////////////////////////////////////////////////////////
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);
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,
77 XED_MAX_INSTRUCTION_BYTES);
78 return disas_decode_encode_binary(dstate, hex_decode_text, bytes, xedd);
81 static unsigned int disas_encode(const xed_state_t* dstate,
82 const char* encode_text) {
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);
89 xed_encode_request_print(&req, buf, 5000);
90 printf("Request: %s", buf);
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");
104 else if (CLIENT_VERBOSE) {
106 xed_print_hex_line(buf2,array, olen);
107 printf("Encodable! %s\n", buf2);
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
124 static void xed_assemble(const xed_state_t* dstate,
125 const char* encode_file_name) {
126 ifstream infile(encode_file_name);
128 printf("Could not open %s\n", encode_file_name);
129 xedex_derror("Dieing");
132 while(infile.getline(buf,sizeof(buf))) {
133 printf("; %s\n",buf);
135 if (strlen(buf) == 0)
138 ascii_encode_request_t areq;
139 areq.dstate = *dstate;
141 xed_encoder_request_t req = parse_encode_request(areq);
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");
152 for(unsigned int i=0;i<olen;i++) {
155 printf("0x%02x",array[i]);
161 static void usage(char* prog) {
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)",
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)",
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)",
189 // "\t-nofeedback (turn off feedback for builds that actually use feedback)",
194 cerr << "Usage: " << prog << " [options]" << endl;
195 for(i=0; usage_msg[i] ; i++)
196 cerr << "\t" << usage_msg[i] << endl;
204 xed_uint64_t v = 0x11223344;
207 xed_immdis_init(&i,8);
208 xed_immdis_add_shortest_width_signed(&i,v,4);
209 xed_immdis_print(&i,buf,1000);
213 xed_immdis_add_shortest_width_unsigned(&i,uv,5);
214 xed_immdis_print(&i,buf,1000);
220 xed_immdis_add_shortest_width_signed(&i,sv,5);
221 xed_immdis_print(&i,buf,1000);
227 xed_immdis_add_shortest_width_signed(&i,sv,5);
228 xed_immdis_print(&i,buf,1000);
234 xed_immdis_add_shortest_width_signed(&i,sv,5);
235 xed_immdis_print(&i,buf,1000);
240 xed_immdis_add_shortest_width_unsigned(&i,uv,5);
241 xed_immdis_print(&i,buf,1000);
244 #if !defined(_MSC_VER) // MSVS6 VC98 chokes on the LL. Just punt on MS compilers
247 sv = 0xffffffff81223344LL;
248 xed_immdis_add_shortest_width_signed(&i,sv,4);
249 xed_immdis_print(&i,buf,1000);
251 v = 0x1122334455667788ULL;
253 xed_immdis_add_shortest_width_signed(&i,sv,4);
254 xed_immdis_print(&i,buf,1000);
260 xed_immdis_add_shortest_width_signed(&i,v,4);
261 xed_immdis_print(&i,buf,1000);
266 xed_immdis_add_shortest_width_signed(&i,v,4);
268 xed_immdis_print(&i,buf,1000);
273 xed_immdis_add_shortest_width_signed(&i,v,4);
275 xed_immdis_print(&i,buf,1000);
280 xed_immdis_add_shortest_width_signed(&i,v,4);
282 xed_immdis_print(&i,buf,1000);
288 xed_immdis_add_shortest_width_signed(&i,v,3);
290 xed_immdis_print(&i,buf,1000);
295 xed_immdis_add_shortest_width_signed(&i,v,2);
297 xed_immdis_print(&i,buf,1000);
302 xed_immdis_add_shortest_width_signed(&i,v,2);
303 xed_immdis_print(&i,buf,1000);
309 xed_immdis_add_shortest_width_signed(&i,v,7);
310 xed_immdis_print(&i,buf,1000);
315 xed_immdis_add_shortest_width_signed(&i,v,5);
316 xed_immdis_print(&i,buf,1000);
321 xed_immdis_add_shortest_width_signed(&i,v,7);
322 xed_immdis_print(&i,buf,1000);
330 void remove_spaces(string& s) {
331 string::size_type i,p=0,len = s.size();
338 void test_argc(int i, int argc) {
340 xedex_derror("Need more arguments. Use \"xed -help\" for usage.");
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("");
350 xed_bool_t encode = false;
351 unsigned int ninst = 100*1000*1000; // FIXME: should use maxint...
352 xed_bool_t decode_encode = false;
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);
365 xed_set_verbosity( client_verbose );
366 for( i=1;i<argc;i++) {
367 if (strcmp(argv[i],"-d")==0) {
369 for(j=i+1; j< argc;j++)
370 decode_text = decode_text + argv[j];
371 break; // leave the i=1...argc loop
373 else if (strcmp(argv[i],"-de")==0) {
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
380 else if (strcmp(argv[i],"-i")==0) {
382 input_file_name = argv[i+1];
385 else if (strcmp(argv[i],"-s")==0) {
387 target_section = argv[i+1];
390 else if (strcmp(argv[i],"-ir")==0) {
392 input_file_name = argv[i+1];
396 else if (strcmp(argv[i],"-ie")==0) {
398 input_file_name = argv[i+1];
402 else if (strcmp(argv[i],"-ide")==0) {
404 input_file_name = argv[i+1];
408 else if (strcmp(argv[i],"-n") ==0) {
410 ninst = STATIC_CAST(unsigned int,xed_atoi_general(argv[i+1],1000));
413 else if (strcmp(argv[i],"-loop") ==0) {
415 loop_decode = STATIC_CAST(unsigned int,xed_atoi_general(argv[i+1],1000));
418 else if (strcmp(argv[i],"-v") ==0) {
420 client_verbose = STATIC_CAST(int,xed_atoi_general(argv[i+1],1000));
421 xed_set_verbosity(client_verbose);
425 else if (strcmp(argv[i],"-xv") ==0) {
427 unsigned int xed_engine_verbose = STATIC_CAST(unsigned int,xed_atoi_general(argv[i+1],1000));
428 xed_set_verbosity(xed_engine_verbose);
431 else if (strcmp(argv[i],"-A")==0) {
433 xed_syntax = intel_syntax = false;
435 else if (strcmp(argv[i],"-I")==0) {
437 xed_syntax = att_syntax = false;
439 else if (strcmp(argv[i],"-X") == 0) { // undocumented
444 else if (strcmp(argv[i],"-16")==0) {
445 sixty_four_bit = false;
446 dstate.mmode = XED_MACHINE_MODE_LEGACY_16;
448 else if (strcmp(argv[i],"-32")==0) { // default
449 sixty_four_bit = false;
450 dstate.mmode = XED_MACHINE_MODE_LEGACY_32;
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;
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) {
467 xed_set_verbosity(5);
471 else if (strcmp(argv[i],"-e") ==0) {
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
485 if (input_file_name == 0 && decode_text == "") {
486 cerr << "ERROR: required argument(s) were missing" << endl;
492 printf("Initializing XED tables...\n");
495 printf("Done initialing XED tables.\n");
497 printf("#XED version: [%s]\n", xed_get_version());
498 xed_decoded_inst_t xedd;
499 xed_decoded_inst_zero_set_mode(&xedd, &dstate);
501 xed_uint_t retval_okay = 1;
502 unsigned int obytes=0;
504 xed_assemble(&dstate, input_file_name);
506 else if (decode_encode) {
507 obytes = disas_decode_encode(&dstate, decode_text.c_str(), &xedd);
508 retval_okay = (obytes != 0) ? 1 : 0;
511 obytes = disas_encode(&dstate, encode_text.c_str());
512 else if (decode_text != "") {
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();
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
526 retval_okay = disas_decode(&dstate, p, &xedd);
527 unsigned int len = xed_decoded_inst_get_length(&xedd);
531 while(retval_okay && remaining > 0);
534 else if (decode_raw) {
535 xed_disas_raw(input_file_name, &dstate, ninst, sixty_four_bit, decode_only);
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,
544 #elif defined(XED_PECOFF_FILE_READER)
545 xed_disas_pecoff(input_file_name, &dstate, ninst, sixty_four_bit, decode_only,
548 xedex_derror("No PECOFF, ELF or MACHO support compiled in");
551 //xed_decode_traverse_dump_profile();
560 ////////////////////////////////////////////////////////////////////////////