Skip to content

Commit 779f910

Browse files
Rot127b1llow
authored andcommitted
Checked in some necessary changes from the #1949
- `cs_simple_types.h` - `MCInst.{c,h}` - `MCInstrDesc.{c,h}` - `utils.{c,h}`
1 parent 35daf04 commit 779f910

File tree

8 files changed

+1126
-8
lines changed

8 files changed

+1126
-8
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ set(SOURCES_ENGINE
106106
)
107107
set(HEADERS_ENGINE
108108
cs_priv.h
109+
cs_simple_types.h
109110
LEB128.h
110111
MathExtras.h
111112
MCDisassembler.h

MCInst.c

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <stdlib.h>
1010
#endif
1111
#include <string.h>
12+
#include <assert.h>
1213

1314
#include "MCInst.h"
1415
#include "utils.h"
@@ -32,16 +33,19 @@ void MCInst_Init(MCInst *inst)
3233
inst->assembly[0] = '\0';
3334
inst->wasm_data.type = WASM_OP_INVALID;
3435
inst->xAcquireRelease = 0;
36+
for (int i = 0; i < MAX_MC_OPS; ++i)
37+
inst->tied_op_idx[i] = -1;
3538
}
3639

3740
void MCInst_clear(MCInst *inst)
3841
{
3942
inst->size = 0;
4043
}
4144

