Skip to content

Commit

Permalink
Check safety of incrementing t the next operand.
Browse files Browse the repository at this point in the history
  • Loading branch information
Rot127 committed Sep 6, 2024
1 parent f08d54f commit 930bebe
Show file tree
Hide file tree
Showing 15 changed files with 72 additions and 37 deletions.
16 changes: 16 additions & 0 deletions Mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,22 @@ DEFINE_get_arch_detail(loongarch, LoongArch);
DEFINE_get_arch_detail(riscv, RISCV);
DEFINE_get_arch_detail(systemz, SystemZ);

#define DEFINE_check_safe_inc(Arch, ARCH) \
static inline void Arch##_check_safe_inc() { \
CS_ASSERT(Arch##_get_detail(MI)->op_count + 1 < NUM_##ARCH##_OPS); \
}

DEFINE_check_safe_inc(ARM, ARM);
DEFINE_check_safe_inc(PPC, PPC);
DEFINE_check_safe_inc(TriCore, TRICORE);
DEFINE_check_safe_inc(AArch64, AARCH64);
DEFINE_check_safe_inc(Alpha, ALPHA);
DEFINE_check_safe_inc(HPPA, HPPA);
DEFINE_check_safe_inc(LoongArch, LOONGARCH);
DEFINE_check_safe_inc(RISCV, RISCV);
DEFINE_check_safe_inc(SystemZ, SYSTEMZ);
DEFINE_check_safe_inc(Mips, MIPS);

