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