Skip to content

Commit 3aa1511

Browse files
authored
Find writeback registers (capstone-engine#2960)
Detection of writebacks was only partially implemented: - MCInst_handleWriteback() was not called, so tied_op_idx was not filled - map_get_op_access() in RISCV_add_cs_detail_0() queried tied_op_idx unnecessarily, because all elements were -1 (initialization value)
1 parent d035490 commit 3aa1511

4 files changed

Lines changed: 7 additions & 28 deletions

File tree

arch/RISCV/RISCVDisassembler.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,11 @@ bool RISCV_LLVM_getInstruction(csh handle, const uint8_t *Bytes, size_t ByteLen,
748748
{
749749
RISCV_init_cs_detail(MI);
750750
MI->MRI = (MCRegisterInfo *)Info;
751-
return RISCV_getInstruction(MI, Size, Bytes, ByteLen, Address, NULL) !=
752-
MCDisassembler_Fail;
751+
DecodeStatus ret =
752+
RISCV_getInstruction(MI, Size, Bytes, ByteLen, Address, NULL);
753+
754+
MCInst_handleWriteback(MI, RISCVDescs.Insts,
755+
ARR_SIZE(RISCVDescs.Insts));
756+
757+
return ret != MCDisassembler_Fail;
753758
}

arch/RISCV/RISCVInstPrinter.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,6 @@ void RISCV_LLVM_printInstruction(MCInst *MI, SStream *O,
424424
printInstruction(McInstr, MI->address, O);
425425
}
426426
RISCV_add_groups(MI);
427-
RISCV_add_missing_write_access(MI);
428427
RISCV_compact_operands(MI);
429428
RISCV_set_alias_id(MI, O);
430429
}

arch/RISCV/RISCVMapping.c

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -297,29 +297,6 @@ void RISCV_compact_operands(MCInst *MI)
297297
(NUM_RISCV_OPS - write_pos) * sizeof(cs_riscv_op));
298298
}
299299

300-
// some RISC-V instructions have only 2 apparent operands, one of them is read-write
301-
// the actual operand information for those instruction should have 3 operands, the first and second are the same operand,
302-
// but once with read and once write access
303-
// when those instructions are disassembled only the operand entry with the read access is used,
304-
// and therefore the read-write operand is wrongly classified as only-read
305-
// this logic tries to correct that
306-
void RISCV_add_missing_write_access(MCInst *MI)
307-
{
308-
if (!detail_is_set(MI))
309-
return;
310-
if (!isCompressed(MI))
311-
return;
312-
313-
cs_riscv *riscv_details = RISCV_get_detail(MI);
314-
cs_riscv_op *ops = riscv_details->operands;
315-
// make the detection condition as specific as possible
316-
// so it doesn't accidentally trigger for other cases
317-
if (riscv_details->op_count == 2 && ops[0].type == RISCV_OP_INVALID &&
318-
ops[1].type == RISCV_OP_REG && ops[1].access == CS_AC_READ) {
319-
ops[1].access |= CS_AC_WRITE;
320-
}
321-
}
322-
323300
// given internal insn id, return public instruction info
324301
void RISCV_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id)
325302
{

arch/RISCV/RISCVMapping.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ void RISCV_init_cs_detail(MCInst *MI);
3131

3232
void RISCV_compact_operands(MCInst *MI);
3333

34-
void RISCV_add_missing_write_access(MCInst *MI);
35-
3634
// map instruction name to instruction ID
3735
riscv_insn RISCV_map_insn(const char *name);
3836

0 commit comments

Comments
 (0)