Sparc conditional branches displacement fix

This commit is contained in:
NighterMan 2015-04-10 04:47:42 +02:00
parent bc96e36ea7
commit 27a22f8633
1 changed files with 31 additions and 5 deletions

View File

@ -160,7 +160,7 @@ static bool printSparcAliasInstr(MCInst *MI, SStream *O)
static void printOperand(MCInst *MI, int opNum, SStream *O) static void printOperand(MCInst *MI, int opNum, SStream *O)
{ {
int Imm; int Imm, len;
unsigned reg; unsigned reg;
MCOperand *MO = MCInst_getOperand(MI, opNum); MCOperand *MO = MCInst_getOperand(MI, opNum);
@ -189,11 +189,37 @@ static void printOperand(MCInst *MI, int opNum, SStream *O)
Imm = (int)MCOperand_getImm(MO); Imm = (int)MCOperand_getImm(MO);
// get absolute address for CALL/Bxx // get absolute address for CALL/Bxx
if (MI->Opcode == SP_CALL) if (MI->Opcode == SP_CALL) {
Imm = SignExtend32(Imm, 30);
Imm += (uint32_t)MI->address; Imm += (uint32_t)MI->address;
else if (MI->flat_insn->id == SPARC_INS_B) }
// pc + (disp30 * 4)
// 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->flat_insn->id) {
case SPARC_INS_B:
case SPARC_INS_FB:
len = 19;
if (MI->csh->detail)
len = (MI->flat_insn->detail->sparc.op_count)? 19 : 22;
Imm = SignExtend32(Imm, len);
Imm = (uint32_t)MI->address + Imm * 4; Imm = (uint32_t)MI->address + Imm * 4;
break;
case SPARC_INS_BRZ:
case SPARC_INS_BRNZ:
case SPARC_INS_BRLZ:
case SPARC_INS_BRLEZ:
case SPARC_INS_BRGEZ:
case SPARC_INS_BRGZ:
Imm = SignExtend32(Imm, 16);
Imm = (uint32_t)MI->address + Imm * 4;
break;
}
if (Imm >= 0) { if (Imm >= 0) {
if (Imm > HEX_THRESHOLD) if (Imm > HEX_THRESHOLD)