LCOV - code coverage report
Current view: directory - src/trusted/validator_x86 - ncdis_segments.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 77 69 89.6 %
Date: 2014-06-18 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                 : #ifndef NACL_TRUSTED_BUT_NOT_TCB
       8                 : #error("This file is not meant for use in the TCB")
       9                 : #endif
      10                 : 
      11                 : #include "native_client/src/trusted/validator_x86/ncdis_segments.h"
      12                 : 
      13                 : #include <string.h>
      14                 : 
      15                 : #include "native_client/src/shared/platform/nacl_log.h"
      16                 : #include "native_client/src/trusted/validator/x86/decoder/nc_inst_iter.h"
      17                 : #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state_internal.h"
      18                 : #include "native_client/src/trusted/validator/x86/decoder/ncop_exps.h"
      19                 : #include "native_client/src/trusted/validator_x86/ncdis_decode_tables.h"
      20                 : #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncval_decode_tables.h"
      21                 : #include "native_client/src/trusted/validator/x86/ncval_seg_sfi/ncdecode_verbose.h"
      22                 : #include "native_client/src/trusted/validator/x86/nc_segment.h"
      23                 : 
      24                 : /* Returns true if the disassemble flag is in the given flag set. */
      25               0 : Bool NaClContainsDisasembleFlag(NaClDisassembleFlags flags,
      26               0 :                                 NaClDisassembleFlag flag) {
      27               0 :   return NaClHasBit(flags, NACL_DISASSEMBLE_FLAG(flag)) ? TRUE : FALSE;
      28                 : }
      29                 : 
      30                 : static const char* kHardCodedMessage = "[hard coded]";
      31                 : 
      32                 : /* Inspect the parsed instruction to print out the opcode sequence matched. */
      33             610 : static void NaClInstPrintOpcodeSeq(struct Gio* gout,
      34             610 :                                    const NaClInstState* state) {
      35             610 :   size_t count = 0;
      36             610 :   if (state->num_opcode_bytes == 0) {
      37                 :     /* Hard coded bytes sequence for instruction. */
      38              38 :     gprintf(gout, "  %s", kHardCodedMessage);
      39              38 :     count = strlen(kHardCodedMessage) + 2;
      40              38 :   } else {
      41                 :     /* Modeled instruction. Pull out parsed opcode bytes from parsed
      42                 :      * instruction.
      43                 :      */
      44             572 :     int i;
      45             572 :     gprintf(gout, " ");
      46             572 :     count = 1;
      47                 : 
      48                 :     /* Add prefix selector if applicable. */
      49             572 :     if (state->opcode_prefix) {
      50              64 :       gprintf(gout, " %02x", state->opcode_prefix);
      51              64 :       count += 3;
      52              64 :     }
      53                 : 
      54                 :     /* Add opcode bytes. */
      55            2784 :     for (i = 0; i < state->num_opcode_bytes; ++i) {
      56             820 :       gprintf(gout, " %02x", state->bytes.byte[state->num_prefix_bytes + i]);
      57             820 :       count += 3;
      58             820 :     }
      59             572 :     if (state->inst->flags & NACL_IFLAG(OpcodeInModRm)) {
      60             156 :       gprintf(gout, " / %d", modrm_opcode(state->modrm));
      61             156 :       count += 4;
      62             572 :     } else if (state->inst->flags & NACL_IFLAG(OpcodePlusR)) {
      63              40 :       gprintf(gout, " - r%d",
      64              20 :               NaClGetOpcodePlusR(state->inst->opcode_ext));
      65              20 :       count += 5;
      66              20 :     }
      67             572 :     if (state->inst->flags & NACL_IFLAG(OpcodeInModRmRm)) {
      68              28 :       gprintf(gout, " / %d", modrm_rm(state->modrm));
      69              28 :       count += 4;
      70              28 :     }
      71                 :     /* Add opcode for 0f0f instructions, where the opcode is the last
      72                 :      * byte of the instruction.
      73                 :      */
      74            1270 :     if ((state->num_opcode_bytes >= 2) &&
      75                 :         (0 == (state->inst->flags & NACL_IFLAG(Opcode0F0F))) &&
      76                 :         (0x0F == state->bytes.byte[state->num_prefix_bytes]) &&
      77                 :         (0x0F == state->bytes.byte[state->num_prefix_bytes + 1])) {
      78               2 :       gprintf(gout, " %02x", state->bytes.byte[state->bytes.length - 1]);
      79               2 :       count += 3;
      80               2 :     }
      81                 :   }
      82           14922 :   while (count < 30) {
      83           13702 :     gprintf(gout, " ");
      84           13702 :     ++count;
      85           13702 :   }
      86             610 : }
      87                 : 
      88                 : /* Disassemble the code segment, using the given decoder tables.
      89                 :  * Note: The decoder tables specified in the flags argument will
      90                 :  * be ignored.
      91                 :  *
      92                 :  * Parameters:
      93                 :  *    mbase - Memory region containing code segment.
      94                 :  *    vbase - PC address associated with first byte of memory region.
      95                 :  *    size - Number of bytes in memory region.
      96                 :  *    flags - Flags to use when decoding.
      97                 :  */
      98                 : static void NaClDisassembleSegmentUsingTables(
      99            1589 :     uint8_t* mbase, NaClPcAddress vbase,
     100            1589 :     NaClMemorySize size, NaClDisassembleFlags flags,
     101            1589 :     const struct NaClDecodeTables* decoder_tables)  {
     102            1589 :   NaClSegment segment;
     103            1589 :   NaClInstIter* iter;
     104            1589 :   struct Gio* gout = NaClLogGetGio();
     105            1589 :   Bool print_internals =
     106                 :       NaClHasBit(flags, NACL_DISASSEMBLE_FLAG(NaClDisassembleAddInternals));
     107            1589 :   NaClSegmentInitialize(mbase, vbase, size, &segment);
     108            1589 :   iter = NaClInstIterCreate(decoder_tables, &segment);
     109            1589 :   if (NULL == iter) {
     110               0 :     gprintf(gout, "Error: not enough memory\n");
     111               0 :   } else {
     112           10190 :     for (; NaClInstIterHasNext(iter); NaClInstIterAdvance(iter)) {
     113            3506 :       NaClInstState* state = NaClInstIterGetState(iter);
     114            3506 :       NaClInstStateInstPrint(gout, state);
     115            3506 :       if (print_internals) {
     116             610 :         NaClInstPrintOpcodeSeq(gout, state);
     117             610 :         NaClInstPrint(gout, state->decoder_tables, NaClInstStateInst(state));
     118             610 :         NaClExpVectorPrint(gout, state);
     119             610 :       }
     120            3506 :     }
     121            1589 :     NaClInstIterDestroy(iter);
     122                 :   }
     123            1589 : }
     124                 : 
     125            1589 : void NaClDisassembleSegment(uint8_t* mbase, NaClPcAddress vbase,
     126            1589 :                             NaClMemorySize size, NaClDisassembleFlags flags) {
     127            1589 :   if (NaClHasBit(flags, NACL_DISASSEMBLE_FLAG(NaClDisassembleFull))) {
     128             844 :     if (NaClHasBit(flags,
     129                 :                    NACL_DISASSEMBLE_FLAG(NaClDisassembleValidatorDecoder))) {
     130               0 :       gprintf(NaClLogGetGio(),
     131                 :               "Error: can't specify both full and validator disassembly,\n"
     132                 :               "       assuming full disassembly.\n");
     133               0 :     }
     134             844 :     NaClDisassembleSegmentUsingTables(mbase, vbase, size, flags,
     135                 :                                       kNaClDecoderTables);
     136            1589 :   } else if (NaClHasBit
     137                 :              (flags,
     138                 :               NACL_DISASSEMBLE_FLAG(NaClDisassembleValidatorDecoder))) {
     139                 :     if (64 == NACL_TARGET_SUBARCH) {
     140             745 :       NaClDisassembleSegmentUsingTables(mbase, vbase, size, flags,
     141                 :                                         kNaClValDecoderTables);
     142                 :     } else {
     143                 :       NCDecodeSegment(mbase, vbase, size);
     144                 :     }
     145             745 :   } else {
     146               0 :     gprintf(NaClLogGetGio(),
     147                 :             "Error: No decoder tables specified, can't disassemble\n");
     148                 :   }
     149            1589 : }

Generated by: LCOV version 1.7