const char *NaClOpcodeName(NaClInstStruct *inst) { const struct NaClInst *nacl_opcode = NaClInstStateInst(inst); return NaClMnemonicName(nacl_opcode->name); }
/* Print the given instruction opcode of the give state, to the * given file. */ static void NaClPrintDisassembled(struct Gio* file, NaClInstState* state, const NaClInst* inst) { uint32_t tree_index = 0; Bool is_first = TRUE; Bool not_printed_prefix_segment = TRUE; NaClExp* node; NaClExpVector* vector = NaClInstStateExpVector(state); /* Print the name of the instruction. */ if (NaClHasBit(inst->flags, NACL_IFLAG(PartialInstruction))) { /* Instruction has been simplified. Print out corresponding * hints to the reader, so that they know that the instruction * has been simplified. */ gprintf(file, "[P] "); NaClPrintLower(file, (char*) NaClMnemonicName(inst->name)); if (NaClHasBit(inst->flags, NACL_IFLAG(NaClIllegal))) { gprintf(file, "(illegal)"); } } else { NaClPrintLower(file, (char*) NaClMnemonicName(inst->name)); } /* Use the generated expression tree to print out (non-implicit) operands * of the instruction. */ while (tree_index < vector->number_expr_nodes) { node = &vector->node[tree_index]; if (node->kind != OperandReference || (NACL_EMPTY_EFLAGS == (node->flags & NACL_EFLAG(ExprImplicit)))) { if (is_first) { gprintf(file, " "); is_first = FALSE; } else { gprintf(file, ", "); } NaClPrintDisassembledExp(file, state, tree_index); /* If this is a partial instruction, add set/use information * so that that it is more clear what was matched. */ if (NaClHasBit(inst->flags, NACL_IFLAG(PartialInstruction)) && node->kind == OperandReference) { const NaClOp* op = NaClGetInstOperandInline(state->decoder_tables, inst, (uint8_t) NaClGetExprUnsignedValue(node)); if (NaClHasBit(op->flags, (NACL_OPFLAG(OpSet) | NACL_OPFLAG(OpUse) | NACL_OPFLAG(OperandZeroExtends_v)))) { gprintf(file, " ("); NaClPrintAddOperandFlag(file, op, OpSet, "s"); NaClPrintAddOperandFlag(file, op, OpUse, "u"); NaClPrintAddOperandFlag(file, op, OperandZeroExtends_v, "z"); gprintf(file, ")"); } } } else if (not_printed_prefix_segment && (OperandReference == node->kind) && (node->flags & NACL_EFLAG(ExprImplicit))) { /* Print out segment override of implicit segment address, if * applicable. */ if (OperandReference == node->kind) { int seg_addr_index = tree_index + 1; if (ExprSegmentAddress == vector->node[seg_addr_index].kind) { if (NaClHasSegmentOverride(vector, seg_addr_index, ExprDSrCase, RegDS)) { NaClPrintSegmentOverride(file, &is_first, state, vector, seg_addr_index); } else if (NaClHasSegmentOverride(vector, seg_addr_index, ExprESrCase, RegES)) { NaClPrintSegmentOverride(file, &is_first, state, vector, seg_addr_index); } } } } /* Skip over expression to next expresssion. */ tree_index += NaClExpWidth(vector, tree_index); } }