42-
// do not free @Op
45+
// does not free @Op
4346
void MCInst_insert0(MCInst *inst, int index, MCOperand *Op)
4447
{
48+
assert(index < MAX_MC_OPS);
4549
int i;
4650

4751
for(i = inst->size; i > index; i--)
@@ -74,6 +78,7 @@ unsigned MCInst_getOpcodePub(const MCInst *inst)
7478

7579
MCOperand *MCInst_getOperand(MCInst *inst, unsigned i)
7680
{
81+
assert(i < MAX_MC_OPS);
7782
return &inst->Operands[i];
7883
}
7984

@@ -85,6 +90,7 @@ unsigned MCInst_getNumOperands(const MCInst *inst)
8590
// This addOperand2 function doesnt free Op
8691
void MCInst_addOperand2(MCInst *inst, MCOperand *Op)
8792
{
93+
assert(inst->size < MAX_MC_OPS);
8894
inst->Operands[inst->size] = *Op;
8995

9096
inst->size++;
@@ -110,6 +116,21 @@ bool MCOperand_isFPImm(const MCOperand *op)
110116
return op->Kind == kFPImmediate;
111117
}
112118

119+
bool MCOperand_isDFPImm(const MCOperand *op)
120+
{
121+
return op->Kind == kDFPImmediate;
122+
}
123+
124+
bool MCOperand_isExpr(const MCOperand *op)
125+
{
126+
return op->Kind == kExpr;
127+
}
128+
129+
bool MCOperand_isInst(const MCOperand *op)
130+
{
131+
return op->Kind == kInst;
132+
}
133+
113134
/// getReg - Returns the register number.
114135
unsigned MCOperand_getReg(const MCOperand *op)
115136
{
@@ -146,6 +167,7 @@ MCOperand *MCOperand_CreateReg1(MCInst *mcInst, unsigned Reg)
146167
{
147168
MCOperand *op = &(mcInst->Operands[MCINST_CACHE]);
148169

170+
op->MachineOperandType = kRegister;
149171
op->Kind = kRegister;
150172
op->RegVal = Reg;
151173

@@ -157,6 +179,7 @@ void MCOperand_CreateReg0(MCInst *mcInst, unsigned Reg)
157179
MCOperand *op = &(mcInst->Operands[mcInst->size]);
158180
mcInst->size++;
159181

182+
op->MachineOperandType = kRegister;
160183
op->Kind = kRegister;
161184
op->RegVal = Reg;
162185
}
@@ -165,6 +188,7 @@ MCOperand *MCOperand_CreateImm1(MCInst *mcInst, int64_t Val)
165188
{
166189
MCOperand *op = &(mcInst->Operands[MCINST_CACHE]);
167190

191+
op->MachineOperandType = kImmediate;
168192
op->Kind = kImmediate;
169193
op->ImmVal = Val;
170194

@@ -173,9 +197,69 @@ MCOperand *MCOperand_CreateImm1(MCInst *mcInst, int64_t Val)
173197

174198
void MCOperand_CreateImm0(MCInst *mcInst, int64_t Val)
175199
{
200+
assert(mcInst->size < MAX_MC_OPS);
176201
MCOperand *op = &(mcInst->Operands[mcInst->size]);
177202
mcInst->size++;
178203

204+
op->MachineOperandType = kImmediate;
179205
op->Kind = kImmediate;
180206
op->ImmVal = Val;
181207
}
208+
209+
/// Check if any operand of the MCInstrDesc is predicable
210+
bool MCInst_isPredicable(const MCInstrDesc *MIDesc) {
211+
const MCOperandInfo *OpInfo = MIDesc->OpInfo;
212+
unsigned NumOps = MIDesc->NumOperands;
213+
for (unsigned i = 0; i < NumOps; ++i) {
214+
if (MCOperandInfo_isPredicate(&OpInfo[i])) {
215+
return true;
216+
}
217+
}
218+
return false;
219+
}
220+
221+
/// Checks if tied operands exist in the instruction and sets
222+
/// - The writeback flag in detail
223+
/// - Saves the indices of the tied destination operands.
224+
void MCInst_handleWriteback(MCInst *MI, const MCInstrDesc *InstDesc) {
225+
const MCOperandInfo *OpInfo = InstDesc[MCInst_getOpcode(MI)].OpInfo;
226+
unsigned short NumOps = InstDesc[MCInst_getOpcode(MI)].NumOperands;
227+
228+
unsigned i;
229+
for (i = 0; i < NumOps; ++i) {
230+
if (MCOperandInfo_isTiedToOp(&OpInfo[i])) {
231+
int idx = MCOperandInfo_getOperandConstraint(
232+
&InstDesc[MCInst_getOpcode(MI)], i, MCOI_TIED_TO);
233+
234+
if (idx == -1)
235+
continue;
236+
237+
if(i >= MAX_MC_OPS) {
238+
assert(0 && "Maximum number of MC operands reached.");
239+
}
240+
MI->tied_op_idx[i] = idx;
241+
242+
if (MI->flat_insn->detail)
243+
MI->flat_insn->detail->writeback = true;
244+
}
245+
}
246+
}
247+
248+
/// Check if operand with OpNum is tied by another operand
249+
/// (operand is tying destination).
250+
bool MCInst_opIsTied(const MCInst *MI, unsigned OpNum) {
251+
assert(OpNum < MAX_MC_OPS && "Maximum number of MC operands exceeded.");
252+
for (int i = 0; i < MAX_MC_OPS; ++i) {
253+
if (MI->tied_op_idx[i] == OpNum)
254+
return true;
255+
}
256+
return false;
257+
}
258+
259+
/// Check if operand with OpNum is tying another operand
260+
/// (operand is tying src).
261+
bool MCInst_opIsTying(const MCInst *MI, unsigned OpNum) {
262+
assert(OpNum < MAX_MC_OPS && "Maximum number of MC operands exceeded.");
263+
return MI->tied_op_idx[OpNum] != -1;
264+
}
265+

MCInst.h

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#define CS_MCINST_H
2121

2222
#include "include/capstone/capstone.h"
23+
#include "MCInstrDesc.h"
2324
#include "MCRegisterInfo.h"
2425

2526
typedef struct MCInst MCInst;
@@ -34,6 +35,10 @@ struct MCOperand {
3435
kRegister, ///< Register operand.
3536
kImmediate, ///< Immediate operand.
3637
kFPImmediate, ///< Floating-point immediate operand.
38+
kDFPImmediate, ///< Double-Floating-point immediate operand.
39+
kExpr, ///< Relocatable immediate operand.
40+
kInst ///< Sub-instruction operand.
41+
3742
} MachineOperandType;
3843
unsigned char Kind;
3944

@@ -52,6 +57,10 @@ bool MCOperand_isImm(const MCOperand *op);
5257

5358
bool MCOperand_isFPImm(const MCOperand *op);
5459

60+
bool MCOperand_isDFPImm(const MCOperand *op);
61+
62+
bool MCOperand_isExpr(const MCOperand *op);
63+
5564
bool MCOperand_isInst(const MCOperand *op);
5665

5766
/// getReg - Returns the register number.
@@ -84,6 +93,8 @@ void MCOperand_CreateImm0(MCInst *inst, int64_t Val);
8493
// create Imm operand in the last-unused slot
8594
MCOperand *MCOperand_CreateImm1(MCInst *inst, int64_t Val);
8695

96+
#define MAX_MC_OPS 48
97+
8798
/// MCInst - Instances of this class represent a single low-level machine
8899
/// instruction.
89100
struct MCInst {
@@ -92,7 +103,7 @@ struct MCInst {
92103
bool has_imm; // indicate this instruction has an X86_OP_IMM operand - used for ATT syntax
93104
uint8_t op1_size; // size of 1st operand - for X86 Intel syntax
94105
unsigned Opcode; // private opcode
95-
MCOperand Operands[48];
106+
MCOperand Operands[MAX_MC_OPS];
96107
cs_insn *flat_insn; // insn to be exposed to public
97108
uint64_t address; // address of this insn
98109
cs_struct *csh; // save the main csh
@@ -108,7 +119,8 @@ struct MCInst {
108119
// This is copied from cs_x86 struct
109120
uint8_t x86_prefix[4];
110121
uint8_t imm_size; // immediate size for X86_OP_IMM operand
111-
bool writeback; // writeback for ARM
122+
bool writeback; // writeback for ARM
123+
int8_t tied_op_idx[MAX_MC_OPS]; ///< Tied operand indices. Index = Src op; Value: Dest op
112124
// operand access index for list of registers sharing the same access right (for ARM)
113125
uint8_t ac_idx;
114126
uint8_t popcode_adjust; // Pseudo X86 instruction adjust
@@ -141,4 +153,12 @@ unsigned MCInst_getNumOperands(const MCInst *inst);
141153
// This addOperand2 function doesnt free Op
142154
void MCInst_addOperand2(MCInst *inst, MCOperand *Op);
143155

156+
bool MCInst_isPredicable(const MCInstrDesc *MIDesc);
157+
158+
void MCInst_handleWriteback(MCInst *MI, const MCInstrDesc *InstDesc);
159+
160+
bool MCInst_opIsTied(const MCInst *MI, unsigned OpNum);
161+
162+
bool MCInst_opIsTying(const MCInst *MI, unsigned OpNum);
163+
144164
#endif

MCInstrDesc.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,23 @@ bool MCOperandInfo_isOptionalDef(const MCOperandInfo *m)
1616
{
1717
return m->Flags & (1 << MCOI_OptionalDef);
1818
}
19+
20+
/// Checks if operand is tied to another one.
21+
bool MCOperandInfo_isTiedToOp(const MCOperandInfo *m) {
22+
if (m->Constraints & (1 << MCOI_TIED_TO))
23+
return true;
24+
return false;
25+
}
26+
27+
/// Returns the value of the specified operand constraint if
28+
/// it is present. Returns -1 if it is not present.
29+
int MCOperandInfo_getOperandConstraint(const MCInstrDesc *InstrDesc, unsigned OpNum,
30+
MCOI_OperandConstraint Constraint) {
31+
const MCOperandInfo OpInfo = InstrDesc->OpInfo[OpNum];
32+
if (OpNum < InstrDesc->NumOperands &&
33+
(OpInfo.Constraints & (1 << Constraint))) {
34+
unsigned ValuePos = 4 + Constraint * 4;
35+
return (OpInfo.Constraints >> ValuePos) & 0xf;
36+
}
37+
return -1;
38+
}

MCInstrDesc.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,4 +158,9 @@ bool MCOperandInfo_isPredicate(const MCOperandInfo *m);
158158

159159
bool MCOperandInfo_isOptionalDef(const MCOperandInfo *m);
160160

161+
bool MCOperandInfo_isTiedToOp(const MCOperandInfo *m);
162+
163+
int MCOperandInfo_getOperandConstraint(const MCInstrDesc *OpInfo, unsigned OpNum,
164+
MCOI_OperandConstraint Constraint);
165+
161166
#endif

0 commit comments

Comments
 (0)