Beispiel #1
0
static void printSaveRestore(MCInst *MI, SStream *O)
{
	unsigned i, e;
	for (i = 0, e = MCInst_getNumOperands(MI); i != e; ++i) {
		if (i != 0)
			SStream_concat(O, ", ");
		if (MCOperand_isReg(MCInst_getOperand(MI, i)))
			printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, i)));
		else
			printUnsignedImm(MI, i, O);
	}
}
Beispiel #2
0
// local printOperand, without updating public operands
static void _printOperand(MCInst *MI, unsigned OpNo, SStream *O)
{
	MCOperand *Op  = MCInst_getOperand(MI, OpNo);
	if (MCOperand_isReg(Op)) {
		printRegName(O, MCOperand_getReg(Op));
	} else if (MCOperand_isImm(Op)) {
		uint8_t encsize;
		uint8_t opsize = X86_immediate_size(MCInst_getOpcode(MI), &encsize);

		// Print X86 immediates as signed values.
		int64_t imm = MCOperand_getImm(Op);
		if (imm < 0) {
			if (MI->csh->imm_unsigned) {
				if (opsize) {
					switch(opsize) {
						default:
							break;
						case 1:
							imm &= 0xff;
							break;
						case 2:
							imm &= 0xffff;
							break;
						case 4:
							imm &= 0xffffffff;
							break;
					}
				}

				SStream_concat(O, "$0x%"PRIx64, imm);
			} else {
				if (imm < -HEX_THRESHOLD)
					SStream_concat(O, "$-0x%"PRIx64, -imm);
				else
					SStream_concat(O, "$-%"PRIu64, -imm);
			}
		} else {
			if (imm > HEX_THRESHOLD)
				SStream_concat(O, "$0x%"PRIx64, imm);
			else
				SStream_concat(O, "$%"PRIu64, imm);
		}
	}
}
Beispiel #3
0
// local printOperand, without updating public operands
static void _printOperand(MCInst *MI, unsigned OpNo, SStream *O)
{
    MCOperand *Op  = MCInst_getOperand(MI, OpNo);
    if (MCOperand_isReg(Op)) {
        printRegName(O, MCOperand_getReg(Op));
    } else if (MCOperand_isImm(Op)) {
        int64_t imm = MCOperand_getImm(Op);
        if (imm < 0) {
            if (imm <= -HEX_THRESHOLD)
                SStream_concat(O, "-0x%"PRIx64, -imm);
            else
                SStream_concat(O, "-%"PRIu64, -imm);
        } else {
            if (imm > HEX_THRESHOLD)
                SStream_concat(O, "0x%"PRIx64, imm);
            else
                SStream_concat(O, "%"PRIu64, imm);
        }
    }
}
Beispiel #4
0
// local printOperand, without updating public operands
static void _printOperand(MCInst *MI, unsigned OpNo, SStream *O)
{
	MCOperand *Op  = MCInst_getOperand(MI, OpNo);
	if (MCOperand_isReg(Op)) {
		printRegName(O, MCOperand_getReg(Op));
	} else if (MCOperand_isImm(Op)) {
		// Print X86 immediates as signed values.
		int64_t imm = MCOperand_getImm(Op);
		if (imm < 0) {
			if (imm < -HEX_THRESHOLD)
				SStream_concat(O, "$-0x%"PRIx64, -imm);
			else
				SStream_concat(O, "$-%"PRIu64, -imm);
		} else {
			if (imm > HEX_THRESHOLD)
				SStream_concat(O, "$0x%"PRIx64, imm);
			else
				SStream_concat(O, "$%"PRIu64, imm);
		}
	}
}
Beispiel #5
0
static void printOperand(MCInst *MI, int opNum, SStream *O)
{
	int Imm;
	unsigned reg;
	MCOperand *MO = MCInst_getOperand(MI, opNum);

	if (MCOperand_isReg(MO)) {
		reg = MCOperand_getReg(MO);
		printRegName(O, reg);
		reg = Sparc_map_register(reg);

		if (MI->csh->detail) {
			if (MI->csh->doing_mem) {
				if (MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.base)
					MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.index = reg;
				else
					MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.base = reg;
			} else {
				MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].type = SPARC_OP_REG;
				MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].reg = reg;
				MI->flat_insn->detail->sparc.op_count++;
			}
		}

		return;
	}

	if (MCOperand_isImm(MO)) {
		Imm = (int)MCOperand_getImm(MO);

		// Conditional branches displacements needs to be signextended to be
		// able to jump backwards.
		//
		// Displacements are measured as the number of instructions forward or
		// backward, so they need to be multiplied by 4
		switch (MI->Opcode) {
			case SP_CALL:
				Imm = SignExtend32(Imm, 30);
				Imm += (uint32_t)MI->address;
				break;

			// Branch on integer condition with prediction (BPcc)
			// Branch on floating point condition with prediction (FBPfcc)
			case SP_BPICC:
			case SP_BPICCA:
			case SP_BPICCANT:
			case SP_BPICCNT:
			case SP_BPXCC:
			case SP_BPXCCA:
			case SP_BPXCCANT:
			case SP_BPXCCNT:
			case SP_BPFCC:
			case SP_BPFCCA:
			case SP_BPFCCANT:
			case SP_BPFCCNT:
				Imm = SignExtend32(Imm, 19);
				Imm = (uint32_t)MI->address + Imm * 4;
				break;

			// Branch on integer condition (Bicc)
			// Branch on floating point condition (FBfcc)
			case SP_BA:
			case SP_BCOND:
			case SP_BCONDA:
			case SP_FBCOND:
			case SP_FBCONDA:
				Imm = SignExtend32(Imm, 22);
				Imm = (uint32_t)MI->address + Imm * 4;
				break;

			// Branch on integer register with prediction (BPr)
			case SP_BPGEZapn:
			case SP_BPGEZapt:
			case SP_BPGEZnapn:
			case SP_BPGEZnapt:
			case SP_BPGZapn:
			case SP_BPGZapt:
			case SP_BPGZnapn:
			case SP_BPGZnapt:
			case SP_BPLEZapn:
			case SP_BPLEZapt:
			case SP_BPLEZnapn:
			case SP_BPLEZnapt:
			case SP_BPLZapn:
			case SP_BPLZapt:
			case SP_BPLZnapn:
			case SP_BPLZnapt:
			case SP_BPNZapn:
			case SP_BPNZapt:
			case SP_BPNZnapn:
			case SP_BPNZnapt:
			case SP_BPZapn:
			case SP_BPZapt:
			case SP_BPZnapn:
			case SP_BPZnapt:
				Imm = SignExtend32(Imm, 16);
				Imm = (uint32_t)MI->address + Imm * 4;
				break;
		}

		if (Imm >= 0) {
			if (Imm > HEX_THRESHOLD)
				SStream_concat(O, "0x%x", Imm);
			else
				SStream_concat(O, "%u", Imm);
		} else {
			if (Imm < -HEX_THRESHOLD)
				SStream_concat(O, "-0x%x", -Imm);
			else
				SStream_concat(O, "-%u", -Imm);
		}

		if (MI->csh->detail) {
			if (MI->csh->doing_mem) {
				MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.disp = Imm;
			} else {
				MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].type = SPARC_OP_IMM;
				MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].imm = Imm;
				MI->flat_insn->detail->sparc.op_count++;
			}
		}
	}

	return;
}
Beispiel #6
0
static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
{
	uint8_t opsize = 0;
	MCOperand *Op  = MCInst_getOperand(MI, OpNo);

	if (MCOperand_isReg(Op)) {
		unsigned int reg = MCOperand_getReg(Op);
		printRegName(O, reg);
		if (MI->csh->detail) {
			if (MI->csh->doing_mem) {
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = reg;
			} else {
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_REG;
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].reg = reg;
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->csh->regsize_map[reg];
				MI->flat_insn->detail->x86.op_count++;
			}
		}
	} else if (MCOperand_isImm(Op)) {
		// Print X86 immediates as signed values.
		int64_t imm = MCOperand_getImm(Op);

		switch(MCInst_getOpcode(MI)) {
			default:
				break;

			case X86_AAD8i8:
			case X86_AAM8i8:
			case X86_ADC8i8:
			case X86_ADD8i8:
			case X86_AND8i8:
			case X86_CMP8i8:
			case X86_OR8i8:
			case X86_SBB8i8:
			case X86_SUB8i8:
			case X86_TEST8i8:
			case X86_XOR8i8:
			case X86_ROL8ri:
			case X86_ADC8ri:
			case X86_ADD8ri:
			case X86_ADD8ri8:
			case X86_AND8ri:
			case X86_AND8ri8:
			case X86_CMP8ri:
			case X86_MOV8ri:
			case X86_MOV8ri_alt:
			case X86_OR8ri:
			case X86_OR8ri8:
			case X86_RCL8ri:
			case X86_RCR8ri:
			case X86_ROR8ri:
			case X86_SAL8ri:
			case X86_SAR8ri:
			case X86_SBB8ri:
			case X86_SHL8ri:
			case X86_SHR8ri:
			case X86_SUB8ri:
			case X86_SUB8ri8:
			case X86_TEST8ri:
			case X86_TEST8ri_NOREX:
			case X86_TEST8ri_alt:
			case X86_XOR8ri:
			case X86_XOR8ri8:
			case X86_OUT8ir:

			case X86_ADC8mi:
			case X86_ADD8mi:
			case X86_AND8mi:
			case X86_CMP8mi:
			case X86_LOCK_ADD8mi:
			case X86_LOCK_AND8mi:
			case X86_LOCK_OR8mi:
			case X86_LOCK_SUB8mi:
			case X86_LOCK_XOR8mi:
			case X86_MOV8mi:
			case X86_OR8mi:
			case X86_RCL8mi:
			case X86_RCR8mi:
			case X86_ROL8mi:
			case X86_ROR8mi:
			case X86_SAL8mi:
			case X86_SAR8mi:
			case X86_SBB8mi:
			case X86_SHL8mi:
			case X86_SHR8mi:
			case X86_SUB8mi:
			case X86_TEST8mi:
			case X86_TEST8mi_alt:
			case X86_XOR8mi:
			case X86_PUSH64i8:
			case X86_CMP32ri8:
			case X86_CMP64ri8:

				imm = imm & 0xff;
				opsize = 1;     // immediate of 1 byte
				break;
		}

		switch(MI->flat_insn->id) {
			default:
				if (imm >= 0) {
					if (imm > HEX_THRESHOLD)
						SStream_concat(O, "$0x%"PRIx64, imm);
					else
						SStream_concat(O, "$%"PRIu64, imm);
				} else {
					if (imm < -HEX_THRESHOLD)
						SStream_concat(O, "$-0x%"PRIx64, -imm);
					else
						SStream_concat(O, "$-%"PRIu64, -imm);
				}
				break;

			case X86_INS_INT:
				// do not print number in negative form
				imm = imm & 0xff;
				if (imm >= 0 && imm <= HEX_THRESHOLD)
					SStream_concat(O, "$%u", imm);
				else {
					SStream_concat(O, "$0x%x", imm);
				}
				break;

			case X86_INS_LCALL:
			case X86_INS_LJMP:
				// always print address in positive form
				if (OpNo == 1) { // selector is ptr16
					imm = imm & 0xffff;
					opsize = 2;
				}
				SStream_concat(O, "$0x%"PRIx64, imm);
				break;

			case X86_INS_AND:
			case X86_INS_OR:
			case X86_INS_XOR:
				// do not print number in negative form
				if (imm >= 0 && imm <= HEX_THRESHOLD)
					SStream_concat(O, "$%u", imm);
				else {
					imm = arch_masks[MI->op1_size? MI->op1_size : MI->imm_size] & imm;
					SStream_concat(O, "$0x%"PRIx64, imm);
				}
				break;

			case X86_INS_RET:
				// RET imm16
				if (imm >= 0 && imm <= HEX_THRESHOLD)
					SStream_concat(O, "$%u", imm);
				else {
					imm = 0xffff & imm;
					SStream_concat(O, "$0x%x", imm);
				}
				break;
		}

		if (MI->csh->detail) {
			if (MI->csh->doing_mem) {
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = imm;
			} else {
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM;
				MI->has_imm = true;
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].imm = imm;

				if (opsize > 0)
					MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = opsize;
				else if (MI->op1_size > 0)
					MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->op1_size;
				else
					MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->imm_size;

				MI->flat_insn->detail->x86.op_count++;
			}
		}
	}
}
Beispiel #7
0
static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
{
	MCOperand *Op  = MCInst_getOperand(MI, OpNo);
	if (MCOperand_isReg(Op)) {
		unsigned int reg = MCOperand_getReg(Op);
		printRegName(O, reg);
		if (MI->csh->detail) {
			if (MI->csh->doing_mem) {
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = reg;
			} else {
				uint8_t access[6];

				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_REG;
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].reg = reg;
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->csh->regsize_map[reg];

				get_op_access(MI->csh, MCInst_getOpcode(MI), access, &MI->flat_insn->detail->x86.eflags);
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].access = access[MI->flat_insn->detail->x86.op_count];

				MI->flat_insn->detail->x86.op_count++;
			}
		}
	} else if (MCOperand_isImm(Op)) {
		// Print X86 immediates as signed values.
		uint8_t encsize;
		int64_t imm = MCOperand_getImm(Op);
		uint8_t opsize = X86_immediate_size(MCInst_getOpcode(MI), &encsize);

		if (opsize == 1)    // print 1 byte immediate in positive form
			imm = imm & 0xff;

		switch(MI->flat_insn->id) {
			default:
				if (imm >= 0) {
					if (imm > HEX_THRESHOLD)
						SStream_concat(O, "$0x%"PRIx64, imm);
					else
						SStream_concat(O, "$%"PRIu64, imm);
				} else {
					if (MI->csh->imm_unsigned) {
						if (opsize) {
							switch(opsize) {
								default:
									break;
								case 1:
									imm &= 0xff;
									break;
								case 2:
									imm &= 0xffff;
									break;
								case 4:
									imm &= 0xffffffff;
									break;
							}
						}

						SStream_concat(O, "$0x%"PRIx64, imm);
					} else {
						if (imm == 0x8000000000000000LL)  // imm == -imm
							SStream_concat0(O, "$0x8000000000000000");
						else if (imm < -HEX_THRESHOLD)
							SStream_concat(O, "$-0x%"PRIx64, -imm);
						else
							SStream_concat(O, "$-%"PRIu64, -imm);
					}
				}
				break;

			case X86_INS_MOVABS:
				// do not print number in negative form
				SStream_concat(O, "$0x%"PRIx64, imm);
				break;

			case X86_INS_IN:
			case X86_INS_OUT:
			case X86_INS_INT:
				// do not print number in negative form
				imm = imm & 0xff;
				if (imm >= 0 && imm <= HEX_THRESHOLD)
					SStream_concat(O, "$%u", imm);
				else {
					SStream_concat(O, "$0x%x", imm);
				}
				break;

			case X86_INS_LCALL:
			case X86_INS_LJMP:
				// always print address in positive form
				if (OpNo == 1) {	// selector is ptr16
					imm = imm & 0xffff;
					opsize = 2;
				}
				SStream_concat(O, "$0x%"PRIx64, imm);
				break;

			case X86_INS_AND:
			case X86_INS_OR:
			case X86_INS_XOR:
				// do not print number in negative form
				if (imm >= 0 && imm <= HEX_THRESHOLD)
					SStream_concat(O, "$%u", imm);
				else {
					imm = arch_masks[opsize? opsize : MI->imm_size] & imm;
					SStream_concat(O, "$0x%"PRIx64, imm);
				}
				break;

			case X86_INS_RET:
			case X86_INS_RETF:
				// RET imm16
				if (imm >= 0 && imm <= HEX_THRESHOLD)
					SStream_concat(O, "$%u", imm);
				else {
					imm = 0xffff & imm;
					SStream_concat(O, "$0x%x", imm);
				}
				break;
		}

		if (MI->csh->detail) {
			if (MI->csh->doing_mem) {
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = imm;
			} else {
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM;
				MI->has_imm = true;
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].imm = imm;

				if (opsize > 0) {
					MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = opsize;
					MI->flat_insn->detail->x86.encoding.imm_size = encsize;
				} else if (MI->op1_size > 0)
					MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->op1_size;
				else
					MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->imm_size;

				MI->flat_insn->detail->x86.op_count++;
			}
		}
	}
}
static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
{
	MCOperand *Op  = MCInst_getOperand(MI, OpNo);
	if (MCOperand_isReg(Op)) {
		unsigned int reg = MCOperand_getReg(Op);

		printRegName(O, reg);
		if (MI->csh->detail) {
			if (MI->csh->doing_mem) {
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = reg;
			} else {
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_REG;
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].reg = reg;
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->csh->regsize_map[reg];
				MI->flat_insn->detail->x86.op_count++;
			}
		}

		if (MI->op1_size == 0)
			MI->op1_size = MI->csh->regsize_map[reg];
	} else if (MCOperand_isImm(Op)) {
		int64_t imm = MCOperand_getImm(Op);

		switch(MI->flat_insn->id) {
			default:
				if (imm >= 0) {
					if (imm > HEX_THRESHOLD)
						SStream_concat(O, "0x%"PRIx64, imm);
					else
						SStream_concat(O, "%"PRIu64, imm);
				} else {
					if (imm < -HEX_THRESHOLD)
						SStream_concat(O, "-0x%"PRIx64, -imm);
					else
						SStream_concat(O, "-%"PRIu64, -imm);
				}

				break;

			case X86_INS_AND:
			case X86_INS_OR:
			case X86_INS_XOR:
				// do not print number in negative form
				if (imm >= 0 && imm <= HEX_THRESHOLD)
					SStream_concat(O, "%u", imm);
				else
					SStream_concat(O, "0x%"PRIx64, arch_masks[MI->op1_size? MI->op1_size : MI->imm_size] & imm);
				break;
			case X86_INS_RET:
				// RET imm16
				if (imm >= 0 && imm <= HEX_THRESHOLD)
					SStream_concat(O, "%u", imm);
				else {
					imm = 0xffff & imm;
					SStream_concat(O, "0x%x", 0xffff & imm);
				}
				break;
		}

		if (MI->csh->detail) {
			if (MI->csh->doing_mem) {
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = imm;
			} else {
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM;
				if (MI->flat_insn->detail->x86.op_count > 0)
					MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->flat_insn->detail->x86.operands[0].size;
				else
					MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->imm_size;
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].imm = imm;
				MI->flat_insn->detail->x86.op_count++;
			}
		}

		//if (MI->op1_size == 0)
		//	MI->op1_size = MI->imm_size;
	}
}
static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
{
	MCOperand *Op  = MCInst_getOperand(MI, OpNo);

	if (MCOperand_isReg(Op)) {
		unsigned int reg = MCOperand_getReg(Op);

		printRegName(O, reg);
		if (MI->csh->detail) {
			if (MI->csh->doing_mem) {
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = reg;
			} else {
#ifndef CAPSTONE_DIET
				uint8_t access[6];
#endif

				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_REG;
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].reg = reg;
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->csh->regsize_map[reg];

#ifndef CAPSTONE_DIET
				get_op_access(MI->csh, MCInst_getOpcode(MI), access, &MI->flat_insn->detail->x86.eflags);
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].access = access[MI->flat_insn->detail->x86.op_count];
#endif

				MI->flat_insn->detail->x86.op_count++;
			}
		}

		if (MI->op1_size == 0)
			MI->op1_size = MI->csh->regsize_map[reg];
	} else if (MCOperand_isImm(Op)) {
		int64_t imm = MCOperand_getImm(Op);
		int opsize = X86_immediate_size(MCInst_getOpcode(MI));
		if (opsize == 1)    // print 1 byte immediate in positive form
			imm = imm & 0xff;

		switch(MI->flat_insn->id) {
			default:
				printImm(MI->csh->syntax, O, imm, false);
				break;

			case X86_INS_INT:
				// do not print number in negative form
				imm = imm & 0xff;
				printImm(MI->csh->syntax, O, imm, true);
				break;

			case X86_INS_LCALL:
			case X86_INS_LJMP:
				// always print address in positive form
				if (OpNo == 1) {	// ptr16 part
					imm = imm & 0xffff;
					opsize = 2;
				}
				printImm(MI->csh->syntax, O, imm, true);
				break;

			case X86_INS_AND:
			case X86_INS_OR:
			case X86_INS_XOR:
				// do not print number in negative form
				if (imm >= 0 && imm <= HEX_THRESHOLD)
					printImm(MI->csh->syntax, O, imm, true);
				else {
					imm = arch_masks[opsize? opsize : MI->imm_size] & imm;
					printImm(MI->csh->syntax, O, imm, true);
				}
				break;

			case X86_INS_RET:
				// RET imm16
				if (imm >= 0 && imm <= HEX_THRESHOLD)
					printImm(MI->csh->syntax, O, imm, true);
				else {
					imm = 0xffff & imm;
					printImm(MI->csh->syntax, O, imm, true);
				}
				break;
		}

		if (MI->csh->detail) {
			if (MI->csh->doing_mem) {
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = imm;
			} else {
#ifndef CAPSTONE_DIET
				uint8_t access[6];
#endif

				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM;
				if (opsize > 0)
					MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = opsize;
				else if (MI->flat_insn->detail->x86.op_count > 0) {
					if (MI->flat_insn->id != X86_INS_LCALL && MI->flat_insn->id != X86_INS_LJMP) {
						MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size =
							MI->flat_insn->detail->x86.operands[0].size;
					} else
						MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->imm_size;
				} else
					MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->imm_size;
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].imm = imm;

#ifndef CAPSTONE_DIET
				get_op_access(MI->csh, MCInst_getOpcode(MI), access, &MI->flat_insn->detail->x86.eflags);
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].access = access[MI->flat_insn->detail->x86.op_count];
#endif

				MI->flat_insn->detail->x86.op_count++;
			}
		}
	}
}
static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
{
	int opsize = 0;
	MCOperand *Op  = MCInst_getOperand(MI, OpNo);

	if (MCOperand_isReg(Op)) {
		unsigned int reg = MCOperand_getReg(Op);

		printRegName(O, reg);
		if (MI->csh->detail) {
			if (MI->csh->doing_mem) {
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = reg;
			} else {
#ifndef CAPSTONE_DIET
				uint8_t access[6];
#endif

				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_REG;
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].reg = reg;
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->csh->regsize_map[reg];

#ifndef CAPSTONE_DIET
				get_op_access(MI->csh, MCInst_getOpcode(MI), access, &MI->flat_insn->detail->x86.eflags);
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].access = access[MI->flat_insn->detail->x86.op_count];
#endif

				MI->flat_insn->detail->x86.op_count++;
			}
		}

		if (MI->op1_size == 0)
			MI->op1_size = MI->csh->regsize_map[reg];
	} else if (MCOperand_isImm(Op)) {
		int64_t imm = MCOperand_getImm(Op);

		switch(MCInst_getOpcode(MI)) {
			default:
				break;

			case X86_AAD8i8:
			case X86_AAM8i8:
			case X86_ADC8i8:
			case X86_ADD8i8:
			case X86_AND8i8:
			case X86_CMP8i8:
			case X86_OR8i8:
			case X86_SBB8i8:
			case X86_SUB8i8:
			case X86_TEST8i8:
			case X86_XOR8i8:
			case X86_ROL8ri:
			case X86_ADC8ri:
			case X86_ADC8ri8:
			case X86_ADD8ri:
			case X86_ADD8ri8:
			case X86_AND8ri:
			case X86_AND8ri8:
			case X86_CMP8ri:
			case X86_CMP8ri8:
			case X86_IN8ri:
			case X86_MOV8ri:
			case X86_MOV8ri_alt:
			case X86_OR8ri:
			case X86_OR8ri8:
			case X86_RCL8ri:
			case X86_RCR8ri:
			case X86_ROR8ri:
			case X86_SAL8ri:
			case X86_SAR8ri:
			case X86_SBB8ri:
			case X86_SBB8ri8:
			case X86_SHL8ri:
			case X86_SHR8ri:
			case X86_SUB8ri:
			case X86_SUB8ri8:
			case X86_TEST8ri:
			case X86_TEST8ri_NOREX:
			case X86_TEST8ri_alt:
			case X86_XOR8ri:
			case X86_XOR8ri8:
			case X86_OUT8ir:

			case X86_ADC8mi:
			case X86_ADC8mi8:
			case X86_ADD8mi:
			case X86_ADD8mi8:
			case X86_AND8mi:
			case X86_AND8mi8:
			case X86_CMP8mi:
			case X86_CMP8mi8:
			case X86_LOCK_ADD8mi:
			case X86_LOCK_AND8mi:
			case X86_LOCK_OR8mi:
			case X86_LOCK_SUB8mi:
			case X86_LOCK_XOR8mi:
			case X86_MOV8mi:
			case X86_OR8mi:
			case X86_OR8mi8:
			case X86_RCL8mi:
			case X86_RCR8mi:
			case X86_ROL8mi:
			case X86_ROR8mi:
			case X86_SAL8mi:
			case X86_SAR8mi:
			case X86_SBB8mi:
			case X86_SBB8mi8:
			case X86_SHL8mi:
			case X86_SHR8mi:
			case X86_SUB8mi:
			case X86_SUB8mi8:
			case X86_TEST8mi:
			case X86_TEST8mi_alt:
			case X86_XOR8mi:
			case X86_XOR8mi8:
			case X86_PUSH64i8:
			case X86_CMP32ri8:
			case X86_CMP64ri8:

				imm = imm & 0xff;
				opsize = 1;	// immediate of 1 byte
				break;
		}

		switch(MI->flat_insn->id) {
			default:
				if (imm >= 0) {
					if (imm > HEX_THRESHOLD)
						SStream_concat(O, "0x%"PRIx64, imm);
					else
						SStream_concat(O, "%"PRIu64, imm);
				} else {
					if (imm < -HEX_THRESHOLD)
						SStream_concat(O, "-0x%"PRIx64, -imm);
					else
						SStream_concat(O, "-%"PRIu64, -imm);
				}

				break;

			case X86_INS_INT:
				// do not print number in negative form
				if (imm >= 0 && imm <= HEX_THRESHOLD)
					SStream_concat(O, "%u", imm);
				else
					SStream_concat(O, "0x%x", imm & 0xff);
				break;

			case X86_INS_AND:
			case X86_INS_OR:
			case X86_INS_XOR:
				// do not print number in negative form
				if (imm >= 0 && imm <= HEX_THRESHOLD)
					SStream_concat(O, "%u", imm);
				else
					SStream_concat(O, "0x%"PRIx64, arch_masks[MI->op1_size? MI->op1_size : MI->imm_size] & imm);
				break;

			case X86_INS_RET:
				// RET imm16
				if (imm >= 0 && imm <= HEX_THRESHOLD)
					SStream_concat(O, "%u", imm);
				else {
					imm = 0xffff & imm;
					SStream_concat(O, "0x%x", 0xffff & imm);
				}
				break;
		}

		if (MI->csh->detail) {
			if (MI->csh->doing_mem) {
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = imm;
			} else {
#ifndef CAPSTONE_DIET
				uint8_t access[6];
#endif

				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM;
				if (opsize > 0)
					MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = opsize;
				else if (MI->flat_insn->detail->x86.op_count > 0)
					MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->flat_insn->detail->x86.operands[0].size;
				else
					MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->imm_size;
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].imm = imm;

#ifndef CAPSTONE_DIET
				get_op_access(MI->csh, MCInst_getOpcode(MI), access, &MI->flat_insn->detail->x86.eflags);
				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].access = access[MI->flat_insn->detail->x86.op_count];
#endif

				MI->flat_insn->detail->x86.op_count++;
			}
		}

		//if (MI->op1_size == 0)
		//	MI->op1_size = MI->imm_size;
	}
}
Beispiel #11
0
static void printOperand(MCInst *MI, SStream *O, m680x_info *info,
	cs_m680x_op *op)
{
	switch (op->type) {
	case M680X_OP_REGISTER:
		printRegName(MI->csh, O, op->reg);
		break;

	case M680X_OP_CONSTANT:
		SStream_concat(O, "%u", op->const_val);
		break;

	case M680X_OP_IMMEDIATE:
		if (MI->csh->imm_unsigned)
			SStream_concat(O, "#%u",
				get_unsigned(op->imm, op->size));
		else
			SStream_concat(O, "#%d", op->imm);

		break;

	case M680X_OP_INDEXED:
		if (op->idx.flags & M680X_IDX_INDIRECT)
			SStream_concat(O, "[");

		if (op->idx.offset_reg != M680X_REG_INVALID)
			printRegName(MI->csh, O, op->idx.offset_reg);
		else if (op->idx.offset_bits > 0) {
			if (op->idx.base_reg == M680X_REG_PC)
				SStream_concat(O, "$%04x", op->idx.offset_addr);
			else
				SStream_concat(O, "%d", op->idx.offset);
		}
		else if (op->idx.inc_dec != 0 &&
			info->cpu_type == M680X_CPU_TYPE_CPU12)
			SStream_concat(O, "%d", abs(op->idx.inc_dec));

		if (!(op->idx.flags & M680X_IDX_NO_COMMA))
			SStream_concat(O, ", ");

		printIncDec(false, O, info, op);

		printRegName(MI->csh, O, op->idx.base_reg);

		if (op->idx.base_reg == M680X_REG_PC &&
			(op->idx.offset_bits > 0))
			SStream_concat(O, "r");

		printIncDec(true, O, info, op);

		if (op->idx.flags & M680X_IDX_INDIRECT)
			SStream_concat(O, "]");

		break;

	case M680X_OP_RELATIVE:
		SStream_concat(O, "$%04x", op->rel.address);
		break;

	case M680X_OP_DIRECT:
		SStream_concat(O, "$%02x", op->direct_addr);
		break;

	case M680X_OP_EXTENDED:
		if (op->ext.indirect)
			SStream_concat(O, "[$%04x]", op->ext.address);
		else {
			if (op->ext.address < 256) {
				SStream_concat(O, ">$%04x", op->ext.address);
			}
			else {
				SStream_concat(O, "$%04x", op->ext.address);
			}
		}

		break;

	default:
		SStream_concat(O, "<invalid_operand>");
		break;
	}
}