/* Capstone Disassembler Engine */ /* By Nguyen Anh Quynh , 2013> */ #include #include #include "capstone/ppc.h" #include "cstool.h" static const char* get_pred_name(ppc_pred pred) { switch(pred) { default: return ("invalid"); case PPC_PRED_LT: case PPC_PRED_LT_MINUS: case PPC_PRED_LT_PLUS: case PPC_PRED_LT_RESERVED: return ("lt"); case PPC_PRED_LE: case PPC_PRED_LE_MINUS: case PPC_PRED_LE_PLUS: case PPC_PRED_LE_RESERVED: return ("le"); case PPC_PRED_EQ: case PPC_PRED_EQ_MINUS: case PPC_PRED_EQ_PLUS: case PPC_PRED_EQ_RESERVED: return ("eq"); case PPC_PRED_GE: case PPC_PRED_GE_MINUS: case PPC_PRED_GE_PLUS: case PPC_PRED_GE_RESERVED: return ("ge"); case PPC_PRED_GT: case PPC_PRED_GT_MINUS: case PPC_PRED_GT_PLUS: case PPC_PRED_GT_RESERVED: return ("gt"); case PPC_PRED_NE: case PPC_PRED_NE_MINUS: case PPC_PRED_NE_PLUS: case PPC_PRED_NE_RESERVED: return ("ne"); case PPC_PRED_UN: // PPC_PRED_SO case PPC_PRED_UN_MINUS: case PPC_PRED_UN_PLUS: case PPC_PRED_UN_RESERVED: return ("so/un"); case PPC_PRED_NU: // PPC_PRED_NS case PPC_PRED_NU_MINUS: case PPC_PRED_NU_PLUS: case PPC_PRED_NU_RESERVED: return ("ns/nu"); case PPC_PRED_NZ: case PPC_PRED_NZ_MINUS: case PPC_PRED_NZ_PLUS: case PPC_PRED_NZ_RESERVED: return ("nz"); case PPC_PRED_Z: case PPC_PRED_Z_MINUS: case PPC_PRED_Z_PLUS: case PPC_PRED_Z_RESERVED: return ("z"); case PPC_PRED_BIT_SET: return "bit-set"; case PPC_PRED_BIT_UNSET: return "bit-unset"; } } static const char *get_pred_hint(ppc_br_hint at) { switch (at) { default: return "invalid"; case PPC_BR_NOT_GIVEN: return "not-given"; case PPC_BR_TAKEN: return "likely-taken"; case PPC_BR_NOT_TAKEN: return "likely-not-taken"; case PPC_BR_RESERVED: return "reserved"; } } void print_insn_detail_ppc(csh handle, cs_insn *ins) { cs_ppc *ppc; int i; // detail can be NULL on "data" instruction if SKIPDATA option is turned ON if (ins->detail == NULL) return; ppc = &(ins->detail->ppc); if (ppc->op_count) printf("\top_count: %u\n", ppc->op_count); for (i = 0; i < ppc->op_count; i++) { cs_ppc_op *op = &(ppc->operands[i]); switch((int)op->type) { default: break; case PPC_OP_REG: printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg)); break; case PPC_OP_IMM: printf("\t\toperands[%u].type: IMM = 0x%"PRIx64"\n", i, op->imm); break; case PPC_OP_MEM: printf("\t\toperands[%u].type: MEM\n", i); if (op->mem.base != PPC_REG_INVALID) printf("\t\t\toperands[%u].mem.base: REG = %s\n", i, cs_reg_name(handle, op->mem.base)); if (op->mem.offset != PPC_REG_INVALID) printf("\t\t\toperands[%u].mem.offset: REG = %s\n", i, cs_reg_name(handle, op->mem.offset)); if (op->mem.disp != 0) printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp); break; } switch(op->access) { default: break; case CS_AC_READ: printf("\t\toperands[%u].access: READ\n", i); break; case CS_AC_WRITE: printf("\t\toperands[%u].access: WRITE\n", i); break; case CS_AC_READ_WRITE: printf("\t\toperands[%u].access: READ | WRITE\n", i); break; } } if (ppc->bc.pred_cr != PPC_PRED_INVALID || ppc->bc.pred_ctr != PPC_PRED_INVALID) { printf("\tBranch:\n"); printf("\t\tbi: %u\n", ppc->bc.bi); printf("\t\tbo: %u\n", ppc->bc.bo); if (ppc->bc.bh != PPC_BH_INVALID) printf("\t\tbh: %u\n", ppc->bc.bh); if (ppc->bc.pred_cr != PPC_PRED_INVALID) { printf("\t\tcrX: %s\n", cs_reg_name(handle, ppc->bc.crX)); printf("\t\tpred CR-bit: %s\n", get_pred_name(ppc->bc.pred_cr)); } if (ppc->bc.pred_ctr != PPC_PRED_INVALID) printf("\t\tpred CTR: %s\n", get_pred_name(ppc->bc.pred_ctr)); if (ppc->bc.hint != PPC_BR_NOT_GIVEN) printf("\t\thint: %s\n", get_pred_hint(ppc->bc.hint)); } if (ppc->bc.hint != PPC_BR_NOT_GIVEN) printf("\tBranch hint: %u\n", ppc->bc.hint); if (ppc->update_cr0) printf("\tUpdate-CR0: True\n"); uint16_t *regs_read = ins->detail->regs_read; uint16_t *regs_write = ins->detail->regs_write; uint8_t regs_read_count = ins->detail->regs_read_count; uint8_t regs_write_count = ins->detail->regs_write_count; // Print out all registers accessed by this instruction (either implicit or explicit) if (regs_read_count) { printf("\tImplicit registers read:"); for(i = 0; i < regs_read_count; i++) { printf(" %s", cs_reg_name(handle, regs_read[i])); } printf("\n"); } if (regs_write_count) { printf("\tImplicit registers modified:"); for(i = 0; i < regs_write_count; i++) { printf(" %s", cs_reg_name(handle, regs_write[i])); } printf("\n"); } }