| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 #include "native_client/src/trusted/validator/x86/decoder/ncop_exps.h" | 7 #include "native_client/src/trusted/validator/x86/decoder/ncop_exps.h" |
| 8 | 8 |
| 9 #include <stdio.h> | 9 #include <stdio.h> |
| 10 #include <ctype.h> | 10 #include <ctype.h> |
| 11 #include <string.h> | 11 #include <string.h> |
| 12 #include <assert.h> | 12 #include <assert.h> |
| 13 #include <sys/stat.h> | 13 #include <sys/stat.h> |
| 14 | 14 |
| 15 #include "native_client/src/include/portability.h" | 15 #include "native_client/src/include/portability.h" |
| 16 #include "native_client/src/shared/platform/nacl_log.h" | 16 #include "native_client/src/shared/platform/nacl_log.h" |
| 17 #include "native_client/src/shared/utils/types.h" | 17 #include "native_client/src/shared/utils/types.h" |
| 18 #include "native_client/src/trusted/validator/x86/decoder/gen/ncop_expr_node_fla
g_impl.h" | 18 #include "native_client/src/trusted/validator/x86/decoder/gen/ncop_expr_node_fla
g_impl.h" |
| 19 #include "native_client/src/trusted/validator/x86/decoder/gen/ncop_expr_node_kin
d_impl.h" | 19 #include "native_client/src/trusted/validator/x86/decoder/gen/ncop_expr_node_kin
d_impl.h" |
| 20 #include "native_client/src/trusted/validator/x86/decoder/ncopcode_desc_inl.h" |
| 21 #include "native_client/src/trusted/validator/x86/decoder/ncop_exps_inl.h" |
| 20 #include "native_client/src/trusted/validator/x86/decoder/nc_decode_tables_types
.h" | 22 #include "native_client/src/trusted/validator/x86/decoder/nc_decode_tables_types
.h" |
| 21 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state_internal
.h" | 23 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state_internal
.h" |
| 22 | 24 |
| 23 /* To turn on debugging of instruction decoding, change value of | 25 /* To turn on debugging of instruction decoding, change value of |
| 24 * DEBUGGING to 1. | 26 * DEBUGGING to 1. |
| 25 * | 27 * |
| 26 * WARNING: Debugging messages inside of print messages must be sent to the | 28 * WARNING: Debugging messages inside of print messages must be sent to the |
| 27 * same gio stream as being printed, since they may be used by another | 29 * same gio stream as being printed, since they may be used by another |
| 28 * nacl log message that has locked the access to NaClLogGetGio(). | 30 * nacl log message that has locked the access to NaClLogGetGio(). |
| 29 */ | 31 */ |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 {ExprMemOffset, 4}, | 71 {ExprMemOffset, 4}, |
| 70 }; | 72 }; |
| 71 | 73 |
| 72 int NaClExpKindRank(NaClExpKind kind) { | 74 int NaClExpKindRank(NaClExpKind kind) { |
| 73 assert(kind == g_NaClExpKindDesc[kind].name); | 75 assert(kind == g_NaClExpKindDesc[kind].name); |
| 74 return g_NaClExpKindDesc[kind].rank; | 76 return g_NaClExpKindDesc[kind].rank; |
| 75 } | 77 } |
| 76 | 78 |
| 77 /* Returns the register defined by the given node. */ | 79 /* Returns the register defined by the given node. */ |
| 78 NaClOpKind NaClGetExpRegister(NaClExp* node) { | 80 NaClOpKind NaClGetExpRegister(NaClExp* node) { |
| 79 assert(node->kind == ExprRegister); | 81 return NaClGetExpRegisterInline(node); |
| 80 return (NaClOpKind) node->value; | |
| 81 } | 82 } |
| 82 | 83 |
| 83 /* Returns the name of the register defined by the indexed node in the | 84 /* Returns the name of the register defined by the indexed node in the |
| 84 * vector of nodes. | 85 * vector of nodes. |
| 85 */ | 86 */ |
| 86 NaClOpKind NaClGetExpVectorRegister(NaClExpVector* vector, | 87 NaClOpKind NaClGetExpVectorRegister(NaClExpVector* vector, |
| 87 int node) { | 88 int node) { |
| 88 return NaClGetExpRegister(&vector->node[node]); | 89 return NaClGetExpRegisterInline(&vector->node[node]); |
| 89 } | 90 } |
| 90 | 91 |
| 91 static int NaClPrintDisassembledExp(struct Gio* file, | 92 static int NaClPrintDisassembledExp(struct Gio* file, |
| 92 NaClExpVector* vector, | 93 NaClExpVector* vector, |
| 93 uint32_t index); | 94 uint32_t index); |
| 94 | 95 |
| 95 /* Print the characters in the given string using lower case. */ | 96 /* Print the characters in the given string using lower case. */ |
| 96 static void NaClPrintLower(struct Gio* file, char* str) { | 97 static void NaClPrintLower(struct Gio* file, char* str) { |
| 97 while (*str) { | 98 while (*str) { |
| 98 gprintf(file, "%c", tolower(*str)); | 99 gprintf(file, "%c", tolower(*str)); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 * to the given file. | 162 * to the given file. |
| 162 */ | 163 */ |
| 163 static void NaClPrintDisassembledRegKind(struct Gio* file, NaClOpKind reg) { | 164 static void NaClPrintDisassembledRegKind(struct Gio* file, NaClOpKind reg) { |
| 164 const char* name = NaClOpKindName(reg); | 165 const char* name = NaClOpKindName(reg); |
| 165 char* str = strstr(name, "Reg"); | 166 char* str = strstr(name, "Reg"); |
| 166 gprintf(file, "%c", '%'); | 167 gprintf(file, "%c", '%'); |
| 167 NaClPrintLower(file, str == NULL ? (char*) name : str + strlen("Reg")); | 168 NaClPrintLower(file, str == NULL ? (char*) name : str + strlen("Reg")); |
| 168 } | 169 } |
| 169 | 170 |
| 170 static INLINE void NaClPrintDisassembledReg(struct Gio* file, NaClExp* node) { | 171 static INLINE void NaClPrintDisassembledReg(struct Gio* file, NaClExp* node) { |
| 171 NaClPrintDisassembledRegKind(file, NaClGetExpRegister(node)); | 172 NaClPrintDisassembledRegKind(file, NaClGetExpRegisterInline(node)); |
| 172 } | 173 } |
| 173 | 174 |
| 174 void NaClExpVectorPrint(struct Gio* file, NaClExpVector* vector) { | 175 void NaClExpVectorPrint(struct Gio* file, NaClExpVector* vector) { |
| 175 uint32_t i; | 176 uint32_t i; |
| 176 gprintf(file, "NaClExpVector[%d] = {\n", vector->number_expr_nodes); | 177 gprintf(file, "NaClExpVector[%d] = {\n", vector->number_expr_nodes); |
| 177 for (i = 0; i < vector->number_expr_nodes; i++) { | 178 for (i = 0; i < vector->number_expr_nodes; i++) { |
| 178 NaClExp* node = &vector->node[i]; | 179 NaClExp* node = &vector->node[i]; |
| 179 gprintf(file, " { %s[%d] , ", | 180 gprintf(file, " { %s[%d] , ", |
| 180 NaClExpKindName(node->kind), | 181 NaClExpKindName(node->kind), |
| 181 NaClExpKindRank(node->kind)); | 182 NaClExpKindRank(node->kind)); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 */ | 300 */ |
| 300 static Bool NaClHasSegmentOverride(NaClExpVector* vector, | 301 static Bool NaClHasSegmentOverride(NaClExpVector* vector, |
| 301 int seg_addr_index, | 302 int seg_addr_index, |
| 302 NaClExpFlag seg_eflag, | 303 NaClExpFlag seg_eflag, |
| 303 NaClOpKind seg_reg) { | 304 NaClOpKind seg_reg) { |
| 304 NaClExp* seg_node = &vector->node[seg_addr_index]; | 305 NaClExp* seg_node = &vector->node[seg_addr_index]; |
| 305 if (seg_node->flags & NACL_EFLAG(seg_eflag)) { | 306 if (seg_node->flags & NACL_EFLAG(seg_eflag)) { |
| 306 int seg_index = seg_addr_index + 1; | 307 int seg_index = seg_addr_index + 1; |
| 307 NaClExp* node = &vector->node[seg_index]; | 308 NaClExp* node = &vector->node[seg_index]; |
| 308 if ((ExprRegister == node->kind) && | 309 if ((ExprRegister == node->kind) && |
| 309 (seg_reg != NaClGetExpRegister(node))) { | 310 (seg_reg != NaClGetExpRegisterInline(node))) { |
| 310 return TRUE; | 311 return TRUE; |
| 311 } | 312 } |
| 312 } | 313 } |
| 313 return FALSE; | 314 return FALSE; |
| 314 } | 315 } |
| 315 | 316 |
| 316 /* Prints out the segment register associated with the segment | 317 /* Prints out the segment register associated with the segment |
| 317 * address node defined by vector[seg_addr_index]. | 318 * address node defined by vector[seg_addr_index]. |
| 318 * | 319 * |
| 319 * Parameters: | 320 * Parameters: |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 } else { | 389 } else { |
| 389 gprintf(file, ", "); | 390 gprintf(file, ", "); |
| 390 } | 391 } |
| 391 NaClPrintDisassembledExp(file, vector, tree_index); | 392 NaClPrintDisassembledExp(file, vector, tree_index); |
| 392 | 393 |
| 393 /* If this is a partial instruction, add set/use information | 394 /* If this is a partial instruction, add set/use information |
| 394 * so that that it is more clear what was matched. | 395 * so that that it is more clear what was matched. |
| 395 */ | 396 */ |
| 396 if (NaClHasBit(inst->flags, NACL_IFLAG(PartialInstruction)) && | 397 if (NaClHasBit(inst->flags, NACL_IFLAG(PartialInstruction)) && |
| 397 node->kind == OperandReference) { | 398 node->kind == OperandReference) { |
| 398 const NaClOp* op = NaClGetInstOperand(state->decoder_tables, | 399 const NaClOp* op = |
| 399 inst, (uint8_t) node->value); | 400 NaClGetInstOperandInline(state->decoder_tables, |
| 401 inst, (uint8_t) node->value); |
| 400 if (NaClHasBit(op->flags, (NACL_OPFLAG(OpSet) | | 402 if (NaClHasBit(op->flags, (NACL_OPFLAG(OpSet) | |
| 401 NACL_OPFLAG(OpUse) | | 403 NACL_OPFLAG(OpUse) | |
| 402 NACL_OPFLAG(OperandZeroExtends_v)))) { | 404 NACL_OPFLAG(OperandZeroExtends_v)))) { |
| 403 gprintf(file, " ("); | 405 gprintf(file, " ("); |
| 404 NaClPrintAddOperandFlag(file, op, OpSet, "s"); | 406 NaClPrintAddOperandFlag(file, op, OpSet, "s"); |
| 405 NaClPrintAddOperandFlag(file, op, OpUse, "u"); | 407 NaClPrintAddOperandFlag(file, op, OpUse, "u"); |
| 406 NaClPrintAddOperandFlag(file, op, OperandZeroExtends_v, "z"); | 408 NaClPrintAddOperandFlag(file, op, OperandZeroExtends_v, "z"); |
| 407 gprintf(file, ")"); | 409 gprintf(file, ")"); |
| 408 } | 410 } |
| 409 } | 411 } |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 /* Assume signed value. */ | 602 /* Assume signed value. */ |
| 601 int64_t value = (int64_t) NaClGetExpConstant(vector, index); | 603 int64_t value = (int64_t) NaClGetExpConstant(vector, index); |
| 602 return value < 0; | 604 return value < 0; |
| 603 } | 605 } |
| 604 break; | 606 break; |
| 605 default: | 607 default: |
| 606 break; | 608 break; |
| 607 } | 609 } |
| 608 return FALSE; | 610 return FALSE; |
| 609 } | 611 } |
| 612 |
| 613 /* Dummy routine to allow unreferenced NaClGetInstNumberOperandsInline |
| 614 * inline. |
| 615 */ |
| 616 uint8_t NaClNcopExpsDummyNaClGetInstNumberOperands(const NaClInst* inst) { |
| 617 return NaClGetInstNumberOperandsInline(inst); |
| 618 } |
| OLD | NEW |