10c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/* 20c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * Licensed to the Apache Software Foundation (ASF) under one or more 30c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * contributor license agreements. See the NOTICE file distributed with 40c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * this work for additional information regarding copyright ownership. 50c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * The ASF licenses this file to You under the Apache License, Version 2.0 60c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * (the "License"); you may not use this file except in compliance with 70c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * the License. You may obtain a copy of the License at 80c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * 90c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * http://www.apache.org/licenses/LICENSE-2.0 100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * 110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * Unless required by applicable law or agreed to in writing, software 120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * distributed under the License is distributed on an "AS IS" BASIS, 130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * See the License for the specific language governing permissions and 150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * limitations under the License. 160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/** 180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * @author Alexander V. Astapchuk 190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/** 220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * @file 230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * @brief Main decoding (disassembling) routines and structures. 240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * 250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * @note Quick and rough implementation, subject for a change. 260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifndef __DEC_BASE_H_INCLUDED__ 290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#define __DEC_BASE_H_INCLUDED__ 300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#include "enc_base.h" 330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#include "enc_prvt.h" 340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef ENCODER_ISOLATE 360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenusing namespace enc_ia32; 370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#define IF_CONDITIONAL (0x00000000) 400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#define IF_SYMMETRIC (0x00000000) 410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#define IF_BRANCH (0x00000000) 420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenstruct Inst { 440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Inst() { 450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen mn = Mnemonic_Null; 460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen prefc = 0; 470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen size = 0; 480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen flags = 0; 490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //offset = 0; 500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //direct_addr = NULL; 510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen argc = 0; 520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(int i = 0; i < 4; ++i) 530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen { 540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen pref[i] = InstPrefix_Null; 550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /** 580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * Mnemonic of the instruction.s 590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic mn; 610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /** 620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * Enumerating of indexes in the pref array. 630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen enum PrefGroups 650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen { 660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Group1 = 0, 670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Group2, 680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Group3, 690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Group4 700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen }; 710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /** 720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * Number of prefixes (1 byte each). 730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen unsigned int prefc; 750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /** 760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * Instruction prefixes. Prefix should be placed here according to its group. 770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen InstPrefix pref[4]; 790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /** 800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * Size, in bytes, of the instruction. 810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen unsigned size; 830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /** 840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * Flags of the instruction. 850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * @see MF_ 860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen unsigned flags; 880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /** 890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * An offset of target address, in case of 'CALL offset', 900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * 'JMP/Jcc offset'. 910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //int offset; 930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /** 940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * Direct address of the target (on Intel64/IA-32 is 'instruction IP' + 950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * 'instruction length' + offset). 960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //void * direct_addr; 980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /** 990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * Number of arguments of the instruction. 1000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 1010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen unsigned argc; 1020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen // 1030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen EncoderBase::Operand operands[3]; 1040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen // 1050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen const EncoderBase::OpcodeDesc * odesc; 1060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen}; 1070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Cheninline bool is_jcc(Mnemonic mn) 1090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen{ 1100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return Mnemonic_JO <= mn && mn<=Mnemonic_JG; 1110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 1120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenclass DecoderBase { 1140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenpublic: 1150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen static unsigned decode(const void * addr, Inst * pinst); 1160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenprivate: 1170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen static bool decodeModRM(const EncoderBase::OpcodeDesc& odesc, 1180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen const unsigned char ** pbuf, Inst * pinst 1190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef _EM64T_ 1200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen , const Rex *rex 1210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 1220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ); 1230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen static bool decode_aux(const EncoderBase::OpcodeDesc& odesc, 1240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen unsigned aux, const unsigned char ** pbuf, 1250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Inst * pinst 1260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef _EM64T_ 1270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen , const Rex *rex 1280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 1290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ); 1300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen static bool try_mn(Mnemonic mn, const unsigned char ** pbuf, Inst * pinst); 1310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen static unsigned int fill_prefs( const unsigned char * bytes, Inst * pinst); 1320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen static bool is_prefix(const unsigned char * bytes); 1330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen}; 1340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif // ~ __DEC_BASE_H_INCLUDED__ 1360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 137