Skip to content

Commit

Permalink
arm: some load/store instructions writeback without bang letter. bug …
Browse files Browse the repository at this point in the history
…reported by @jabba2989
  • Loading branch information
aquynh committed Jan 21, 2015
1 parent b238628 commit e19490e
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 4 deletions.
1 change: 1 addition & 0 deletions MCInst.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ void MCInst_Init(MCInst *inst)
inst->size = 0;
inst->has_imm = false;
inst->op1_size = 0;
inst->writeback = false;
}

void MCInst_clear(MCInst *inst)
Expand Down
1 change: 1 addition & 0 deletions MCInst.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ struct MCInst {
// This is copied from cs_x86 struct
uint8_t x86_prefix[4];
uint8_t imm_size; // immediate size for X86_OP_IMM operand
bool writeback; // writeback for ARM
};

void MCInst_Init(MCInst *inst);
Expand Down
1 change: 1 addition & 0 deletions arch/ARM/ARMDisassembler.c
Original file line number Diff line number Diff line change
Expand Up @@ -1772,6 +1772,7 @@ static DecodeStatus DecodeAddrMode3Instruction(MCInst *Inst, unsigned Insn,
}

if (writeback) { // Writeback
Inst->writeback = true;
if (P)
U |= ARMII_IndexModePre << 9;
else
Expand Down
107 changes: 103 additions & 4 deletions arch/ARM/ARMInstPrinter.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,104 @@ void ARM_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci)
return;

// check if this insn requests write-back
if (strrchr(insn_asm, '!') != NULL) {
if (mci->writeback || (strrchr(insn_asm, '!')) != NULL) {
insn->detail->arm.writeback = true;
} else if (MI->csh->mode & CS_MODE_THUMB) {
// handle some special instructions with writeback
switch(mci->Opcode) {
default:
break;
case ARM_t2LDC2L_PRE:
case ARM_t2LDC2_PRE:
case ARM_t2LDCL_PRE:
case ARM_t2LDC_PRE:

case ARM_t2LDRB_PRE:
case ARM_t2LDRD_PRE:
case ARM_t2LDRH_PRE:
case ARM_t2LDRSB_PRE:
case ARM_t2LDRSH_PRE:
case ARM_t2LDR_PRE:

case ARM_t2STC2L_PRE:
case ARM_t2STC2_PRE:
case ARM_t2STCL_PRE:
case ARM_t2STC_PRE:

case ARM_t2STRB_PRE:
case ARM_t2STRD_PRE:
case ARM_t2STRH_PRE:
case ARM_t2STR_PRE:

case ARM_t2LDC2L_POST:
case ARM_t2LDC2_POST:
case ARM_t2LDCL_POST:
case ARM_t2LDC_POST:

case ARM_t2LDRB_POST:
case ARM_t2LDRD_POST:
case ARM_t2LDRH_POST:
case ARM_t2LDRSB_POST:
case ARM_t2LDRSH_POST:
case ARM_t2LDR_POST:

case ARM_t2STC2L_POST:
case ARM_t2STC2_POST:
case ARM_t2STCL_POST:
case ARM_t2STC_POST:

case ARM_t2STRB_POST:
case ARM_t2STRD_POST:
case ARM_t2STRH_POST:
case ARM_t2STR_POST:
insn->detail->arm.writeback = true;
break;
}
} else { // ARM mode
// handle some special instructions with writeback
switch(mci->Opcode) {
default:
break;
case ARM_LDC2L_PRE:
case ARM_LDC2_PRE:
case ARM_LDCL_PRE:
case ARM_LDC_PRE:

case ARM_LDRD_PRE:
case ARM_LDRH_PRE:
case ARM_LDRSB_PRE:
case ARM_LDRSH_PRE:

case ARM_STC2L_PRE:
case ARM_STC2_PRE:
case ARM_STCL_PRE:
case ARM_STC_PRE:

case ARM_STRD_PRE:
case ARM_STRH_PRE:

case ARM_LDC2L_POST:
case ARM_LDC2_POST:
case ARM_LDCL_POST:
case ARM_LDC_POST:

case ARM_LDRBT_POST:
case ARM_LDRD_POST:
case ARM_LDRH_POST:
case ARM_LDRSB_POST:
case ARM_LDRSH_POST:

case ARM_STC2L_POST:
case ARM_STC2_POST:
case ARM_STCL_POST:
case ARM_STC_POST:

case ARM_STRBT_POST:
case ARM_STRD_POST:
case ARM_STRH_POST:
insn->detail->arm.writeback = true;
break;
}
}

// check if this insn requests update flags
Expand Down Expand Up @@ -536,8 +632,10 @@ void ARM_printInst(MCInst *MI, SStream *O, void *Info)
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = BaseReg;
MI->flat_insn->detail->arm.op_count++;
}
if (Writeback)
if (Writeback) {
MI->writeback = true;
SStream_concat0(O, "!");
}
SStream_concat0(O, ", ");
printRegisterList(MI, 3, O);
return;
Expand Down Expand Up @@ -1137,9 +1235,10 @@ static void printAddrMode7Operand(MCInst *MI, unsigned OpNum, SStream *O)
static void printAddrMode6OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O)
{
MCOperand *MO = MCInst_getOperand(MI, OpNum);
if (MCOperand_getReg(MO) == 0)
if (MCOperand_getReg(MO) == 0) {
MI->writeback = true;
SStream_concat0(O, "!");
else {
} else {
SStream_concat0(O, ", ");
printRegName(MI->csh, O, MCOperand_getReg(MO));
if (MI->csh->detail) {
Expand Down

0 comments on commit e19490e

Please sign in to comment.