Skip to content

Commit

Permalink
Optimize tests and fix imm in map & null deref due invalid pointer.
Browse files Browse the repository at this point in the history
  • Loading branch information
wargio committed Sep 3, 2024
1 parent 0953b79 commit a52c901
Show file tree
Hide file tree
Showing 116 changed files with 115,644 additions and 644 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ cstool/cstool
android-ndk-*

# python virtual env
.venv/
.ven*/

# Auto-sync files
suite/auto-sync/src/autosync.egg-info
Expand Down
17 changes: 9 additions & 8 deletions arch/Mips/MipsDisassembler.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,11 @@ bool Mips_getFeatureBits(unsigned int mode, unsigned int feature)
case Mips_FeatureFP64Bit:
return mode & (CS_MODE_MIPS32R6 | CS_MODE_MIPS3 |
CS_MODE_MIPS4 | CS_MODE_MIPS5 |
CS_MODE_MIPS64 | CS_MODE_MIPS64R2 |
CS_MODE_MIPS64R3 | CS_MODE_MIPS64R5 |
CS_MODE_MIPS64R6 | CS_MODE_OCTEON |
CS_MODE_OCTEONP);
CS_MODE_MIPS32R2 | CS_MODE_MIPS32R3 |
CS_MODE_MIPS32R5 | CS_MODE_MIPS64 |
CS_MODE_MIPS64R2 | CS_MODE_MIPS64R3 |
CS_MODE_MIPS64R5 | CS_MODE_MIPS64R6 |
CS_MODE_OCTEON | CS_MODE_OCTEONP);
case Mips_FeatureNaN2008:
return mode & (CS_MODE_MIPS32R6 | CS_MODE_MIPS64R6);
case Mips_FeatureAbs2008:
Expand Down Expand Up @@ -835,8 +836,8 @@ static DecodeStatus DecodeDAHIDATIMMR6(MCInst *MI, uint32_t insn,
{
uint32_t Rs = fieldFromInstruction_4(insn, 16, 5);
uint32_t Imm = fieldFromInstruction_4(insn, 0, 16);
MCOperand_CreateReg0(MI, (getReg(Decoder, Mips_GPR64RegClassID, Rs)));
MCOperand_CreateReg0(MI, (getReg(Decoder, Mips_GPR64RegClassID, Rs)));
MCOperand_CreateReg0(MI, (getReg(MI, Mips_GPR64RegClassID, Rs)));
MCOperand_CreateReg0(MI, (getReg(MI, Mips_GPR64RegClassID, Rs)));
MCOperand_CreateImm0(MI, (Imm));
return MCDisassembler_Success;
Expand All @@ -848,8 +849,8 @@ static DecodeStatus DecodeDAHIDATI(MCInst *MI, uint32_t insn, uint64_t Address,
{
uint32_t Rs = fieldFromInstruction_4(insn, 21, 5);
uint32_t Imm = fieldFromInstruction_4(insn, 0, 16);
MCOperand_CreateReg0(MI, (getReg(Decoder, Mips_GPR64RegClassID, Rs)));
MCOperand_CreateReg0(MI, (getReg(Decoder, Mips_GPR64RegClassID, Rs)));
MCOperand_CreateReg0(MI, (getReg(MI, Mips_GPR64RegClassID, Rs)));
MCOperand_CreateReg0(MI, (getReg(MI, Mips_GPR64RegClassID, Rs)));
MCOperand_CreateImm0(MI, (Imm));

return MCDisassembler_Success;
Expand Down
246 changes: 123 additions & 123 deletions arch/Mips/MipsGenCSMappingInsnOp.inc

Large diffs are not rendered by default.

21 changes: 19 additions & 2 deletions arch/Mips/MipsInstPrinter.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ static const char *MipsFCCToString(Mips_CondCode CC)
return "ngt";
}
assert(0 && "Impossible condition code!");
return "";
}

const char *Mips_LLVM_getRegisterName(unsigned RegNo, bool noRegName);
Expand All @@ -121,8 +122,24 @@ static void printRegName(MCInst *MI, SStream *OS, MCRegister Reg)
}

void Mips_LLVM_printInst(MCInst *MI, uint64_t Address, SStream *O) {
if (!printAliasInstr(MI, Address, O) && !printAlias4(MI, Address, O))
bool useAliasDetails = map_use_alias_details(MI);
if (!useAliasDetails) {
SStream_Close(O);
printInstruction(MI, Address, O);
SStream_Open(O);
map_set_fill_detail_ops(MI, false);
}

if (printAliasInstr(MI, Address, O) ||
printAlias4(MI, Address, O)) {
MCInst_setIsAlias(MI, true);
} else {
printInstruction(MI, Address, O);
}

if (!useAliasDetails) {
map_set_fill_detail_ops(MI, true);
}
}

void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
Expand Down Expand Up @@ -520,7 +537,7 @@ static void printPCRel(MCInst *MI, uint64_t Address, int OpNum, SStream *O)

const char *Mips_LLVM_getRegisterName(unsigned RegNo, bool noRegName)
{
if (RegNo >= MIPS_REG_ENDING) {
if (!RegNo || RegNo >= MIPS_REG_ENDING) {
return NULL;
}
if (noRegName) {
Expand Down
103 changes: 58 additions & 45 deletions arch/Mips/MipsMapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ bool Mips_getInstruction(csh handle, const uint8_t *code, size_t code_len,
uint64_t size64;
Mips_init_cs_detail(instr);
instr->MRI = (MCRegisterInfo *)info;
map_set_fill_detail_ops(instr, true);

bool result = Mips_LLVM_getInstruction(instr, &size64, code,
code_len, address, info)
Expand Down Expand Up @@ -250,33 +251,49 @@ static void Mips_set_detail_op_imm(MCInst *MI, unsigned OpNum, int64_t Imm)
Mips_inc_op_count(MI);
}

static void Mips_set_detail_op_reg(MCInst *MI, unsigned OpNum, mips_reg Reg)
static void Mips_set_detail_op_uimm(MCInst *MI, unsigned OpNum, uint64_t Imm)
{
if (!detail_is_set(MI))
return;

if (doing_mem(MI)) {
Mips_set_detail_op_mem_reg(MI, OpNum, Reg);
Mips_set_detail_op_mem_disp(MI, OpNum, Imm);
return;
}

assert((map_get_op_type(MI, OpNum) & ~CS_OP_MEM) == CS_OP_REG);
Mips_get_detail_op(MI, 0)->type = MIPS_OP_IMM;
Mips_get_detail_op(MI, 0)->imm = (int64_t)Imm;
Mips_get_detail_op(MI, 0)->is_unsigned = true;
Mips_get_detail_op(MI, 0)->access = map_get_op_access(MI, OpNum);
Mips_inc_op_count(MI);
}

static void Mips_set_detail_op_reg(MCInst *MI, unsigned OpNum, mips_reg Reg, bool is_reglist)
{
if (!detail_is_set(MI))
return;

if (doing_mem(MI)) {
Mips_set_detail_op_mem_reg(MI, OpNum, Reg);
return;
}

CS_ASSERT((map_get_op_type(MI, OpNum) & ~CS_OP_MEM) == CS_OP_REG);
Mips_get_detail_op(MI, 0)->type = MIPS_OP_REG;
Mips_get_detail_op(MI, 0)->reg = Reg;
Mips_get_detail_op(MI, 0)->is_reglist = is_reglist;
Mips_get_detail_op(MI, 0)->access = map_get_op_access(MI, OpNum);
Mips_inc_op_count(MI);
}

static void Mips_set_detail_op_operand(MCInst *MI, unsigned OpNum)
{
cs_op_type op_type = map_get_op_type(MI, OpNum) & ~CS_OP_MEM;
int64_t value = MCInst_getOpVal(MI, OpNum);
if (op_type == CS_OP_IMM) {
Mips_set_detail_op_imm(MI, OpNum,
MCInst_getOpVal(MI, OpNum));
Mips_set_detail_op_imm(MI, OpNum, value);
} else if (op_type == CS_OP_REG) {
Mips_set_detail_op_reg(MI, OpNum,
MCInst_getOpVal(MI, OpNum));
Mips_set_detail_op_reg(MI, OpNum, value, false);
} else
printf("Operand type %d not handled!\n", op_type);
}
Expand All @@ -286,34 +303,33 @@ static void Mips_set_detail_op_branch(MCInst *MI, unsigned OpNum)
cs_op_type op_type = map_get_op_type(MI, OpNum) & ~CS_OP_MEM;
if (op_type == CS_OP_IMM) {
uint64_t Target = (uint64_t)MCInst_getOpVal(MI, OpNum);
Mips_set_detail_op_imm(MI, OpNum, Target + MI->address);
Mips_set_detail_op_uimm(MI, OpNum, Target + MI->address);
} else if (op_type == CS_OP_REG) {
Mips_set_detail_op_reg(MI, OpNum,
MCInst_getOpVal(MI, OpNum));
MCInst_getOpVal(MI, OpNum), false);
} else
printf("Operand type %d not handled!\n", op_type);
}

static void Mips_set_detail_op_uimm(MCInst *MI, unsigned OpNum)
static void Mips_set_detail_op_unsigned(MCInst *MI, unsigned OpNum)
{
Mips_set_detail_op_imm(MI, OpNum,
Mips_set_detail_op_uimm(MI, OpNum,
MCInst_getOpVal(MI, OpNum));
}

static void Mips_set_detail_op_uimm_offset(MCInst *MI, unsigned OpNum,
static void Mips_set_detail_op_unsigned_offset(MCInst *MI, unsigned OpNum,
unsigned Bits, uint64_t Offset)
{
uint64_t Imm = MCInst_getOpVal(MI, OpNum);
Imm -= Offset;
Imm &= (1 << Bits) - 1;
Imm += Offset;
Mips_set_detail_op_imm(MI, OpNum, Imm);
Mips_set_detail_op_uimm(MI, OpNum, Imm);
}

static void Mips_set_detail_op_mem_nanomips(MCInst *MI, unsigned OpNum)
{
if (!detail_is_set(MI) || !doing_mem(MI))
return;
CS_ASSERT(doing_mem(MI))

MCOperand *Op = MCInst_getOperand(MI, OpNum);
Mips_get_detail_op(MI, 0)->type = MIPS_OP_MEM;
Expand All @@ -324,31 +340,28 @@ static void Mips_set_detail_op_mem_nanomips(MCInst *MI, unsigned OpNum)

static void Mips_set_detail_op_reglist(MCInst *MI, unsigned OpNum, bool isNanoMips)
{
if (!detail_is_set(MI))
return;

if (isNanoMips) {
for (unsigned i = OpNum; i < MCInst_getNumOperands(MI); i++) {
Mips_set_detail_op_reg(MI, i, MCInst_getOpVal(MI, i));
Mips_set_detail_op_reg(MI, i, MCInst_getOpVal(MI, i), true);
}
return;
}
// -2 because register List is always first operand of instruction
// and it is always followed by memory operand (base + offset).
for (unsigned i = OpNum, e = MCInst_getNumOperands(MI) - 2; i != e; ++i) {
Mips_set_detail_op_reg(MI, i, MCInst_getOpVal(MI, i));
Mips_set_detail_op_reg(MI, i, MCInst_getOpVal(MI, i), true);
}
}

static void Mips_set_detail_op_uimm_address(MCInst *MI, unsigned OpNum)
static void Mips_set_detail_op_unsigned_address(MCInst *MI, unsigned OpNum)
{
uint64_t Target = MI->address + (uint64_t)MCInst_getOpVal(MI, OpNum);
Mips_set_detail_op_imm(MI, OpNum, Target);
}

void Mips_add_cs_detail(MCInst *MI, mips_op_group op_group, va_list args)
{
if (!detail_is_set(MI))
if (!detail_is_set(MI) || !map_fill_detail_ops(MI))
return;

unsigned OpNum = va_arg(args, unsigned);
Expand All @@ -367,57 +380,57 @@ void Mips_add_cs_detail(MCInst *MI, mips_op_group op_group, va_list args)
case Mips_OP_GROUP_Operand:
return Mips_set_detail_op_operand(MI, OpNum);
case Mips_OP_GROUP_UImm_1_0:
return Mips_set_detail_op_uimm_offset(MI, OpNum, 1, 0);
return Mips_set_detail_op_unsigned_offset(MI, OpNum, 1, 0);
case Mips_OP_GROUP_UImm_2_0:
return Mips_set_detail_op_uimm_offset(MI, OpNum, 2, 0);
return Mips_set_detail_op_unsigned_offset(MI, OpNum, 2, 0);
case Mips_OP_GROUP_UImm_3_0:
return Mips_set_detail_op_uimm_offset(MI, OpNum, 3, 0);
return Mips_set_detail_op_unsigned_offset(MI, OpNum, 3, 0);
case Mips_OP_GROUP_UImm_32_0:
return Mips_set_detail_op_uimm_offset(MI, OpNum, 32, 0);
return Mips_set_detail_op_unsigned_offset(MI, OpNum, 32, 0);
case Mips_OP_GROUP_UImm_16_0:
return Mips_set_detail_op_uimm_offset(MI, OpNum, 16, 0);
return Mips_set_detail_op_unsigned_offset(MI, OpNum, 16, 0);
case Mips_OP_GROUP_UImm_8_0:
return Mips_set_detail_op_uimm_offset(MI, OpNum, 8, 0);
return Mips_set_detail_op_unsigned_offset(MI, OpNum, 8, 0);
case Mips_OP_GROUP_UImm_5_0:
return Mips_set_detail_op_uimm_offset(MI, OpNum, 5, 0);
return Mips_set_detail_op_unsigned_offset(MI, OpNum, 5, 0);
case Mips_OP_GROUP_UImm_6_0:
return Mips_set_detail_op_uimm_offset(MI, OpNum, 6, 0);
return Mips_set_detail_op_unsigned_offset(MI, OpNum, 6, 0);
case Mips_OP_GROUP_UImm_4_0:
return Mips_set_detail_op_uimm_offset(MI, OpNum, 4, 0);
return Mips_set_detail_op_unsigned_offset(MI, OpNum, 4, 0);
case Mips_OP_GROUP_UImm_7_0:
return Mips_set_detail_op_uimm_offset(MI, OpNum, 7, 0);
return Mips_set_detail_op_unsigned_offset(MI, OpNum, 7, 0);
case Mips_OP_GROUP_UImm_10_0:
return Mips_set_detail_op_uimm_offset(MI, OpNum, 10, 0);
return Mips_set_detail_op_unsigned_offset(MI, OpNum, 10, 0);
case Mips_OP_GROUP_UImm_6_1:
return Mips_set_detail_op_uimm_offset(MI, OpNum, 6, 1);
return Mips_set_detail_op_unsigned_offset(MI, OpNum, 6, 1);
case Mips_OP_GROUP_UImm_5_1:
return Mips_set_detail_op_uimm_offset(MI, OpNum, 5, 1);
return Mips_set_detail_op_unsigned_offset(MI, OpNum, 5, 1);
case Mips_OP_GROUP_UImm_5_33:
return Mips_set_detail_op_uimm_offset(MI, OpNum, 5, 33);
return Mips_set_detail_op_unsigned_offset(MI, OpNum, 5, 33);
case Mips_OP_GROUP_UImm_5_32:
return Mips_set_detail_op_uimm_offset(MI, OpNum, 5, 32);
return Mips_set_detail_op_unsigned_offset(MI, OpNum, 5, 32);
case Mips_OP_GROUP_UImm_6_2:
return Mips_set_detail_op_uimm_offset(MI, OpNum, 6, 2);
return Mips_set_detail_op_unsigned_offset(MI, OpNum, 6, 2);
case Mips_OP_GROUP_UImm_2_1:
return Mips_set_detail_op_uimm_offset(MI, OpNum, 2, 1);
return Mips_set_detail_op_unsigned_offset(MI, OpNum, 2, 1);
case Mips_OP_GROUP_UImm_0_0:
return Mips_set_detail_op_uimm_offset(MI, OpNum, 0, 0);
return Mips_set_detail_op_unsigned_offset(MI, OpNum, 0, 0);
case Mips_OP_GROUP_UImm_26_0:
return Mips_set_detail_op_uimm_offset(MI, OpNum, 26, 0);
return Mips_set_detail_op_unsigned_offset(MI, OpNum, 26, 0);
case Mips_OP_GROUP_UImm_12_0:
return Mips_set_detail_op_uimm_offset(MI, OpNum, 12, 0);
return Mips_set_detail_op_unsigned_offset(MI, OpNum, 12, 0);
case Mips_OP_GROUP_UImm_20_0:
return Mips_set_detail_op_uimm_offset(MI, OpNum, 20, 0);
return Mips_set_detail_op_unsigned_offset(MI, OpNum, 20, 0);
case Mips_OP_GROUP_RegisterList:
return Mips_set_detail_op_reglist(MI, OpNum, false);
case Mips_OP_GROUP_NanoMipsRegisterList:
return Mips_set_detail_op_reglist(MI, OpNum, true);
case Mips_OP_GROUP_PCRel:
/* fall-thru */
case Mips_OP_GROUP_Hi20PCRel:
return Mips_set_detail_op_uimm_address(MI, OpNum);
return Mips_set_detail_op_unsigned_address(MI, OpNum);
case Mips_OP_GROUP_Hi20:
return Mips_set_detail_op_uimm(MI, OpNum);
return Mips_set_detail_op_unsigned(MI, OpNum);
}
}

Expand Down
5 changes: 3 additions & 2 deletions arch/Mips/MipsMapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "../../include/capstone/capstone.h"
#include "../../utils.h"
#include "../../Mapping.h"

typedef enum {
#include "MipsGenCSOpGroup.inc"
Expand Down Expand Up @@ -43,7 +44,7 @@ void Mips_add_cs_detail(MCInst *MI, mips_op_group op_group, va_list args);

static inline void add_cs_detail(MCInst *MI, mips_op_group op_group, ...)
{
if (!MI->flat_insn->detail)
if (!detail_is_set(MI))
return;
va_list args;
va_start(args, op_group);
Expand All @@ -53,7 +54,7 @@ static inline void add_cs_detail(MCInst *MI, mips_op_group op_group, ...)

static inline void set_mem_access(MCInst *MI, bool status)
{
if (!MI->flat_insn->detail)
if (!detail_is_set(MI))
return;
Mips_set_mem_access(MI, status);
}
Expand Down
Loading

0 comments on commit a52c901

Please sign in to comment.