LCOV - code coverage report
Current view: directory - src/trusted/validator/x86/ncval_seg_sfi - ncdecode.h (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 3 3 100.0 %
Date: 2014-09-25 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2012 The Native Client Authors. All rights reserved.
       3                 :  * Use of this source code is governed by a BSD-style license that can be
       4                 :  * found in the LICENSE file.
       5                 :  */
       6                 : 
       7                 : /*
       8                 :  * ncdecode.h - table driven decoder for Native Client.
       9                 :  *
      10                 :  * This header file contains type declarations and constants
      11                 :  * used by the decoder input table
      12                 :  */
      13                 : #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_NCVAL_SEG_SFI_NCDECODE_H_
      14                 : #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_NCVAL_SEG_SFI_NCDECODE_H_
      15                 : 
      16                 : #include "native_client/src/shared/utils/types.h"
      17                 : #include "native_client/src/trusted/validator/ncvalidate.h"
      18                 : #include "native_client/src/trusted/validator/x86/error_reporter.h"
      19                 : #include "native_client/src/trusted/validator/x86/ncinstbuffer.h"
      20                 : #include "native_client/src/trusted/validator/x86/x86_insts.h"
      21                 : 
      22                 : EXTERN_C_BEGIN
      23                 : 
      24                 : struct NCDecoderInst;
      25                 : struct NCDecoderState;
      26                 : 
      27                 : /* Function type for a decoder action. Returns TRUE if action
      28                 :  * was applied successfully.
      29                 :  */
      30                 : typedef Bool (*NCDecoderStateAction)(const struct NCDecoderInst* dinst);
      31                 : 
      32                 : /* Function type for other decoder state methods. */
      33                 : typedef void (*NCDecoderStateMethod)(struct NCDecoderState* vstate);
      34                 : 
      35                 : typedef enum {
      36                 :   NOGROUP = 0,
      37                 :   GROUP1,
      38                 :   GROUP2,
      39                 :   GROUP3,
      40                 :   GROUP4,
      41                 :   /* these comments facilitate counting */
      42                 :   GROUP5,
      43                 :   GROUP6,
      44                 :   GROUP7,
      45                 :   GROUP8,
      46                 :   GROUP9,
      47                 :   /* these comments facilitate counting */
      48                 :   GROUP10,
      49                 :   GROUP11,
      50                 :   GROUP12,
      51                 :   GROUP13,
      52                 :   GROUP14,
      53                 :   /* these comments facilitate counting */
      54                 :   GROUP15,
      55                 :   GROUP16,
      56                 :   GROUP17,
      57                 :   GROUP1A,
      58                 :   GROUPP
      59                 : } NaClMRMGroups;
      60                 : /* kModRMOpcodeGroups doesn't work as a const int since it is used */
      61                 : /* as an array dimension */
      62                 : #define kNaClMRMGroupsRange 20
      63                 : 
      64                 : /* Define the maximum value that can be encoded in the modrm mod field. */
      65                 : #define kModRMOpcodeGroupSize 8
      66                 : 
      67                 : /* Define the maximum register value that can be encoded into the opcode
      68                 :  * byte.
      69                 :  */
      70                 : #define kMaxRegisterIndexInOpcode 7
      71                 : 
      72                 : /* information derived from the opcode, wherever it happens to be */
      73                 : typedef enum {
      74                 :   IMM_UNKNOWN = 0,
      75                 :   IMM_NONE = 1,
      76                 :   IMM_FIXED1 = 2,
      77                 :   IMM_FIXED2 = 3,
      78                 :   IMM_FIXED3 = 4,
      79                 :   IMM_FIXED4 = 5,
      80                 :   IMM_DATAV = 6,
      81                 :   IMM_ADDRV = 7,
      82                 :   IMM_GROUP3_F6 = 8,
      83                 :   IMM_GROUP3_F7 = 9,
      84                 :   IMM_FARPTR = 10,
      85                 :   IMM_MOV_DATAV,     /* Special case for 64-bits MOVs (b8 through bf). */
      86                 :   /* Don't add to this enum without update kNCDecodeImmediateTypeRange */
      87                 :   /* and updating the tables below which are sized using this constant */
      88                 : } NCDecodeImmediateType;
      89                 : #define kNCDecodeImmediateTypeRange 12
      90                 : 
      91                 : /* 255 will force an error */
      92                 : static const uint8_t kImmTypeToSize66[kNCDecodeImmediateTypeRange] =
      93                 :   { 0, 0, 1, 2, 3, 4, 2, (NACL_TARGET_SUBARCH == 64 ? 8 : 4), 0, 0, 6, 2};
      94                 : static const uint8_t kImmTypeToSize67[kNCDecodeImmediateTypeRange] =
      95                 :   { 0, 0, 1, 2, 3, 4, 4, 2, 0, 0, 4, 4};
      96                 : static const uint8_t kImmTypeToSize[kNCDecodeImmediateTypeRange] =
      97                 :   { 0, 0, 1, 2, 3, 4, 4, (NACL_TARGET_SUBARCH == 64 ? 8 : 4), 0, 0, 6, 4 };
      98                 : 
      99                 : /* Defines how to decode operands for byte codes. */
     100                 : typedef enum {
     101                 :   /* Assume the default size of the operands is 64-bits (if
     102                 :    * not specified in prefix bits).
     103                 :    */
     104                 :   DECODE_OPS_DEFAULT_64,
     105                 :   /* Assume the default size of the operands is 32-bits (if
     106                 :    * not specified in prefix bits).
     107                 :    */
     108                 :   DECODE_OPS_DEFAULT_32,
     109                 :   /* Force the size of the operands to 64 bits (prefix bits are
     110                 :    * ignored).
     111                 :    */
     112                 :   DECODE_OPS_FORCE_64
     113                 : } DecodeOpsKind;
     114                 : 
     115                 : /* Models information on an x86-32 bit instruction. */
     116                 : struct OpInfo {
     117                 :   NaClInstType insttype;
     118                 :   uint8_t hasmrmbyte;   /* 1 if this inst has an mrm byte, else 0 */
     119                 :   uint8_t immtype;      /* IMM_NONE, IMM_FIXED1, etc. */
     120                 :   uint8_t opinmrm;      /* set to 1..8 if you must find opcode in MRM byte */
     121                 : };
     122                 : 
     123                 : /* Models a node in a trie of NOP instructions. */
     124                 : typedef struct NCNopTrieNode {
     125                 :   /* The matching byte for the trie node. */
     126                 :   uint8_t matching_byte;
     127                 :   /* The matching modeled nop, if byte matched. */
     128                 :   struct OpInfo *matching_opinfo;
     129                 :   /* Node to match remaining bytes. */
     130                 :   struct NCNopTrieNode* success;
     131                 :   /* Node to match remaining bytes. */
     132                 :   struct NCNopTrieNode* fail;
     133                 : } NCNopTrieNode;
     134                 : 
     135                 : /* Predefined value to communicate that the lock prefix was not
     136                 :  * found in an instruction.
     137                 :  */
     138                 : static const uint8_t kNoLockPrefixIndex = 0xFF;
     139                 : 
     140                 : /* Models a parsed x86-32 bit instruction. */
     141                 : struct InstInfo {
     142                 :   /* The bytes used to parse the x86-32 instruction (may have added
     143                 :    * zero filler if the instruction straddles the memory segment).
     144                 :    */
     145                 :   NCInstBytes bytes;
     146                 :   /* The number of prefix bytes in the instruction. */
     147                 :   uint8_t prefixbytes;  /* 0..4 */
     148                 :   /* Number of opcode bytes in the instruction. */
     149                 :   uint8_t num_opbytes;
     150                 :   /* non-zero if the instruction contains an SIB byte. */
     151                 :   uint8_t hassibbyte;
     152                 :   /* The ModRm byte. */
     153                 :   uint8_t mrm;
     154                 :   /* A NCDecodeImmediateType describing the type of immediate value(s)
     155                 :    * the instruction has.
     156                 :    */
     157                 :   uint8_t immtype;
     158                 :   /* The number of bytes that define the immediate value(s). */
     159                 :   uint8_t immbytes;
     160                 :   /* The number of displacement bytes defined by the instruction. */
     161                 :   uint8_t dispbytes;
     162                 :   /* The set of prefix masks defined by the prefix bytes. */
     163                 :   uint32_t prefixmask;
     164                 :   /* The prefix form used to select multibyte instructions, or 0 if
     165                 :    * not used. That is, if 66, f2, or f3 is used to select the instruction,
     166                 :    * then this value is non-zero. For example SSE3 instructions.
     167                 :    */
     168                 :   uint32_t opcode_prefixmask;
     169                 :   /* True if it has a rex prefix. */
     170                 :   uint8_t rexprefix;
     171                 :   /* Index of lock prefix (F0), or kNoLockPrefixIndex if the lock prefix
     172                 :    * isn't specified.
     173                 :    */
     174                 :   uint8_t lock_prefix_index;
     175                 : };
     176                 : 
     177                 : /* Models data collected about the parsed instruction. */
     178                 : typedef struct NCDecoderInst {
     179                 :   /* The address of the instruction, relative to the begining of the code
     180                 :    * segment.
     181                 :    */
     182                 :   NaClPcAddress inst_addr;
     183                 :   /* The instruction rule used to decode the instruction. */
     184                 :   const struct OpInfo* opinfo;
     185                 :   /* The low level details of the instructionm, extracted during parsing. */
     186                 :   struct InstInfo inst;
     187                 :   /* Pointer to bytes of the parsed instruction (int inst) for easier access. */
     188                 :   const NCInstBytesPtr inst_bytes;
     189                 :   /* The decoder state the instruction appears in. */
     190                 :   struct NCDecoderState* dstate;
     191                 :   /* Corresopnding index of this instruction wrt to inst_buffer in
     192                 :    * in the corresponding decoder state NCDecoderState.
     193                 :    */
     194                 :   size_t inst_index;
     195                 :   /* The number of instructions parsed so far (including this instrruction).
     196                 :    * Used to detect when one tries to get a previous instruction that doesn't
     197                 :    * exist.
     198                 :    */
     199                 :   size_t inst_count;
     200                 :   /* True if the instruction is unchanged while dynamically replacing code.
     201                 :    * False if the instruction has changed or if code replacement is not being
     202                 :    * performed (i.e. normal validation.)
     203                 :    */
     204                 :   Bool unchanged;
     205                 : } NCDecoderInst;
     206                 : 
     207                 : /* Given a (decoded) instruction, return the instruction that appeared
     208                 :  * n elements before it, or NULL if no such instruction exists.
     209                 :  *
     210                 :  * Parameters:
     211                 :  *    dinst - The instruction to look up relative to.
     212                 :  *    n - number of elements back to look.
     213                 :  */
     214                 : extern NCDecoderInst *PreviousInst(const NCDecoderInst* dinst, int n);
     215                 : 
     216                 : /* Models decoding instructions in a memory region.
     217                 :  *
     218                 :  * Note: This struct is modeling a notion of a (virtual) base class to parse
     219                 :  * a window of k instructions. In this model, we consider NCDecoderState a
     220                 :  * class that can be (singly) inherited by derived classes. This code
     221                 :  * assumes that the "this" pointer can be cast to a derived class
     222                 :  * using a C cast. This implies that derived classes should have the
     223                 :  * field NCDecoderState as its first field.
     224                 :  *
     225                 :  * Typical use is:
     226                 :  *
     227                 :  *    NCDecoderState dstate;
     228                 :  *    NCDecoder inst_buffer[BUF_SIZE]; // window of BUF_SIZE instructions.
     229                 :  *    NCDecoderStateConstruct(&dstate, mbase, vbase, size,
     230                 :  *                            inst_buffer, BUF_SIZE);
     231                 :  *    NCDecoderStateDecode(&dstate);
     232                 :  *    NCDecoderStateDestruct(&dstate);
     233                 :  *
     234                 :  * Note: The old API for this class is further down in this file,
     235                 :  * and should be considered deprecated.
     236                 :  */
     237                 : typedef struct NCDecoderState {
     238                 :   /* PROTECTED: */
     239                 : 
     240                 :   /* The instruction buffer is an array of instructions, used
     241                 :    * by the decoder to define a window of decoded instructions.
     242                 :    * This window automatically moves as instructions are decoded
     243                 :    * so that one can always see the current decoded instruction,
     244                 :    * and some (fixed) number of previously decoded instructions.
     245                 :    */
     246                 :   NCDecoderInst* inst_buffer;
     247                 : 
     248                 :   /* The number of elements in inst_buffer. Must be greater than zero. */
     249                 :   size_t inst_buffer_size;
     250                 : 
     251                 :   /* Remaining memory to decode. It is allocated on
     252                 :    * the stack to make it thread-local, and included here
     253                 :    * so that all decoder states have access to it.
     254                 :    */
     255                 :   NCRemainingMemory memory;
     256                 : 
     257                 :   /* The begining of the memory segment to decode. */
     258                 :   uint8_t* mbase;
     259                 : 
     260                 :   /* The (virtual) base address of the memory segment. */
     261                 :   NaClPcAddress vbase;
     262                 : 
     263                 :   /* The number of bytes in the memory segment. */
     264                 :   NaClMemorySize size;
     265                 : 
     266                 :   /* The index of the current instruction within inst_buffer. */
     267                 :   size_t cur_inst_index;
     268                 : 
     269                 :   /* Holds the error reporting object to use. */
     270                 :   NaClErrorReporter* error_reporter;
     271                 : 
     272                 :   /* Member function to apply actions to a decoded instruction. */
     273                 :   NCDecoderStateAction action_fn;
     274                 : 
     275                 :   /* Member function to process new segment. */
     276                 :   NCDecoderStateMethod new_segment_fn;
     277                 : 
     278                 :   /* Member function called to report an error with the validity of the
     279                 :    * memory segment.
     280                 :    */
     281                 :   NCDecoderStateMethod segmentation_error_fn;
     282                 : 
     283                 :   /* Member function called to report other errors while processing the
     284                 :    * memory segment.
     285                 :    */
     286                 :   NCDecoderStateMethod internal_error_fn;
     287                 : } NCDecoderState;
     288                 : 
     289                 : /*
     290                 :  * Construct a decoder state.
     291                 :  *
     292                 :  * Parameters are:
     293                 :  *   this  - The instance to be constructed.
     294                 :  *   mbase - The begining of the memory segment to decode.
     295                 :  *   vbase - The (virtual) base address of the memory segment.
     296                 :  *   sz - The number of bytes in the memory segment.
     297                 :  *
     298                 :  * Note: Constructors of subclasses of NCDecoderState should
     299                 :  * call this constructor first, to initialize the decoder state.
     300                 :  */
     301                 : extern void NCDecoderStateConstruct(NCDecoderState* tthis,
     302                 :                                     uint8_t* mbase, NaClPcAddress vbase,
     303                 :                                     NaClMemorySize sz,
     304                 :                                     NCDecoderInst* inst_buffer,
     305                 :                                     size_t inst_buffer_size);
     306                 : 
     307                 : /* Define an error reporter to use to report error messages.
     308                 :  * Note: By default, a decoder state uses the null error reporter,
     309                 :  * which doesn't report error messages.
     310                 :  *
     311                 :  * WARNING: Be sure the error reporter is expecting a NCDecoderInst* for
     312                 :  * the print_inst method.
     313                 :  */
     314                 : void NCDecoderStateSetErrorReporter(NCDecoderState* tthis,
     315                 :                                     NaClErrorReporter* reporter);
     316                 : 
     317                 : 
     318                 : /* A default, null error reporter for a NCDecoderInst* instruction. */
     319                 : extern NaClErrorReporter kNCNullErrorReporter;
     320                 : 
     321                 : /*
     322                 :  * Decodes the memory segment associated with the decoder state.
     323                 :  * Returns TRUE if able to apply action to all decoded instructions.
     324                 :  *
     325                 :  * Parameters are:
     326                 :  *   this  - The decoder state.
     327                 :  */
     328                 : extern Bool NCDecoderStateDecode(NCDecoderState* tthis);
     329                 : 
     330                 : /*
     331                 :  * Destruct a decoder state.
     332                 :  *
     333                 :  * Parameters are:
     334                 :  *   this  - The decoder state.
     335                 :  *
     336                 :  * Note: Destructors of subclasses of NCDecoderState should
     337                 :  * call this destructor last, after the subinstance has been destructed.
     338                 :  */
     339                 : extern void NCDecoderStateDestruct(NCDecoderState* tthis);
     340                 : 
     341                 : /* "Printable" means the value returned by this function can be used for
     342                 :  * printing user-readable output, but it should not be used to influence if the
     343                 :  * validation algorithm passes or fails.  The validation algorithm should not
     344                 :  * depend on vbase - in other words, it should not depend on where the code is
     345                 :  * being mapped in memory.
     346                 :  */
     347                 : static INLINE NaClPcAddress NCPrintableInstructionAddress(
     348               4 :     const NCDecoderInst *dinst) {
     349               4 :   return dinst->dstate->vbase + dinst->inst_addr;
     350               4 : }
     351                 : 
     352                 : struct NCDecoderStatePair;
     353                 : 
     354                 : /* Models a method that does a compare/update on a pair of instructions from
     355                 :  * the pairwise instruction decoder. Returns true if the action succeeded.
     356                 :  */
     357                 : typedef Bool (*NCDecoderStatePairAction)(struct NCDecoderStatePair* tthis,
     358                 :                                          struct NCDecoderInst* dinst_old,
     359                 :                                          struct NCDecoderInst* dinst_new);
     360                 : 
     361                 : /* Models decoding a pair of instruction segments, compariing/updating
     362                 :  * them as appropriate. Assumes that two instruction segments are the same,
     363                 :  * except for some (constant-sized) changes. At the instruction level,
     364                 :  * the instruction lengths are assumed to be the same. Typically, this is
     365                 :  * because the one instruction segment was an updated version of a
     366                 :  * previous instruction segment.
     367                 :  *
     368                 :  * Typical use is:
     369                 :  *
     370                 :  * NCDecoderState dstate_old;
     371                 :  * NCDecoderState dstate_new;
     372                 :  * NCDecoderStatePair dstate_pair;
     373                 :  * ... Code that constructs dstate_old and dstate_new.
     374                 :  * NCDecoderStatePair Construct(&dstate_pair, &dstate_old, &dstate_new);
     375                 :  * NCDecoderStatePairDecode(&dstate_pair);
     376                 :  * NCDecoderStatePairDestruct(&dstate_pair);
     377                 :  */
     378                 : typedef struct NCDecoderStatePair {
     379                 :   /* PROTECTED: */
     380                 : 
     381                 :   /* The old decoder state. */
     382                 :   NCDecoderState* old_dstate;
     383                 : 
     384                 :   /* The new decoder state. */
     385                 :   NCDecoderState* new_dstate;
     386                 : 
     387                 :   /* The (virtual method) action to apply to each instruction. */
     388                 :   NCDecoderStatePairAction action_fn;
     389                 : 
     390                 :   /* Utility function that copies a single instruction in memory, can be used in
     391                 :    * actions.
     392                 :    */
     393                 :   NaClCopyInstructionFunc copy_func;
     394                 : } NCDecoderStatePair;
     395                 : 
     396                 : /*
     397                 :  * Construct a decoder state pair.
     398                 :  *
     399                 :  * Parameters are:
     400                 :  *    tthis - The decoder state pair to construct.
     401                 :  *    old_dstate - A constructed old decoder state to use.
     402                 :  *    new_dstate - A constructed new decoder state to use.
     403                 :  *
     404                 :  * Note: Constructors of subclasses of NCDecoderStatePair should
     405                 :  * call this constructor first, to initialize the decoder pair fields.
     406                 :  */
     407                 : extern void NCDecoderStatePairConstruct(
     408                 :     NCDecoderStatePair* tthis,
     409                 :     NCDecoderState* old_dstate,
     410                 :     NCDecoderState* new_dstate,
     411                 :     NaClCopyInstructionFunc copy_func);
     412                 : 
     413                 : /*
     414                 :  * Decode the memory segments in each instruction state, applying
     415                 :  * the appropriate action on each instruction till either:
     416                 :  * (1) The instruction lengths differ.
     417                 :  * (2) The action returns false.
     418                 :  * Returns true if no instruction lengths differ, and the action
     419                 :  * returns true for all found instructions.
     420                 :  */
     421                 : extern Bool NCDecoderStatePairDecode(NCDecoderStatePair* tthis);
     422                 : 
     423                 : /*
     424                 :  * Destruct a decoder state pair.
     425                 :  *
     426                 :  * Note: Destructors of subclasses of NCDecoderStatePair should
     427                 :  * call this distructor last, after the subinstance has been destructed.
     428                 :  */
     429                 : extern void NCDecoderStatePairDestruct(NCDecoderStatePair* tthis);
     430                 : 
     431                 : EXTERN_C_END
     432                 : 
     433                 : #endif  /* NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_NCVAL_SEG_SFI_NCDECODE_H_ */

Generated by: LCOV version 1.7