From: Per M. <pe...@si...> - 2016-03-24 01:10:56
|
On 64-bit PPC a branch, like “bce TARGET” gets the target truncated to 32-bits. 00003fff76030028 bge 0x760300c0 # this is really branching to the ld instruction, below. ... 00003fff760300c0 ld r6, -8(r20) I think the cause is the (int) cast in the following procedure, in PPCInstPrinter.c: static void printAbsBranchOperand(MCInst *MI, unsigned OpNo, SStream *O) { int imm; if (!MCOperand_isImm(MCInst_getOperand(MI, OpNo))) { printOperand(MI, OpNo, O); return; } imm = ((int)MCOperand_getImm(MCInst_getOperand(MI, OpNo)) << 2); if (!PPC_abs_branch(MI->csh, MCInst_getOpcode(MI))) { imm = (int)MI->address + imm; } SStream_concat(O, "0x%x", imm); if (MI->csh->detail) { MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM; MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = imm; MI->flat_insn->detail->ppc.op_count++; } } If I change that procedure, as follows, I get the correct result: 00003fff87940028 bge 0x3fff87940060 ... 00003fff87940060 ld r6, -8(r20) # New version, using int64_t instead of int static void printAbsBranchOperand(MCInst *MI, unsigned OpNo, SStream *O) { int64_t imm; if (!MCOperand_isImm(MCInst_getOperand(MI, OpNo))) { printOperand(MI, OpNo, O); return; } imm = MCOperand_getImm(MCInst_getOperand(MI, OpNo)) << 2; if (!PPC_abs_branch(MI->csh, MCInst_getOpcode(MI))) { imm = MI->address + imm; } SStream_concat(O, "0x%"PRIx64, imm); if (MI->csh->detail) { MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM; MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = imm; MI->flat_insn->detail->ppc.op_count++; } } uname -a on this machine says: Linux ... 3.10.0-229.4.2.ael7b.ppc64le #1 SMP Fri Apr 24 15:23:58 EDT 2015 ppc64le ppc64le ppc64le GNU/Linux Capstone branch “next” at commit 16ae82e0fcd707466f27f4bf84afdbd13667e27d Regards, Per Mildner Per...@si... Swedish Institute of Computer Science |