static inline bool detail_is_set(const MCInst *MI)
{
assert(MI && MI->flat_insn);
Expand Down
28 changes: 14 additions & 14 deletions arch/AArch64/AArch64Mapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -2475,7 +2475,7 @@ void AArch64_set_detail_op_reg(MCInst *MI, unsigned OpNum, aarch64_reg Reg)
{
if (!detail_is_set(MI))
return;
assert(AArch64_get_detail(MI)->op_count + 1 < MAX_AARCH64_OPS);
AArch64_check_safe_inc();

if (Reg == AARCH64_REG_ZA ||
(Reg >= AARCH64_REG_ZAB0 && Reg < AARCH64_REG_ZT0)) {
Expand Down Expand Up @@ -2522,7 +2522,7 @@ void AArch64_set_detail_op_imm(MCInst *MI, unsigned OpNum,
{
if (!detail_is_set(MI))
return;
assert(AArch64_get_detail(MI)->op_count + 1 < MAX_AARCH64_OPS);
AArch64_check_safe_inc();

if (AArch64_get_detail(MI)->is_doing_sme) {
assert(map_get_op_type(MI, OpNum) & CS_OP_BOUND);
Expand Down Expand Up @@ -2557,7 +2557,7 @@ void AArch64_set_detail_op_imm_range(MCInst *MI, unsigned OpNum,
{
if (!detail_is_set(MI))
return;
assert(AArch64_get_detail(MI)->op_count + 1 < MAX_AARCH64_OPS);
AArch64_check_safe_inc();

if (AArch64_get_detail(MI)->is_doing_sme) {
assert(map_get_op_type(MI, OpNum) & CS_OP_BOUND);
Expand Down Expand Up @@ -2590,7 +2590,7 @@ void AArch64_set_detail_op_mem(MCInst *MI, unsigned OpNum, uint64_t Val)
{
if (!detail_is_set(MI))
return;
assert(AArch64_get_detail(MI)->op_count + 1 < MAX_AARCH64_OPS);
AArch64_check_safe_inc();
assert(map_get_op_type(MI, OpNum) & CS_OP_MEM);

AArch64_set_mem_access(MI, true);
Expand Down Expand Up @@ -2676,7 +2676,7 @@ void AArch64_set_detail_op_float(MCInst *MI, unsigned OpNum, float Val)
{
if (!detail_is_set(MI))
return;
assert(AArch64_get_detail(MI)->op_count + 1 < MAX_AARCH64_OPS);
AArch64_check_safe_inc();

AArch64_get_detail_op(MI, 0)->type = AARCH64_OP_FP;
AArch64_get_detail_op(MI, 0)->fp = Val;
Expand All @@ -2691,7 +2691,7 @@ void AArch64_set_detail_op_sys(MCInst *MI, unsigned OpNum, aarch64_sysop sys_op,
{
if (!detail_is_set(MI))
return;
assert(AArch64_get_detail(MI)->op_count + 1 < MAX_AARCH64_OPS);
AArch64_check_safe_inc();

AArch64_get_detail_op(MI, 0)->type = type;
AArch64_get_detail_op(MI, 0)->sysop = sys_op;
Expand All @@ -2701,7 +2701,7 @@ void AArch64_set_detail_op_sys(MCInst *MI, unsigned OpNum, aarch64_sysop sys_op,
void AArch64_set_detail_op_pred(MCInst *MI, unsigned OpNum) {
if (!detail_is_set(MI))
return;
assert(AArch64_get_detail(MI)->op_count + 1 < MAX_AARCH64_OPS);
AArch64_check_safe_inc();

if (AArch64_get_detail_op(MI, 0)->type == AARCH64_OP_INVALID) {
setup_pred_operand(MI);
Expand Down Expand Up @@ -2729,7 +2729,7 @@ void AArch64_set_detail_op_sme(MCInst *MI, unsigned OpNum,
{
if (!detail_is_set(MI))
return;
assert(AArch64_get_detail(MI)->op_count + 1 < MAX_AARCH64_OPS);
AArch64_check_safe_inc();

AArch64_get_detail_op(MI, 0)->type = AARCH64_OP_SME;
switch (part) {
Expand Down Expand Up @@ -2807,9 +2807,9 @@ static void insert_op(MCInst *MI, unsigned index, cs_aarch64_op op)
return;
}

AArch64_check_safe_inc();
cs_aarch64_op *ops = AArch64_get_detail(MI)->operands;
int i = AArch64_get_detail(MI)->op_count;
assert(i < MAX_AARCH64_OPS);
if (index == -1) {
ops[i] = op;
AArch64_inc_op_count(MI);
Expand All @@ -2831,7 +2831,7 @@ void AArch64_insert_detail_op_float_at(MCInst *MI, unsigned index, double val,
if (!detail_is_set(MI))
return;

assert(AArch64_get_detail(MI)->op_count + 1 < MAX_AARCH64_OPS);
AArch64_check_safe_inc();

cs_aarch64_op op;
AArch64_setup_op(&op);
Expand All @@ -2851,7 +2851,7 @@ void AArch64_insert_detail_op_reg_at(MCInst *MI, unsigned index,
if (!detail_is_set(MI))
return;

assert(AArch64_get_detail(MI)->op_count + 1 < MAX_AARCH64_OPS);
AArch64_check_safe_inc();

cs_aarch64_op op;
AArch64_setup_op(&op);
Expand All @@ -2869,7 +2869,7 @@ void AArch64_insert_detail_op_imm_at(MCInst *MI, unsigned index, int64_t Imm)
{
if (!detail_is_set(MI))
return;
assert(AArch64_get_detail(MI)->op_count + 1 < MAX_AARCH64_OPS);
AArch64_check_safe_inc();

cs_aarch64_op op;
AArch64_setup_op(&op);
Expand All @@ -2885,7 +2885,7 @@ void AArch64_insert_detail_op_sys(MCInst *MI, unsigned index, aarch64_sysop sys_
{
if (!detail_is_set(MI))
return;
assert(AArch64_get_detail(MI)->op_count + 1 < MAX_AARCH64_OPS);
AArch64_check_safe_inc();

cs_aarch64_op op;
AArch64_setup_op(&op);
Expand All @@ -2899,7 +2899,7 @@ void AArch64_insert_detail_op_sme(MCInst *MI, unsigned index, aarch64_op_sme sme
{
if (!detail_is_set(MI))
return;
assert(AArch64_get_detail(MI)->op_count + 1 < MAX_AARCH64_OPS);
AArch64_check_safe_inc();

cs_aarch64_op op;
AArch64_setup_op(&op);
Expand Down
18 changes: 13 additions & 5 deletions arch/ARM/ARMMapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -935,6 +935,7 @@ static void ARM_set_mem_access(MCInst *MI, bool status)
#endif
} else {
// done, select the next operand slot
ARM_check_safe_inc();
ARM_inc_op_count(MI);
}
}
Expand Down Expand Up @@ -1160,6 +1161,7 @@ static void add_cs_detail_general(MCInst *MI, arm_op_group op_group,
unsigned Reg =
MCOperand_getReg(MCInst_getOperand(MI, i));

ARM_check_safe_inc();
ARM_get_detail_op(MI, 0)->type = ARM_OP_REG;
ARM_get_detail_op(MI, 0)->reg = Reg;
ARM_get_detail_op(MI, 0)->access = access;
Expand Down Expand Up @@ -1661,6 +1663,7 @@ static void add_cs_detail_general(MCInst *MI, arm_op_group op_group,
int32_t OffImm = MCInst_getOpVal(MI, OpNum);
if (OffImm == INT32_MIN)
OffImm = 0;
ARM_check_safe_inc();
ARM_get_detail_op(MI, 0)->type = ARM_OP_MEM;
ARM_get_detail_op(MI, 0)->mem.base = ARM_REG_PC;
ARM_get_detail_op(MI, 0)->mem.index = ARM_REG_INVALID;
Expand All @@ -1683,6 +1686,7 @@ static void add_cs_detail_general(MCInst *MI, arm_op_group op_group,
}
case ARM_OP_GROUP_SetendOperand: {
bool be = MCInst_getOpVal(MI, OpNum) != 0;
ARM_check_safe_inc();
if (be) {
ARM_get_detail_op(MI, 0)->type = ARM_OP_SETEND;
ARM_get_detail_op(MI, 0)->setend = ARM_SETEND_BE;
Expand Down Expand Up @@ -1793,6 +1797,7 @@ static void add_cs_detail_template_1(MCInst *MI, arm_op_group op_group,
if (AlwaysPrintImm0)
map_add_implicit_write(MI, MCInst_getOpVal(MI, OpNum));

ARM_check_safe_inc();
cs_arm_op *Op = ARM_get_detail_op(MI, 0);
Op->type = ARM_OP_MEM;
Op->mem.base = MCInst_getOpVal(MI, OpNum);
Expand Down Expand Up @@ -1932,7 +1937,7 @@ void ARM_insert_detail_op_reg_at(MCInst *MI, unsigned index, arm_reg Reg,
if (!detail_is_set(MI))
return;

assert(ARM_get_detail(MI)->op_count < MAX_ARM_OPS);
ARM_check_safe_inc();

cs_arm_op op;
ARM_setup_op(&op);
Expand All @@ -1942,7 +1947,6 @@ void ARM_insert_detail_op_reg_at(MCInst *MI, unsigned index, arm_reg Reg,

cs_arm_op *ops = ARM_get_detail(MI)->operands;
int i = ARM_get_detail(MI)->op_count;
assert(i < MAX_ARM_OPS);
for (; i > 0 && i > index; --i) {
ops[i] = ops[i - 1];
}
Expand All @@ -1957,8 +1961,7 @@ void ARM_insert_detail_op_imm_at(MCInst *MI, unsigned index, int64_t Val,
{
if (!detail_is_set(MI))
return;

assert(ARM_get_detail(MI)->op_count < MAX_ARM_OPS);
ARM_check_safe_inc();

cs_arm_op op;
ARM_setup_op(&op);
Expand All @@ -1968,7 +1971,6 @@ void ARM_insert_detail_op_imm_at(MCInst *MI, unsigned index, int64_t Val,

cs_arm_op *ops = ARM_get_detail(MI)->operands;
int i = ARM_get_detail(MI)->op_count;
assert(i < MAX_ARM_OPS);
for (; i > 0 && i > index; --i) {
ops[i] = ops[i - 1];
}
Expand All @@ -1982,6 +1984,7 @@ void ARM_set_detail_op_reg(MCInst *MI, unsigned OpNum, arm_reg Reg)
{
if (!detail_is_set(MI))
return;
ARM_check_safe_inc();
assert(!(map_get_op_type(MI, OpNum) & CS_OP_MEM));
assert(map_get_op_type(MI, OpNum) == CS_OP_REG);

Expand All @@ -1998,6 +2001,7 @@ void ARM_set_detail_op_imm(MCInst *MI, unsigned OpNum, arm_op_type ImmType,
{
if (!detail_is_set(MI))
return;
ARM_check_safe_inc();
assert(!(map_get_op_type(MI, OpNum) & CS_OP_MEM));
assert(map_get_op_type(MI, OpNum) == CS_OP_IMM);
assert(ImmType == ARM_OP_IMM || ImmType == ARM_OP_PIMM ||
Expand Down Expand Up @@ -2107,6 +2111,8 @@ void ARM_set_detail_op_sysop(MCInst *MI, int Val, arm_op_type type,
{
if (!detail_is_set(MI))
return;
ARM_check_safe_inc();

ARM_get_detail_op(MI, 0)->type = type;
switch (type) {
default:
Expand Down Expand Up @@ -2136,6 +2142,8 @@ void ARM_set_detail_op_float(MCInst *MI, unsigned OpNum, uint64_t Imm)
{
if (!detail_is_set(MI))
return;
ARM_check_safe_inc();

ARM_get_detail_op(MI, 0)->type = ARM_OP_FP;
ARM_get_detail_op(MI, 0)->fp = ARM_AM_getFPImmFloat(Imm);
ARM_inc_op_count(MI);
Expand Down
7 changes: 6 additions & 1 deletion arch/PowerPC/PPCMapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ static void add_cs_detail_general(MCInst *MI, ppc_op_group op_group,
return;
unsigned Val = MCInst_getOpVal(MI, OpNum) << 2;
int32_t Imm = SignExtend32(Val, 32);
PPC_check_safe_inc();
PPC_get_detail_op(MI, 0)->type = PPC_OP_IMM;
PPC_get_detail_op(MI, 0)->imm = Imm;
PPC_get_detail_op(MI, 0)->access = map_get_op_access(MI, OpNum);
Expand All @@ -424,6 +425,7 @@ static void add_cs_detail_general(MCInst *MI, ppc_op_group op_group,
uint64_t Address = MI->address + Imm;
if (IS_32BIT(MI->csh->mode))
Address &= 0xffffffff;
PPC_check_safe_inc();
PPC_get_detail_op(MI, 0)->type = PPC_OP_IMM;
PPC_get_detail_op(MI, 0)->imm = Address;
PPC_get_detail_op(MI, 0)->access = map_get_op_access(MI, OpNum);
Expand Down Expand Up @@ -566,6 +568,7 @@ void PPC_set_detail_op_reg(MCInst *MI, unsigned OpNum, ppc_reg Reg)
{
if (!detail_is_set(MI))
return;
PPC_check_safe_inc();
assert(!(map_get_op_type(MI, OpNum) & CS_OP_MEM));
assert(map_get_op_type(MI, OpNum) == CS_OP_REG);

Expand All @@ -581,6 +584,7 @@ void PPC_set_detail_op_imm(MCInst *MI, unsigned OpNum, int64_t Imm)
{
if (!detail_is_set(MI))
return;
PPC_check_safe_inc();
assert(!(map_get_op_type(MI, OpNum) & CS_OP_MEM));
assert(map_get_op_type(MI, OpNum) == CS_OP_IMM);

Expand All @@ -594,6 +598,7 @@ void PPC_set_mem_access(MCInst *MI, bool status)
{
if (!detail_is_set(MI))
return;
PPC_check_safe_inc();
if ((!status && !doing_mem(MI)) || (status && doing_mem(MI)))
return; // Nothing to do

Expand Down Expand Up @@ -629,7 +634,7 @@ void PPC_insert_detail_op_imm_at(MCInst *MI, unsigned index, int64_t Val,
if (!detail_is_set(MI) || !map_fill_detail_ops(MI))
return;

assert(PPC_get_detail(MI)->op_count < PPC_NUM_OPS);
PPC_check_safe_inc();

cs_ppc_op op;
PPC_setup_op(&op);
Expand Down
2 changes: 1 addition & 1 deletion bindings/python/capstone/hppa_const.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX, UINT8_MAX
# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [hppa_const.py]
HPPA_MAX_OPS = 5
NUM_HPPA_OPS = 5
HPPA_STR_MODIFIER_LEN = 8
HPPA_MAX_MODIFIERS_LEN = 5

Expand Down
2 changes: 1 addition & 1 deletion bindings/python/capstone/tricore_const.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
TRICORE_OP_REG = CS_OP_REG
TRICORE_OP_IMM = CS_OP_IMM
TRICORE_OP_MEM = CS_OP_MEM
TRICORE_OP_COUNT = 8
NUM_ALPHA_OPS = 8

TRICORE_REG_INVALID = 0
TRICORE_REG_FCX = 1
Expand Down
4 changes: 2 additions & 2 deletions include/capstone/aarch64.h
Original file line number Diff line number Diff line change
Expand Up @@ -2852,7 +2852,7 @@ typedef struct {
cs_ac_type mem_acc; ///< CGI memory access according to mayLoad and mayStore
} aarch64_suppl_info;

#define MAX_AARCH64_OPS 16
#define NUM_AARCH64_OPS 16

/// Instruction structure
typedef struct cs_aarch64 {
Expand All @@ -2865,7 +2865,7 @@ typedef struct cs_aarch64 {
/// or 0 when instruction has no operand.
uint8_t op_count;

cs_aarch64_op operands[MAX_AARCH64_OPS]; ///< operands for this instruction.
cs_aarch64_op operands[NUM_AARCH64_OPS]; ///< operands for this instruction.
} cs_aarch64;

/// AArch64 instruction
Expand Down
4 changes: 2 additions & 2 deletions include/capstone/alpha.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ extern "C" {
#pragma warning(disable : 4201)
#endif

#define MAX_ALPHA_OPS 3
#define NUM_ALPHA_OPS 3

//> Operand type for instruction's operands
typedef enum alpha_op_type {
Expand All @@ -43,7 +43,7 @@ typedef struct cs_alpha {
// Number of operands of this instruction,
// or 0 when instruction has no operand.
uint8_t op_count;
cs_alpha_op operands[MAX_ALPHA_OPS]; // operands for this instruction.
cs_alpha_op operands[NUM_ALPHA_OPS]; // operands for this instruction.
} cs_alpha;


Expand Down
4 changes: 2 additions & 2 deletions include/capstone/arm.h
Original file line number Diff line number Diff line change
Expand Up @@ -891,7 +891,7 @@ typedef struct cs_arm_op {
int8_t neon_lane;
} cs_arm_op;

#define MAX_ARM_OPS 36
#define NUM_ARM_OPS 36

/// Instruction structure
typedef struct cs_arm {
Expand All @@ -911,7 +911,7 @@ typedef struct cs_arm {
/// or 0 when instruction has no operand.
uint8_t op_count;

cs_arm_op operands[MAX_ARM_OPS]; ///< operands for this instruction.
cs_arm_op operands[NUM_ARM_OPS]; ///< operands for this instruction.
} cs_arm;

/// ARM instruction
Expand Down
4 changes: 2 additions & 2 deletions include/capstone/hppa.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ extern "C" {
#include "cs_operand.h"
#include "platform.h"

#define HPPA_MAX_OPS 5
#define NUM_HPPA_OPS 5
#define HPPA_STR_MODIFIER_LEN 8
#define HPPA_MAX_MODIFIERS_LEN 5

Expand Down Expand Up @@ -492,7 +492,7 @@ typedef struct cs_hppa {
// Number of operands of this instruction,
// or 0 when instruction has no operand.
uint8_t op_count;
cs_hppa_op operands[HPPA_MAX_OPS]; ///< operands for hppa instruction.
cs_hppa_op operands[NUM_HPPA_OPS]; ///< operands for hppa instruction.
} cs_hppa;

/// HPPA modifiers type. Can be string (most of them) or int (uid, sop)
Expand Down
Loading

0 comments on commit 930bebe

Please sign in to comment.