#include "xed/xed-interface.h"
#include "xed/xed-immdis.h"
#include "xed-examples-util.h"
#if defined(XED_ENCODER)
# include "xed-enc-lang.h"
#endif
#include "xed-disas-elf.h"
#include "xed-disas-macho.h"
#include "xed-disas-raw.h"
#include "xed-disas-hex.h"
#include "xed-disas-pecoff.h"
#include "xed-disas-filter.h"
#include "xed-symbol-table.h"
#include "xed-nm-symtab.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
int main(int argc, char** argv);
static int intel_asm_emit = 0;
#if defined(XED_DECODER)
static xed_uint_t disas_decode( xed_disas_info_t* di,
const char* decode_text,
xed_decoded_inst_t* xedd,
xed_uint64_t runtime_address)
{
xed_uint8_t hex_decode_text[XED_MAX_INSTRUCTION_BYTES];
xed_uint_t bytes = xed_convert_ascii_to_hex(decode_text,
hex_decode_text,
XED_MAX_INSTRUCTION_BYTES);
return disas_decode_binary(di,
hex_decode_text,
bytes,
xedd,
runtime_address);
}
#endif
#if defined(XED_DECODER) && defined(XED_ENCODER)
static unsigned int disas_decode_encode(xed_disas_info_t* di,
const char* decode_text,
xed_decoded_inst_t* xedd,
xed_uint64_t runtime_address)
{
xed_uint8_t hex_decode_text[XED_MAX_INSTRUCTION_BYTES];
xed_uint_t bytes = xed_convert_ascii_to_hex( decode_text,
hex_decode_text,
XED_MAX_INSTRUCTION_BYTES);
return disas_decode_encode_binary(di,
hex_decode_text,
bytes,
xedd,
runtime_address);
}
#endif
static FILE*
fopen_portable(char const* const file_name,
char const* const mode)
{
FILE* f = 0;
if ((file_name == 0) || (file_name[0] == 0))
return 0;
#if defined(XED_WINDOWS) && !defined(PIN_CRT)
errno_t error = fopen_s(&f, file_name, mode);
if (error != 0)
return 0;
#else
f = fopen(file_name, mode);
#endif
return f;
}
#if defined(XED_ENCODER)
static unsigned int disas_encode(const xed_state_t* dstate,
const char* encode_text,
xed_operand_enum_t* operands,
xed_uint32_t* operands_value,
xed_bool_t encode_force)
{
char buf[5000];
xed_uint8_t array[XED_MAX_INSTRUCTION_BYTES];
unsigned int ilen = XED_MAX_INSTRUCTION_BYTES;
unsigned int olen=0;
ascii_encode_request_t areq;
xed_encoder_request_t req;
xed_error_enum_t r;
unsigned int i;
areq.dstate = *dstate;
areq.command = encode_text;
req = parse_encode_request(areq);
for(i = 0; i < XED_MAX_INPUT_OPERNADS; i++) {
if (operands[i] != XED_OPERAND_INVALID)
xed3_set_generic_operand(&req, operands[i], operands_value[i]);
}
xed3_operand_set_encode_force(&req, encode_force);
xed_encode_request_print(&req, buf, 5000);
printf("Request: %s", buf);
r = xed_encode(&req, array, ilen, &olen);
if (r != XED_ERROR_NONE) {
printf("Could not encode: %s\n", encode_text);
printf("Error code was: %s\n", xed_error_enum_t2str(r));
xedex_derror("Dying");
}
else if (CLIENT_VERBOSE) {
char buf2[XED_HEX_BUFLEN];
xed_print_hex_line(buf2,array, olen,XED_HEX_BUFLEN);
printf("Encodable! %s\n", buf2);
if (intel_asm_emit)
xed_print_intel_asm_emit(array,olen);
else
xed_print_bytes_pseudo_op(array,olen);
}
return olen;
}
static void no_comments(char* buf) {
size_t i, len = strlen(buf);
for(i=0;i<len;i++) {
if (buf[i] == ';' || buf[i] == '#' ||
buf[i] == '\r' || buf[i] == '\n')
{
buf[i]= 0; return;
}
}
}
static void xed_assemble(const xed_state_t* dstate,
const char* encode_file_name)
{
#define ASM_BUF_SIZE 1024
const xed_int_t bsize = ASM_BUF_SIZE;
char buf[ASM_BUF_SIZE];
FILE* f;
if ((encode_file_name == 0) || (encode_file_name[0] == 0)) {
printf("illegal 'encode_file_name' file name\n");
xedex_derror("Dying");
}
f = fopen_portable(encode_file_name, "r");
if (!f) {
printf("Could not open %s\n", encode_file_name);
xedex_derror("Dying");
}
while(!feof(f) && fgets(buf, bsize, f))
{
unsigned int olen=0;
ascii_encode_request_t areq;
xed_encoder_request_t req;
xed_uint8_t array[XED_MAX_INSTRUCTION_BYTES];
const unsigned int ilen = XED_MAX_INSTRUCTION_BYTES;
xed_error_enum_t r;
unsigned int i;
printf("; %s\n",buf);
no_comments(buf);
if (strlen(buf) == 0)
continue;
areq.dstate = *dstate;
areq.command = buf;
req = parse_encode_request(areq);
r = xed_encode(&req, array, ilen, &olen);
if (r != XED_ERROR_NONE) {
printf("Could not encode: %s\n", buf);
printf("Error code was: %s\n", xed_error_enum_t2str(r));
xedex_derror("Dying");
}
printf(" .byte ");
for(i=0;i<olen;i++) {
if (i > 0)
printf(", ");
printf("0x%02x",array[i]);
}
printf("\n");
}
fclose(f);
}
#endif
static void emit_version(void) {
printf("%s\n", xed_get_copyright());
printf("XED version: [%s]\n\n", xed_get_version());
}
static void usage(char* prog) {
unsigned int i;
static const char* usage_msg[] = {
"One of the following is required:",
#if defined(__APPLE__)
"\t-i input_file (decode macho-format file)",
#elif defined(XED_ELF_READER)
"\t-i input_file (decode elf-format file)",
#elif defined(_WIN32)
"\t-i input_file (decode pecoff-format file)",
#endif
"\t-ir raw_input_file (decode a raw unformatted binary file)",
"\t-ih hex_input_file (decode a raw unformatted ASCII hex file)",
"\t-d hex-string (decode a sequence of bytes, must be last)",
"\t-j (just decode one instruction when using -d)",
"\t-F prefix (decode ascii hex bytes after prefix)",
"\t (running in filter mode from stdin)",
#if defined(XED_ENCODER)
"\t-ide input_file (decode/encode file)",
"\t-e instruction (encode, must be last)",
"\t-f (encode force, skip encoder chip check)",
"\t-ie file-to-assemble (assemble the contents of the file)",
"\t-de hex-string (decode-then-encode, must be last)",
#endif
"",
"Optional arguments:",
"",
"\t-v N (0=quiet, 1=errors, 2=useful-info, 3=trace,",
"\t 5=very verbose)",
"\t-xv N (XED engine verbosity, 0...99)",
"",
"\t-chip-check CHIP (count instructions that are not valid for CHIP)",
"\t-chip-check-list (list the valid chips)",
"",
"\t-s section (target section for file disassembly,",
"\t PECOFF and ELF formats only)",
"",
"\t-n N (number of instructions to decode. Default 100M,",
"\t accepts K/M/G qualifiers)",
" ",
"\t-b addr (Base address offset, for DLLs/shared libraries.",
"\t Use 0x for hex addresses)",
"\t-as addr (Address to start disassembling.",
"\t Use 0x for hex addresses)",
"\t-ae addr (Address to end disassembling.",
"\t Use 0x for hex addresses)",
"\t-no-resync (Disable symbol-based resynchronization algorithm",
"\t for disassembly)",
"\t-ast (Show the AVX/SSE transition classfication)",
"\t-histo (Histogram decode times)",
"",
"\t-I (Intel syntax for disassembly)",
"\t-A (ATT SYSV syntax for disassembly)",
"\t-isa-set (Emit the XED \"ISA set\" in dissasembly)",
"\t-xml (XML formatting)",
"\t-uc (upper case hex formatting)",
"\t-pmd (positive memory displacement formatting)",
"\t-nwm (Format AVX512 without curly braces for writemasks, include k0)",
"\t-emit (Output __emit statements for the Intel compiler)",
"\t-S file Read symbol table in \"nm\" format from file",
#if defined(XED_DWARF)
"\t-line (Emit line number information, if present)",
#endif
"\t-dot FN (Emit a register dependence graph file in dot format.",
"\t Best used with -as ADDR -ae ADDR to limit graph size.)",
"",
"\t-r (for REAL_16 mode, 16b addressing (20b addresses),",
"\t 16b default data size)",
"\t-r32 (for REAL_32 mode, 16b addressing (20b addresses),",
"\t 32b default data size)",
"\t-16 (for LEGACY_16 mode, 16b addressing,",
"\t 16b default data size)",
"\t-32 (for LEGACY_32 mode, 32b addressing,",
"\t 32b default data size -- default)",
"\t-64 (for LONG_64 mode w/64b addressing",
"\t Optional on windows/linux)",
#if defined(XED_MPX)
"\t-mpx (Turn on MPX mode for disassembly, default is off)",
#endif
#if defined(XED_CET)
"\t-cet (Turn on CET mode for disassembly, default is off)",
#endif
"\t-s32 (32b stack addressing, default, not in LONG_64 mode)",
"\t-s16 (16b stack addressing, not in LONG_64 mode)",
"\t-set OP VAL (Set a XED operands to some integer value, repeatable)",
#if defined(XED_USING_DEBUG_HELP)
"",
"\t-sp (Search path for windows symbols)",
#endif
"\t-version (The version message)",
"\t-help (This help message)",
" ",
0
};
emit_version();
printf("Usage: %s [options]\n", prog);
for(i=0; usage_msg[i] ; i++)
printf("%s\n", usage_msg[i]);
}
static char const* remove_spaces(char const* s) { xed_uint32_t i=0,c=0;
char* p=0;
if (s == 0)
return 0;
while(s[i]) {
if (s[i] != ' ')
c++;
i++;
}
c++; p = (char*)malloc(c);
assert(p!=0);
i=0;
c=0;
while(s[i]) {
if (s[i] != ' ')
p[c++] = s[i];
i++;
}
p[c]=0;
free((void*)s);
return p;
}
static void
test_argc(int i, int argc)
{
if (i+1 >= argc)
xedex_derror("Need more arguments. Use \"xed -help\" for usage.");
}
static void list_chips(void)
{
xed_chip_enum_t c = XED_CHIP_INVALID;
int i=0;
for( ; c < XED_CHIP_LAST; i++ ) {
if (i > 0 && (i % 3) == 0)
printf("\n");
printf("%-25s ", xed_chip_enum_t2str(c));
c = (xed_chip_enum_t)(c + 1);
}
printf("\n");
}
int
main(int argc, char** argv)
{
xed_bool_t sixty_four_bit = 0;
xed_bool_t mpx_mode = 0;
xed_bool_t cet_mode = 0;
xed_bool_t decode_only = 1;
char* input_file_name = 0;
char* symbol_search_path = 0;
char const* decode_text=0;
char const* encode_text=0;
xed_state_t dstate;
xed_bool_t encode = 0;
xed_bool_t encode_force = 0;
xed_uint_t ninst = 100*1000*1000; unsigned int perf_tail = 0;
xed_bool_t decode_encode = 0;
int i,j;
unsigned int loop_decode = 0;
xed_bool_t decode_raw = 0;
xed_bool_t decode_hex = 0;
xed_bool_t assemble = 0;
char* target_section = 0;
xed_bool_t use_binary_mode = 1;
xed_bool_t emit_isa_set = 0;
xed_uint64_t addr_start = 0;
xed_uint64_t addr_end = 0;
xed_uint64_t fake_base = 0;
xed_bool_t xml_format =0;
xed_bool_t resync = 0;
xed_bool_t ast = 0;
xed_bool_t histo = 0;
xed_bool_t line_numbers = 0;
xed_chip_enum_t xed_chip = XED_CHIP_INVALID;
xed_operand_enum_t operands[XED_MAX_INPUT_OPERNADS] = {XED_OPERAND_INVALID};
xed_uint32_t operands_value[XED_MAX_INPUT_OPERNADS] = {0};
xed_uint8_t operands_index = 0;
xed_bool_t filter = 0;
xed_bool_t just_decode_first_pattern=0;
#if defined(XED_LINUX)
char *prefix = NULL;
#endif
char* dot_output_file_name = 0;
xed_bool_t dot = 0;
xed_decoded_inst_t xedd;
xed_uint_t retval_okay = 1;
unsigned int obytes=0;
#if defined(XED_DECODER)
xed_disas_info_t decode_info;
#endif
#if defined(XED_LINUX)
char *nm_symtab_fn = NULL;
#endif
xed_format_options_t format_options;
memset(&format_options,0,sizeof(xed_format_options_t));
#if defined(XED_NO_HEX_BEFORE_SYMBOLIC_NAMES)
format_options.hex_address_before_symbolic_name=0;
#else
format_options.hex_address_before_symbolic_name=1;
#endif
format_options.write_mask_curly_k0 = 1;
format_options.lowercase_hex = 1;
xed_example_utils_init();
xed_state_init(&dstate,
XED_MACHINE_MODE_LEGACY_32,
XED_ADDRESS_WIDTH_32b,
XED_ADDRESS_WIDTH_32b);
resync = 1;
client_verbose = 3;
xed_set_verbosity( client_verbose );
for( i=1; i < argc ; i++ ) {
#if defined(XED_LINUX)
if (strcmp(argv[i], "-F") == 0) {
test_argc(i, argc);
filter = 1;
prefix = argv[++i];
continue;
} else if (strcmp(argv[i], "-S") == 0) {
test_argc(i, argc);
nm_symtab_fn = argv[++i];
continue;
}
#endif
if (strcmp(argv[i], "-no-resync") ==0) {
resync = 0;
continue;
}
if (strcmp(argv[i], "-ast") ==0) {
ast = 1;
continue;
}
if (strcmp(argv[i], "-histo") ==0) {
histo = 1;
continue;
}
else if (strcmp(argv[i],"-d")==0) {
test_argc(i,argc);
for(j=i+1; j< argc;j++)
decode_text = xedex_append_string(decode_text,argv[j]);
break; }
else if (strcmp(argv[i],"-j")==0) {
just_decode_first_pattern=1;
continue;
}
else if (strcmp(argv[i],"-i")==0) {
test_argc(i,argc);
input_file_name = argv[i+1];
i++;
}
#if defined(XED_USING_DEBUG_HELP)
else if (strcmp(argv[i],"-sp")==0) {
test_argc(i,argc);
symbol_search_path = argv[i+1];
i++;
}
#endif
else if (strcmp(argv[i],"-s")==0) {
test_argc(i,argc);
target_section = argv[i+1];
i++;
}
else if (strcmp(argv[i],"-xml")==0) {
format_options.xml_a = 1;
format_options.xml_f = 1;
xml_format = 1;
}
else if (strcmp(argv[i],"-pmd")==0) {
format_options.positive_memory_displacements=1;
}
else if (strcmp(argv[i],"-uc")==0) {
format_options.lowercase_hex = 0; }
else if (strcmp(argv[i],"-nwm")==0) {
format_options.write_mask_curly_k0 = 0;
}
#if defined(XED_DWARF)
else if (strcmp(argv[i],"-line")==0) {
line_numbers = 1;
}
#endif
else if (strcmp(argv[i],"-dot")==0) {
test_argc(i,argc);
dot_output_file_name = argv[i+1];
dot = 1;
i++;
}
else if (strcmp(argv[i],"-ir")==0) {
test_argc(i,argc);
input_file_name = argv[i+1];
decode_raw = 1;
i++;
}
else if (strcmp(argv[i],"-ih")==0) {
test_argc(i,argc);
input_file_name = argv[i+1];
decode_hex = 1;
i++;
}
#if defined(XED_ENCODER)
else if (strcmp(argv[i],"-f") == 0) {
encode_force = 1;
continue;
}
else if (strcmp(argv[i],"-e") == 0) {
encode = 1;
test_argc(i,argc);
for( j = i+1; j< argc; j++ ) {
encode_text = xedex_append_string(encode_text, argv[j]);
encode_text = xedex_append_string(encode_text, " ");
}
break; }
else if (strcmp(argv[i],"-de")==0) {
test_argc(i,argc);
decode_encode = 1;
for(j=i+1; j< argc;j++)
decode_text = xedex_append_string(decode_text,argv[j]);
break; }
else if (strcmp(argv[i],"-ie")==0) {
test_argc(i,argc);
input_file_name = argv[i+1];
assemble = 1;
i++;
}
else if (strcmp(argv[i],"-ide")==0) {
test_argc(i,argc);
input_file_name = argv[i+1];
decode_only = 0;
i++;
}
#endif
else if (strcmp(argv[i],"-n") ==0) {
test_argc(i,argc);
ninst = XED_STATIC_CAST(xed_uint_t,
xed_atoi_general(argv[i+1],1000));
i++;
}
else if (strcmp(argv[i],"-perftail") ==0) {
test_argc(i,argc);
perf_tail = XED_STATIC_CAST(unsigned int,
xed_atoi_general(argv[i+1],1000));
i++;
}
else if (strcmp(argv[i],"-b") ==0) {
test_argc(i,argc);
fake_base = (xed_uint64_t)xed_atoi_general(argv[i+1],1000);
printf("ASSUMED BASE = " XED_FMT_LX "\n",fake_base);
i++;
}
else if (strcmp(argv[i],"-as") == 0 || strcmp(argv[i],"-sa") == 0) {
test_argc(i,argc);
addr_start = XED_STATIC_CAST(xed_uint64_t,
xed_atoi_general(argv[i+1],1000));
i++;
}
else if (strcmp(argv[i],"-ae") == 0 || strcmp(argv[i],"-ea") == 0) {
test_argc(i,argc);
addr_end = XED_STATIC_CAST(xed_uint64_t,
xed_atoi_general(argv[i+1],1000));
i++;
}
else if (strcmp(argv[i],"-loop") ==0) {
test_argc(i,argc);
loop_decode = XED_STATIC_CAST(unsigned int,
xed_atoi_general(argv[i+1],1000));
i++;
}
else if (strcmp(argv[i],"-v") ==0) {
test_argc(i,argc);
client_verbose = XED_STATIC_CAST(int,xed_atoi_general(argv[i+1],1000));
xed_set_verbosity(client_verbose);
i++;
}
else if (strcmp(argv[i],"-xv") ==0) {
int xed_engine_verbose;
test_argc(i,argc);
xed_engine_verbose = XED_STATIC_CAST(xed_int_t,
xed_atoi_general(argv[i+1],1000));
xed_set_verbosity(xed_engine_verbose);
i++;
}
else if (strcmp(argv[i],"-chip-check")==0) {
test_argc(i,argc);
xed_chip = str2xed_chip_enum_t(argv[i+1]);
printf("Setting chip to %s\n", xed_chip_enum_t2str(xed_chip));
if (xed_chip == XED_CHIP_INVALID) {
printf("Invalid chip name specified. Use -chip-check-list to "
"see the valid chip names.\n");
exit(1);
}
i++;
}
else if (strcmp(argv[i],"-chip-check-list")==0) {
list_chips();
exit(0);
}
else if (strcmp(argv[i],"-A")==0) {
global_syntax = XED_SYNTAX_ATT;
}
else if (strcmp(argv[i],"-I")==0) {
global_syntax = XED_SYNTAX_INTEL;
}
else if (strcmp(argv[i],"-X")==0) { global_syntax = XED_SYNTAX_XED;
}
else if (strcmp(argv[i],"-isa-set")==0) {
emit_isa_set = 1;
}
else if (strcmp(argv[i],"-r32")==0) {
sixty_four_bit = 0;
dstate.mmode = XED_MACHINE_MODE_REAL_32;
dstate.stack_addr_width = XED_ADDRESS_WIDTH_16b;
use_binary_mode = 0;
}
else if (strcmp(argv[i],"-r")==0) {
sixty_four_bit = 0;
dstate.mmode = XED_MACHINE_MODE_REAL_16;
dstate.stack_addr_width = XED_ADDRESS_WIDTH_16b;
use_binary_mode = 0;
}
else if (strcmp(argv[i],"-16")==0) {
sixty_four_bit = 0;
dstate.mmode = XED_MACHINE_MODE_LEGACY_16;
use_binary_mode = 0;
}
else if (strcmp(argv[i],"-32")==0) { sixty_four_bit = 0;
dstate.mmode = XED_MACHINE_MODE_LEGACY_32;
use_binary_mode = 0;
}
else if (strcmp(argv[i],"-64")==0) {
sixty_four_bit = 1;
dstate.mmode = XED_MACHINE_MODE_LONG_64;
use_binary_mode = 0;
}
#if defined(XED_MPX)
else if (strcmp(argv[i],"-mpx")==0) {
mpx_mode = 1;
}
#endif
#if defined(XED_CET)
else if (strcmp(argv[i],"-cet")==0) {
cet_mode = 1;
}
#endif
else if (strcmp(argv[i],"-s32")==0) {
dstate.stack_addr_width = XED_ADDRESS_WIDTH_32b;
use_binary_mode = 0;
}
else if (strcmp(argv[i],"-s16")==0) {
dstate.stack_addr_width = XED_ADDRESS_WIDTH_16b;
use_binary_mode = 0;
}
else if (strcmp(argv[i],"-set")==0) {
test_argc(i+1,argc); if (operands_index >= XED_MAX_INPUT_OPERNADS) {
printf("ERROR: too many -set operands, max is %d\n", XED_MAX_INPUT_OPERNADS);
exit(1);
}
operands[operands_index] = str2xed_operand_enum_t(argv[i+1]);
operands_value[operands_index] = XED_STATIC_CAST(xed_uint32_t,
xed_atoi_general(argv[i+2],1000));
operands_index++;
i += 2;
}
#if 0#endif
else if (strcmp(argv[i],"-emit") ==0) {
intel_asm_emit = 1;
}
else if (strcmp(argv[i],"-version") == 0 ) {
emit_version();
exit(0);
}
else {
usage(argv[0]);
exit(1);
}
}
if (!encode) {
if (input_file_name == 0 &&
(decode_text == 0 ||
strlen(decode_text) == 0) && !filter)
{
printf("ERROR: required argument(s) were missing\n");
usage(argv[0]);
exit(1);
}
}
#if defined(XED_LINUX)
if ((nm_symtab_fn != 0) && (nm_symtab_fn[0] != 0)) {
if (!filter) {
printf("ERROR: -S only support with -F for now\n");
exit(1);
}
xed_read_nm_symtab(nm_symtab_fn);
}
#endif
if (CLIENT_VERBOSE2)
printf("Initializing XED tables...\n");
xed_tables_init();
if (CLIENT_VERBOSE2)
printf("Done initialing XED tables.\n");
if (decode_text) {
decode_text = remove_spaces(decode_text);
assert(decode_text);
}
#if defined(XED_DECODER)
xed_format_set_options(format_options);
#endif
if (CLIENT_VERBOSE1)
printf("#XED version: [%s]\n", xed_get_version());
retval_okay = 1;
obytes=0;
#if defined(XED_DECODER)
xed_disas_info_init(&decode_info);
decode_info.input_file_name = input_file_name;
decode_info.symbol_search_path = symbol_search_path;
decode_info.dstate = dstate;
decode_info.ninst = ninst;
decode_info.decode_only = decode_only;
decode_info.sixty_four_bit = sixty_four_bit;
decode_info.target_section = target_section;
decode_info.use_binary_mode = use_binary_mode;
decode_info.addr_start = addr_start;
decode_info.addr_end = addr_end;
decode_info.xml_format = xml_format;
decode_info.fake_base = fake_base;
decode_info.resync = resync;
decode_info.line_numbers = line_numbers;
decode_info.perf_tail_start = perf_tail;
decode_info.ast = ast;
decode_info.histo = histo;
decode_info.chip = xed_chip;
decode_info.mpx_mode = mpx_mode;
decode_info.cet_mode = cet_mode;
decode_info.emit_isa_set = emit_isa_set;
decode_info.format_options = format_options;
decode_info.encode_force = encode_force;
decode_info.dot_graph_output = 0;
memcpy(decode_info.operands, operands, sizeof(decode_info.operands));
memcpy(decode_info.operands_value, operands_value, sizeof(decode_info.operands_value));
if (dot)
{
decode_info.dot_graph_output = fopen_portable(dot_output_file_name,"w");
if (!decode_info.dot_graph_output) {
printf("Could not open %s\n", dot_output_file_name);
xedex_derror("Dying");
}
}
init_xedd(&xedd, &decode_info);
#endif
#if defined(XED_LINUX)
if (filter)
{
#if defined(XED_DECODER)
retval_okay = disas_filter(&xedd, prefix, &decode_info);
#endif
} else
#endif
if (assemble)
{
#if defined(XED_ENCODER)
xed_assemble(&dstate, input_file_name);
#endif
}
else if (decode_encode)
{
#if defined(XED_DECODER) && defined(XED_ENCODER)
assert(decode_text);
obytes = disas_decode_encode(&decode_info,
decode_text,
&xedd,
fake_base);
#endif
retval_okay = (obytes != 0) ? 1 : 0;
}
else if (encode)
{
#if defined(XED_ENCODER)
assert(encode_text != 0);
obytes = disas_encode(&dstate,
encode_text,
operands,
operands_value,
encode_force);
#endif
}
else if (decode_text && strlen(decode_text) != 0)
{
#if defined(XED_DECODER)
if (loop_decode)
{
unsigned int k;
for(k=0;k<loop_decode;k++) {
retval_okay = disas_decode(&decode_info,
decode_text,
&xedd,
fake_base);
init_xedd(&xedd, &decode_info);
}
}
else
{
char const* p = decode_text;
unsigned int remaining = (unsigned int)strlen(decode_text) / 2;
do {
unsigned int len;
retval_okay = disas_decode(&decode_info, p, &xedd, fake_base);
len = xed_decoded_inst_get_length(&xedd);
p+=len*2;
if (len < remaining) {
remaining -= len;
init_xedd(&xedd, &decode_info);
}
else {
remaining = 0;
}
}
while(just_decode_first_pattern==0 && retval_okay && remaining > 0);
}
#endif
}
else
{
#if defined(XED_DECODER)
if (xml_format) {
printf("<?xml version=\"1.0\"?>\n");
printf("<XEDDISASM>\n");
printf("<XEDFORMAT>1</XEDFORMAT>\n");
}
if (decode_raw) {
xed_disas_raw(&decode_info);
}
else if (decode_hex) {
xed_disas_hex(&decode_info);
}
else
{
#if defined(__APPLE__)
xed_disas_macho(&decode_info);
#elif defined(XED_ELF_READER)
xed_disas_elf(&decode_info);
#elif defined(_WIN32)
xed_disas_pecoff(&decode_info);
#else
xedex_derror("No PECOFF, ELF or MACHO support compiled in");
#endif
printf("# Total Errors: " XED_FMT_LU "\n", decode_info.errors);
if (decode_info.chip)
printf("# Total Chip Check Errors: " XED_FMT_LU "\n",
decode_info.errors_chip_check);
}
#endif }
if (xml_format)
printf("</XEDDISASM>\n");
if (retval_okay==0)
exit(1);
if (decode_info.dot_graph_output)
fclose(decode_info.dot_graph_output);
if (decode_text)
free((void*)decode_text);
#if defined(XED_ENCODER)
if (encode_text)
free((void*)encode_text);
#else
(void) encode_text;
#endif
(void) obytes;
return 0;
#if !defined(XED_DECODER)
(void) xedd;
(void) sixty_four_bit;
(void) decode_only;
(void) symbol_search_path;
(void) ninst;
(void) perf_tail;
(void) loop_decode;
(void) decode_raw;
(void) decode_hex;
(void) target_section;
(void) addr_start;
(void) addr_end;
(void) resync;
(void) ast;
(void) histo;
(void) line_numbers;
(void) dot_output_file_name;
(void) dot;
(void) use_binary_mode;
(void) emit_isa_set;
#endif
}