+++ /dev/null
-/*BEGIN_LEGAL
-Intel Open Source License
-
-Copyright (c) 2002-2007 Intel Corporation
-All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-Redistributions of source code must retain the above copyright notice,
-this list of conditions and the following disclaimer. Redistributions
-in binary form must reproduce the above copyright notice, this list of
-conditions and the following disclaimer in the documentation and/or
-other materials provided with the distribution. Neither the name of
-the Intel Corporation nor the names of its contributors may be used to
-endorse or promote products derived from this software without
-specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
-ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-END_LEGAL */
-/// @file xed-ex1.cpp
-/// @author Mark Charney <mark.charney@intel.com>
-
-extern "C" {
-#include "xed-interface.h"
-}
-#include "xed-examples-ostreams.H"
-#include <iostream>
-#include <iomanip>
-#include <sstream>
-#include <cassert>
-using namespace std;
-
-int main(int argc, char** argv);
-
-void print_attributes(xed_decoded_inst_t* xedd) {
- const xed_inst_t* xi = xed_decoded_inst_inst(xedd);
- unsigned int i, nattributes = xed_attribute_max();
- xed_uint32_t all_attributes = xed_inst_get_attributes(xi);
- if (all_attributes == 0)
- return;
- cout << "ATTRIBUTES: ";
- for(i=0;i<nattributes;i++) {
- xed_attribute_enum_t attr = xed_attribute(i);
- if (xed_inst_get_attribute(xi,attr))
- cout << xed_attribute_enum_t2str(attr) << " ";
- }
- cout << endl;
-}
-
-void print_flags(xed_decoded_inst_t* xedd) {
- unsigned int i, nflags;
- if (xed_decoded_inst_uses_rflags(xedd)) {
- cout << "FLAGS:" << endl;
- const xed_simple_flag_t* rfi = xed_decoded_inst_get_rflags_info(xedd);
- if (xed_simple_flag_reads_flags(rfi)) {
- cout << " reads-rflags ";
- }
- else if (xed_simple_flag_writes_flags(rfi)) {
- //XED provides may-write and must-write information
- if (xed_simple_flag_get_may_write(rfi)) {
- cout << " may-write-rflags ";
- }
- if (xed_simple_flag_get_must_write(rfi)) {
- cout << " must-write-rflags ";
- }
- }
- nflags = xed_simple_flag_get_nflags(rfi);
- for( i=0;i<nflags ;i++) {
- const xed_flag_action_t* fa = xed_simple_flag_get_flag_action(rfi,i);
- char buf[500];
- xed_flag_action_print(fa,buf,500);
- cout << buf << " ";
- }
- cout << endl;
- // or as as bit-union
- const xed_flag_set_t* read_set = xed_simple_flag_get_read_flag_set(rfi);
- const xed_flag_set_t* written_set = xed_simple_flag_get_written_flag_set(rfi);
- char buf[500];
- xed_flag_set_print(read_set,buf,500);
- cout << " read: " << buf << endl;
- xed_flag_set_print(written_set,buf,500);
- cout << " written: " << buf << endl;
- }
-}
-
-void print_memops(xed_decoded_inst_t* xedd) {
- unsigned int i, memops = xed_decoded_inst_number_of_memory_operands(xedd);
- cout << "Memory Operands" << endl;
-
- for( i=0;i<memops ; i++) {
- xed_bool_t r_or_w = false;
- cout << " " << i << " ";
- if ( xed_decoded_inst_mem_read(xedd,i)) {
- cout << "read ";
- r_or_w = true;
- }
- if (xed_decoded_inst_mem_written(xedd,i)) {
- cout << "written ";
- r_or_w = true;
- }
- if (!r_or_w) {
- cout << "agen "; // LEA instructions
- }
- xed_reg_enum_t seg = xed_decoded_inst_get_seg_reg(xedd,i);
- if (seg != XED_REG_INVALID) {
- cout << "SEG= " << xed_reg_enum_t2str(seg) << " ";
- }
- xed_reg_enum_t base = xed_decoded_inst_get_base_reg(xedd,i);
- if (base != XED_REG_INVALID) {
- cout << "BASE= " << xed_reg_enum_t2str(base) << "/"
- << xed_reg_class_enum_t2str(xed_reg_class(base)) << " ";
- }
- xed_reg_enum_t indx = xed_decoded_inst_get_index_reg(xedd,i);
- if (i == 0 && indx != XED_REG_INVALID) {
- cout << "INDEX= " << xed_reg_enum_t2str(indx)
- << "/" << xed_reg_class_enum_t2str(xed_reg_class(indx)) << " ";
- if (xed_decoded_inst_get_scale(xedd,i) != 0) {
- // only have a scale if the index exists.
- cout << "SCALE= " << xed_decoded_inst_get_scale(xedd,i) << " ";
- }
- }
- xed_uint_t disp_bits = xed_decoded_inst_get_memory_displacement_width(xedd,i);
- if (disp_bits) {
- cout << "DISPLACEMENT_BYTES= " << disp_bits << " ";
- xed_int64_t disp = xed_decoded_inst_get_memory_displacement(xedd,i);
- cout << hex << setfill('0') << setw(16) << disp << setfill(' ') << dec;
- }
- cout << endl;
- }
- cout << " MemopBytes = " << xed_decoded_inst_get_memory_operand_length(xedd,0) << endl;
-}
-
-void print_operands(xed_decoded_inst_t* xedd) {
- unsigned int i, noperands;
- cout << "Operands" << endl;
- const xed_inst_t* xi = xed_decoded_inst_inst(xedd);
- noperands = xed_inst_noperands(xi);
- for( i=0; i < noperands ; i++) {
- const xed_operand_t* op = xed_inst_operand(xi,i);
- xed_operand_enum_t op_name = xed_operand_name(op);
- cout << i << " " << xed_operand_enum_t2str(op_name) << " ";
- switch(op_name) {
- case XED_OPERAND_AGEN:
- case XED_OPERAND_MEM0:
- case XED_OPERAND_MEM1:
- // we print memops in a different function
- break;
- case XED_OPERAND_PTR: // pointer (always in conjunction with a IMM0)
- case XED_OPERAND_RELBR: { // branch displacements
- xed_uint_t disp_bits = xed_decoded_inst_get_branch_displacement_width(xedd);
- if (disp_bits) {
- cout << "BRANCH_DISPLACEMENT_BYTES= " << disp_bits << " ";
- xed_int32_t disp = xed_decoded_inst_get_branch_displacement(xedd);
- cout << hex << setfill('0') << setw(8) << disp << setfill(' ') << dec;
- }
- }
- break;
-
- case XED_OPERAND_IMM0: { // immediates
- xed_uint_t width = xed_decoded_inst_get_immediate_width(xedd);
- if (xed_decoded_inst_get_immediate_is_signed(xedd)) {
- xed_int32_t x =xed_decoded_inst_get_signed_immediate(xedd);
- cout << hex << setfill('0') << setw(8) << x << setfill(' ') << dec
- << '(' << width << ')';
- }
- else {
- xed_uint64_t x = xed_decoded_inst_get_unsigned_immediate(xedd);
- cout << hex << setfill('0') << setw(16) << x << setfill(' ') << dec
- << '(' << width << ')';
- }
- break;
- }
- case XED_OPERAND_IMM1: { // immediates
- xed_uint8_t x = xed_decoded_inst_get_second_immediate(xedd);
- cout << hex << setfill('0') << setw(2) << (int)x << setfill(' ') << dec;
- break;
- }
-
- case XED_OPERAND_REG0:
- case XED_OPERAND_REG1:
- case XED_OPERAND_REG2:
- case XED_OPERAND_REG3:
- case XED_OPERAND_REG4:
- case XED_OPERAND_REG5:
- case XED_OPERAND_REG6:
- case XED_OPERAND_REG7:
- case XED_OPERAND_REG8:
- case XED_OPERAND_REG9:
- case XED_OPERAND_REG10:
- case XED_OPERAND_REG11:
- case XED_OPERAND_REG12:
- case XED_OPERAND_REG13:
- case XED_OPERAND_REG14:
- case XED_OPERAND_REG15: {
- xed_reg_enum_t r = xed_decoded_inst_get_reg(xedd, op_name);
- cout << xed_operand_enum_t2str(op_name) << "=" << xed_reg_enum_t2str(r);
- break;
- }
- default:
- cout << "[Not currently printing value of field " << xed_operand_enum_t2str(op_name) << ']';
- break;
-
- }
- cout << " " << xed_operand_visibility_enum_t2str(xed_operand_operand_visibility(op))
- << " / " << xed_operand_action_enum_t2str(xed_operand_rw(op))
- << " / " << xed_operand_width_enum_t2str(xed_operand_width(op));
- cout << " bytes=" << xed_decoded_inst_operand_length(xedd,i);
- cout << endl;
- }
-}
-
-int main(int argc, char** argv) {
- xed_state_t dstate;
- xed_decoded_inst_t xedd;
- int i, bytes = 0;
- unsigned char itext[XED_MAX_INSTRUCTION_BYTES];
- xed_bool_t long_mode = false;
- unsigned int first_argv;
-
- xed_tables_init();
- xed_state_zero(&dstate);
- if (argc > 2 && strcmp(argv[1], "-64") == 0)
- long_mode = true;
-
- if (long_mode) {
- first_argv = 2;
- dstate.mmode=XED_MACHINE_MODE_LONG_64;
- }
- else {
- first_argv=1;
- xed_state_init(&dstate,
- XED_MACHINE_MODE_LEGACY_32,
- XED_ADDRESS_WIDTH_32b,
- XED_ADDRESS_WIDTH_32b);
- }
-
- xed_decoded_inst_zero_set_mode(&xedd, &dstate);
-
- for( i=first_argv ;i < argc; i++) {
- unsigned int x;
- // sscanf is deprecated for MSVS8, so I'm using istringstreams
- //sscanf(argv[i],"%x", &x);
- istringstream s(argv[i]);
- s >> hex >> x;
- assert(bytes < XED_MAX_INSTRUCTION_BYTES);
- itext[bytes++] = STATIC_CAST(xed_uint8_t,x);
- }
- if (bytes == 0) {
- cout << "Must supply some hex bytes" << endl;
- exit(1);
- }
-
- cout << "Attempting to decode: " << hex << setfill('0') ;
- for(i=0;i<bytes;i++)
- cout << setw(2) << static_cast<xed_uint_t>(itext[i]) << " ";
- cout << endl << setfill(' ') << dec;
-
- xed_error_enum_t xed_error = xed_decode(&xedd,
- REINTERPRET_CAST(const xed_uint8_t*,itext),
- bytes);
- switch(xed_error) {
- case XED_ERROR_NONE:
- break;
- case XED_ERROR_BUFFER_TOO_SHORT:
- cout << "Not enough bytes provided" << endl;
- exit(1);
- case XED_ERROR_GENERAL_ERROR:
- cout << "Could not decode given input." << endl;
- exit(1);
- default:
- cout << "Unhandled error code " << xed_error_enum_t2str(xed_error) << endl;
- exit(1);
- }
-
-
- cout << "iclass "
- << xed_iclass_enum_t2str(xed_decoded_inst_get_iclass(&xedd)) << "\t";
- cout << "category "
- << xed_category_enum_t2str(xed_decoded_inst_get_category(&xedd)) << "\t";
- cout << "ISA-extension "
- << xed_extension_enum_t2str(xed_decoded_inst_get_extension(&xedd)) << endl;
- cout << "instruction-length "
- << xed_decoded_inst_get_length(&xedd) << endl;
- cout << "effective-operand-width "
- << xed_operand_values_get_effective_operand_width(xed_decoded_inst_operands_const(&xedd)) << endl;
- cout << "effective-address-width "
- << xed_operand_values_get_effective_address_width(xed_decoded_inst_operands_const(&xedd)) << endl;
- cout << "iform-enum-name "
- << xed_iform_enum_t2str(xed_decoded_inst_get_iform_enum(&xedd)) << endl;
- cout << "iform-enum-name-dispatch (zero based) "
- << xed_decoded_inst_get_iform_enum_dispatch(&xedd) << endl;
- cout << "iclass-max-iform-dispatch "
- << xed_iform_max_per_iclass(xed_decoded_inst_get_iclass(&xedd)) << endl;
-
- // operands
- print_operands(&xedd);
-
- // memops
- print_memops(&xedd);
-
- // flags
- print_flags(&xedd);
-
- // attributes
- print_attributes(&xedd);
- return 0;
-}