| OLD | NEW |
| (Empty) |
| 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_tab
les.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 Bool NaClContainsDisasembleFlag(NaClDisassembleFlags flags, | |
| 26 NaClDisassembleFlag flag) { | |
| 27 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 static void NaClInstPrintOpcodeSeq(struct Gio* gout, | |
| 34 const NaClInstState* state) { | |
| 35 size_t count = 0; | |
| 36 if (state->num_opcode_bytes == 0) { | |
| 37 /* Hard coded bytes sequence for instruction. */ | |
| 38 gprintf(gout, " %s", kHardCodedMessage); | |
| 39 count = strlen(kHardCodedMessage) + 2; | |
| 40 } else { | |
| 41 /* Modeled instruction. Pull out parsed opcode bytes from parsed | |
| 42 * instruction. | |
| 43 */ | |
| 44 int i; | |
| 45 gprintf(gout, " "); | |
| 46 count = 1; | |
| 47 | |
| 48 /* Add prefix selector if applicable. */ | |
| 49 if (state->opcode_prefix) { | |
| 50 gprintf(gout, " %02x", state->opcode_prefix); | |
| 51 count += 3; | |
| 52 } | |
| 53 | |
| 54 /* Add opcode bytes. */ | |
| 55 for (i = 0; i < state->num_opcode_bytes; ++i) { | |
| 56 gprintf(gout, " %02x", state->bytes.byte[state->num_prefix_bytes + i]); | |
| 57 count += 3; | |
| 58 } | |
| 59 if (state->inst->flags & NACL_IFLAG(OpcodeInModRm)) { | |
| 60 gprintf(gout, " / %d", modrm_opcode(state->modrm)); | |
| 61 count += 4; | |
| 62 } else if (state->inst->flags & NACL_IFLAG(OpcodePlusR)) { | |
| 63 gprintf(gout, " - r%d", | |
| 64 NaClGetOpcodePlusR(state->inst->opcode_ext)); | |
| 65 count += 5; | |
| 66 } | |
| 67 if (state->inst->flags & NACL_IFLAG(OpcodeInModRmRm)) { | |
| 68 gprintf(gout, " / %d", modrm_rm(state->modrm)); | |
| 69 count += 4; | |
| 70 } | |
| 71 /* Add opcode for 0f0f instructions, where the opcode is the last | |
| 72 * byte of the instruction. | |
| 73 */ | |
| 74 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 gprintf(gout, " %02x", state->bytes.byte[state->bytes.length - 1]); | |
| 79 count += 3; | |
| 80 } | |
| 81 } | |
| 82 while (count < 30) { | |
| 83 gprintf(gout, " "); | |
| 84 ++count; | |
| 85 } | |
| 86 } | |
| 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 uint8_t* mbase, NaClPcAddress vbase, | |
| 100 NaClMemorySize size, NaClDisassembleFlags flags, | |
| 101 const struct NaClDecodeTables* decoder_tables) { | |
| 102 NaClSegment segment; | |
| 103 NaClInstIter* iter; | |
| 104 struct Gio* gout = NaClLogGetGio(); | |
| 105 Bool print_internals = | |
| 106 NaClHasBit(flags, NACL_DISASSEMBLE_FLAG(NaClDisassembleAddInternals)); | |
| 107 NaClSegmentInitialize(mbase, vbase, size, &segment); | |
| 108 iter = NaClInstIterCreate(decoder_tables, &segment); | |
| 109 if (NULL == iter) { | |
| 110 gprintf(gout, "Error: not enough memory\n"); | |
| 111 } else { | |
| 112 for (; NaClInstIterHasNext(iter); NaClInstIterAdvance(iter)) { | |
| 113 NaClInstState* state = NaClInstIterGetState(iter); | |
| 114 NaClInstStateInstPrint(gout, state); | |
| 115 if (print_internals) { | |
| 116 NaClInstPrintOpcodeSeq(gout, state); | |
| 117 NaClInstPrint(gout, state->decoder_tables, NaClInstStateInst(state)); | |
| 118 NaClExpVectorPrint(gout, state); | |
| 119 } | |
| 120 } | |
| 121 NaClInstIterDestroy(iter); | |
| 122 } | |
| 123 } | |
| 124 | |
| 125 void NaClDisassembleSegment(uint8_t* mbase, NaClPcAddress vbase, | |
| 126 NaClMemorySize size, NaClDisassembleFlags flags) { | |
| 127 if (NaClHasBit(flags, NACL_DISASSEMBLE_FLAG(NaClDisassembleFull))) { | |
| 128 if (NaClHasBit(flags, | |
| 129 NACL_DISASSEMBLE_FLAG(NaClDisassembleValidatorDecoder))) { | |
| 130 gprintf(NaClLogGetGio(), | |
| 131 "Error: can't specify both full and validator disassembly,\n" | |
| 132 " assuming full disassembly.\n"); | |
| 133 } | |
| 134 NaClDisassembleSegmentUsingTables(mbase, vbase, size, flags, | |
| 135 kNaClDecoderTables); | |
| 136 } else if (NaClHasBit | |
| 137 (flags, | |
| 138 NACL_DISASSEMBLE_FLAG(NaClDisassembleValidatorDecoder))) { | |
| 139 if (64 == NACL_TARGET_SUBARCH) { | |
| 140 NaClDisassembleSegmentUsingTables(mbase, vbase, size, flags, | |
| 141 kNaClValDecoderTables); | |
| 142 } else { | |
| 143 NCDecodeSegment(mbase, vbase, size); | |
| 144 } | |
| 145 } else { | |
| 146 gprintf(NaClLogGetGio(), | |
| 147 "Error: No decoder tables specified, can't disassemble\n"); | |
| 148 } | |
| 149 } | |
| OLD | NEW |