6 #include <capstone/capstone.h>
7 #include <capstone/ppc.h>
8 #include "../../asm/arch/ppc/libvle/vle.h"
10 #define SPR_HID0 0x3f0
11 #define SPR_HID1 0x3f1
12 #define SPR_HID2 0x3f3
13 #define SPR_HID4 0x3f4
14 #define SPR_HID5 0x3f6
15 #define SPR_HID6 0x3f9
23 #define INSOPS insn->detail->ppc.op_count
24 #define INSOP(n) insn->detail->ppc.operands[n]
25 #define IMM(x) (ut64)(insn->detail->ppc.operands[x].imm)
34 return (mb <= me) ? maskmb & maskme : maskmb | maskme;
40 return (mb <= me) ? maskmb & maskme : maskmb | maskme;
43 static const char *
cmask64(
const char *mb_c,
const char *me_c) {
44 static char cmask[32];
48 mb = strtol(mb_c,
NULL, 16);
51 me = strtol(me_c,
NULL, 16);
57 static const char *
cmask32(
const char *mb_c,
const char *me_c) {
58 static char cmask[32];
62 mb = strtol(mb_c,
NULL, 16);
65 me = strtol(me_c,
NULL, 16);
72 cs_insn *insn = gop->
insn;
74 static char words[8][64];
77 if (n < 0 || n >= 8) {
110 cs_insn *insn = gop->
insn;
113 if (n < 0 || n >= 8) {
138 static char cspr[16];
140 if (n < 0 || n >= 8) {
158 snprintf(cspr,
sizeof(cspr),
"spr_%u", spr);
171 pj_ka(pj,
"operands");
172 cs_ppc *
x = &insn->detail->ppc;
173 for (
i = 0;
i <
x->op_count;
i++) {
178 pj_ks(pj,
"type",
"reg");
182 pj_ks(pj,
"type",
"imm");
186 pj_ks(pj,
"type",
"mem");
190 pj_ki(pj,
"disp",
op->mem.disp);
193 pj_ks(pj,
"type",
"invalid");
206 #define PPCSPR(n) getspr(&gop, n)
207 #define ARG(n) getarg2(&gop, n, "")
208 #define ARG2(n, m) getarg2(&gop, n, m)
211 const char *
p =
NULL;
212 if (analysis->
bits == 32) {
251 "gpr r23 .32 100 0\n"
252 "gpr r24 .32 104 0\n"
253 "gpr r25 .32 108 0\n"
254 "gpr r26 .32 112 0\n"
255 "gpr r27 .32 116 0\n"
256 "gpr r28 .32 120 0\n"
257 "gpr r29 .32 124 0\n"
258 "gpr r30 .32 128 0\n"
259 "gpr r31 .32 132 0\n"
261 "gpr ctr .32 140 0\n"
262 "gpr msr .32 144 0\n"
273 "gpr xer .32 160 0\n"
275 "gpr fpscr .32 168 0\n"
276 "gpr vrsave .32 172 0\n"
277 "gpr pvr .32 176 0\n"
278 "gpr dccr .32 180 0\n"
279 "gpr iccr .32 184 0\n"
280 "gpr dear .32 188 0\n"
281 "gpr hid0 .32 192 0\n"
282 "gpr hid1 .32 196 0\n"
283 "gpr hid2 .32 200 0\n"
284 "gpr hid3 .32 204 0\n"
285 "gpr hid4 .32 208 0\n"
286 "gpr hid5 .32 212 0\n"
287 "gpr hid6 .32 216 0\n"
288 "gpr ibat0 .64 220 0\n"
289 "gpr ibat1 .64 228 0\n"
290 "gpr ibat2 .64 236 0\n"
291 "gpr ibat3 .64 244 0\n"
292 "gpr ibat0l .32 220 0\n"
293 "gpr ibat1l .32 228 0\n"
294 "gpr ibat2l .32 236 0\n"
295 "gpr ibat3l .32 244 0\n"
296 "gpr ibat0u .32 224 0\n"
297 "gpr ibat1u .32 232 0\n"
298 "gpr ibat2u .32 240 0\n"
299 "gpr ibat3u .32 248 0\n"
300 "gpr dbat0 .64 256 0\n"
301 "gpr dbat1 .64 264 0\n"
302 "gpr dbat2 .64 272 0\n"
303 "gpr dbat3 .64 280 0\n"
304 "gpr dbat0l .32 256 0\n"
305 "gpr dbat1l .32 264 0\n"
306 "gpr dbat2l .32 272 0\n"
307 "gpr dbat3l .32 280 0\n"
308 "gpr dbat0u .32 260 0\n"
309 "gpr dbat1u .32 268 0\n"
310 "gpr dbat2u .32 276 0\n"
311 "gpr dbat3u .32 284 0\n"
312 "gpr mask .32 288 0\n";
339 "gpr r11 .64 104 0\n"
340 "gpr r12 .64 112 0\n"
341 "gpr r13 .64 120 0\n"
342 "gpr r14 .64 128 0\n"
343 "gpr r15 .64 136 0\n"
344 "gpr r16 .64 144 0\n"
345 "gpr r17 .64 152 0\n"
346 "gpr r18 .64 160 0\n"
347 "gpr r19 .64 168 0\n"
348 "gpr r20 .64 176 0\n"
349 "gpr r21 .64 184 0\n"
350 "gpr r22 .64 192 0\n"
351 "gpr r23 .64 200 0\n"
352 "gpr r24 .64 208 0\n"
353 "gpr r25 .64 216 0\n"
354 "gpr r26 .64 224 0\n"
355 "gpr r27 .64 232 0\n"
356 "gpr r28 .64 240 0\n"
357 "gpr r29 .64 248 0\n"
358 "gpr r30 .64 256 0\n"
359 "gpr r31 .64 264 0\n"
361 "gpr ctr .64 280 0\n"
362 "gpr msr .64 288 0\n"
373 "gpr xer .64 312 0\n"
375 "gpr fpscr .64 328 0\n"
376 "gpr vrsave .64 336 0\n"
377 "gpr pvr .64 344 0\n"
378 "gpr dccr .32 352 0\n"
379 "gpr iccr .32 356 0\n"
380 "gpr dear .32 360 0\n"
381 "gpr hid0 .64 364 0\n"
382 "gpr hid1 .64 372 0\n"
383 "gpr hid2 .64 380 0\n"
384 "gpr hid3 .64 388 0\n"
385 "gpr hid4 .64 396 0\n"
386 "gpr hid5 .64 404 0\n"
387 "gpr hid6 .64 412 0\n"
388 "gpr ibat0 .64 420 0\n"
389 "gpr ibat1 .64 428 0\n"
390 "gpr ibat2 .64 436 0\n"
391 "gpr ibat3 .64 444 0\n"
392 "gpr ibat0l .32 420 0\n"
393 "gpr ibat1l .32 428 0\n"
394 "gpr ibat2l .32 436 0\n"
395 "gpr ibat3l .32 444 0\n"
396 "gpr ibat0u .32 424 0\n"
397 "gpr ibat1u .32 432 0\n"
398 "gpr ibat2u .32 440 0\n"
399 "gpr ibat3u .32 448 0\n"
400 "gpr dbat0 .64 456 0\n"
401 "gpr dbat1 .64 464 0\n"
402 "gpr dbat2 .64 472 0\n"
403 "gpr dbat3 .64 480 0\n"
404 "gpr dbat0l .32 456 0\n"
405 "gpr dbat1l .32 464 0\n"
406 "gpr dbat2l .32 472 0\n"
407 "gpr dbat3l .32 480 0\n"
408 "gpr dbat0u .32 460 0\n"
409 "gpr dbat1u .32 468 0\n"
410 "gpr dbat2u .32 476 0\n"
411 "gpr dbat3u .32 484 0\n"
412 "gpr mask .64 488 0\n";
539 switch (ppcop.
type) {
593 size_t len = strlen(
op);
603 static int omode = -1, obits = -1;
611 if (
a->cpu && strncmp(
a->cpu,
"vle", 3) == 0) {
613 if (!
a->big_endian) {
622 if (
mode != omode ||
a->bits != obits) {
643 op->mnemonic =
strdup(insn->mnemonic);
656 #if CS_API_MAJOR >= 4
673 if (
ARG(2)[0] ==
'\0') {
676 esilprintf(
op,
"%s,%s,-,0xff,&,%s,=",
ARG(2),
ARG(1),
ARG(0));
705 esilprintf(
op,
"%s,%s,<<<,%s,&,%s,=",
ARG(2),
ARG(1),
cmask32(
ARG(3),
ARG(4)),
ARG(0));
715 esilprintf(
op,
"%s,0x80,&,?{,0xFFFFFFFFFFFFFF00,%s,|,%s,=,}",
ARG(1),
ARG(1),
ARG(0));
717 esilprintf(
op,
"%s,0x80,&,?{,0xFFFFFF00,%s,|,%s,=,}",
ARG(1),
ARG(1),
ARG(0));
723 esilprintf(
op,
"%s,0x8000,&,?{,0xFFFFFFFFFFFF0000,%s,|,%s,=,}",
ARG(1),
ARG(1),
ARG(0));
725 esilprintf(
op,
"%s,0x8000,&,?{,0xFFFF0000,%s,|,%s,=,}",
ARG(1),
ARG(1),
ARG(0));
730 esilprintf(
op,
"%s,0x80000000,&,?{,0xFFFFFFFF00000000,%s,|,%s,=,}",
ARG(1),
ARG(1),
ARG(0));
761 if (strstr(op1,
"r1")) {
763 op->stackptr = -atoi(op1);
806 #if CS_API_MAJOR >= 4
824 #if CS_API_MAJOR >= 4
877 #if CS_API_MAJOR >= 4
969 switch (
insn->detail->ppc.bc) {
971 if (
ARG(1)[0] ==
'\0') {
972 esilprintf(
op,
"0x80,cr0,&,!,!,?{,%s,pc,=,},",
ARG(0));
974 esilprintf(
op,
"0x80,%s,&,!,!,?{,%s,pc,=,},",
ARG(0),
ARG(1));
978 if (
ARG(1)[0] ==
'\0') {
979 esilprintf(
op,
"0x80,cr0,&,!,!,cr0,!,|,?{,%s,pc,=,},",
ARG(0));
981 esilprintf(
op,
"0x80,%s,&,!,!,0,%s,!,|,?{,%s,pc,=,},",
ARG(0),
ARG(0),
ARG(1));
985 if (
ARG(1)[0] ==
'\0') {
988 esilprintf(
op,
"%s,!,?{,%s,pc,=,},",
ARG(0),
ARG(1));
992 if (
ARG(1)[0] ==
'\0') {
993 esilprintf(
op,
"0x80,cr0,&,!,cr0,!,|,?{,%s,pc,=,},",
ARG(0));
995 esilprintf(
op,
"0x80,%s,&,!,%s,!,|,?{,%s,pc,=,},",
ARG(0),
ARG(0),
ARG(1));
999 if (
ARG(1)[0] ==
'\0') {
1000 esilprintf(
op,
"0x80,cr0,&,!,?{,%s,pc,=,},",
ARG(0));
1002 esilprintf(
op,
"0x80,%s,&,!,?{,%s,pc,=,},",
ARG(0),
ARG(1));
1006 if (
ARG(1)[0] ==
'\0') {
1007 esilprintf(
op,
"cr0,!,!,?{,%s,pc,=,},",
ARG(0));
1009 esilprintf(
op,
"%s,!,!,?{,%s,pc,=,},",
ARG(0),
ARG(1));
1025 switch (
insn->detail->ppc.operands[0].type) {
1047 esilprintf(
op,
"1,ctr,-=,$z,!,?{,%s,pc,=,}",
ARG(0));
1067 esilprintf(
op,
"1,ctr,-=,$z,!,?{,lr,pc,=,},");
1077 esilprintf(
op,
"1,ctr,-=,$z,?{,%s,pc,=,}",
ARG(0));
1109 switch (
insn->detail->ppc.bc) {
1115 if (
ARG(1)[0] ==
'\0') {
1116 esilprintf(
op,
"0x80,cr0,&,!,!,?{,lr,pc,=,},");
1118 esilprintf(
op,
"0x80,%s,&,!,!,?{,lr,pc,=,},",
ARG(0));
1122 if (
ARG(1)[0] ==
'\0') {
1123 esilprintf(
op,
"0x80,cr0,&,!,!,cr0,!,|,?{,lr,pc,=,},");
1125 esilprintf(
op,
"0x80,%s,&,!,!,0,%s,!,|,?{,lr,pc,=,},",
ARG(0),
ARG(0));
1129 if (
ARG(1)[0] ==
'\0') {
1136 if (
ARG(1)[0] ==
'\0') {
1137 esilprintf(
op,
"0x80,cr0,&,!,cr0,!,|,?{,lr,pc,=,},");
1139 esilprintf(
op,
"0x80,%s,&,!,%s,!,|,?{,lr,pc,=,},",
ARG(0),
ARG(0));
1143 if (
ARG(1)[0] ==
'\0') {
1144 esilprintf(
op,
"0x80,cr0,&,!,?{,lr,pc,=,},");
1146 esilprintf(
op,
"0x80,%s,&,!,?{,lr,pc,=,},",
ARG(0));
1150 if (
ARG(1)[0] ==
'\0') {
1153 esilprintf(
op,
"%s,!,!,?{,lr,pc,=,},",
ARG(0));
1175 esilprintf(
op,
"16,%s,<<,%s,^,%s,=",
ARG(2),
ARG(1),
ARG(0));
1207 esilprintf(
op,
"16,%s,<<,%s,&,%s,=",
ARG(2),
ARG(1),
ARG(0));
1216 esilprintf(
op,
"16,%s,<<,%s,|,%s,=",
ARG(2),
ARG(1),
ARG(0));
1283 esilprintf(
op,
"%s,%s,<<<,%s,&,%s,=",
ARG(2),
ARG(1),
cmask64(
ARG(3),
"0x3F"),
ARG(0));
1288 esilprintf(
op,
"%s,%s,<<<,%s,&,%s,=",
ARG(2),
ARG(1),
cmask64(0,
ARG(3)),
ARG(0));
1304 if (
a->cpu && !strncmp(
a->cpu,
"vle", 3)) {
1311 #define KW(d, ds, m, ms) rz_list_append(l, rz_search_keyword_new((const ut8 *)d, ds, (const ut8 *)m, ms, NULL))
1313 KW(
"\x7c\x08\x02\xa6", 4,
NULL, 0);
1319 .desc =
"Capstone PowerPC analysis",
1330 #ifndef RZ_PLUGIN_INCORE
RZ_API RzAnalysisValue * rz_analysis_value_new(void)
static int parse_reg_name(RzRegItem *reg, csh handle, cs_insn *insn, int reg_num)
static char * get_reg_profile(RzAnalysis *analysis)
static int analop_vle(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, RzAnalysisOpMask mask)
static ut64 getarg(struct Getarg *gop, int n)
static void create_src_dst(RzAnalysisOp *op)
static const char * cmask64(const char *mb_c, const char *me_c)
static char * getarg2(struct Getarg *gop, int n, const char *setstr)
static void opex(RzStrBuf *buf, csh handle, cs_insn *insn)
static int archinfo(RzAnalysis *a, int q)
static int analop(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, RzAnalysisOpMask mask)
RzAnalysisPlugin rz_analysis_plugin_ppc_cs
RZ_API RzLibStruct rizin_plugin
static const char * getspr(struct Getarg *gop, int n)
static RzRegItem base_regs[4]
static ut32 mask32(ut32 mb, ut32 me)
static char * shrink(char *op)
static const char * cmask32(const char *mb_c, const char *me_c)
static void set_src_dst(RzAnalysisValue *val, csh *handle, cs_insn *insn, int x)
static ut64 mask64(ut64 mb, ut64 me)
static RzList * analysis_preludes(RzAnalysis *analysis)
static void op_fillval(RzAnalysisOp *op, csh handle, cs_insn *insn)
static mcore_handle handle
@ CS_ARCH_PPC
PowerPC architecture.
@ CS_MODE_64
64-bit mode (X86, PPC)
@ CS_MODE_32
32-bit mode (X86)
@ CS_MODE_BIG_ENDIAN
big-endian mode
@ CS_MODE_LITTLE_ENDIAN
little-endian mode (default mode)
@ CS_OPT_DETAIL
Break down instruction structure into details.
@ CS_OPT_ON
Turn ON an option (CS_OPT_DETAIL, CS_OPT_SKIPDATA).
CAPSTONE_EXPORT size_t CAPSTONE_API cs_disasm(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, size_t count, cs_insn **insn)
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_open(cs_arch arch, cs_mode mode, csh *handle)
CAPSTONE_EXPORT void CAPSTONE_API cs_free(cs_insn *insn, size_t count)
CAPSTONE_EXPORT const char *CAPSTONE_API cs_reg_name(csh ud, unsigned int reg)
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_close(csh *handle)
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_option(csh ud, cs_opt_type type, size_t value)
RZ_API void rz_search_keyword_free(RzSearchKeyword *kw)
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
#define esilprintf(op, fmt,...)
@ RZ_ANALYSIS_OP_MASK_DISASM
@ RZ_ANALYSIS_OP_MASK_VAL
@ RZ_ANALYSIS_OP_MASK_OPEX
@ RZ_ANALYSIS_OP_MASK_ESIL
#define RZ_ANALYSIS_OP_TYPE_MASK
@ RZ_ANALYSIS_OP_TYPE_CMP
@ RZ_ANALYSIS_OP_TYPE_SUB
@ RZ_ANALYSIS_OP_TYPE_LOAD
@ RZ_ANALYSIS_OP_TYPE_MUL
@ RZ_ANALYSIS_OP_TYPE_ROL
@ RZ_ANALYSIS_OP_TYPE_JMP
@ RZ_ANALYSIS_OP_TYPE_AND
@ RZ_ANALYSIS_OP_TYPE_SAL
@ RZ_ANALYSIS_OP_TYPE_SYNC
@ RZ_ANALYSIS_OP_TYPE_UJMP
@ RZ_ANALYSIS_OP_TYPE_NOR
@ RZ_ANALYSIS_OP_TYPE_ROR
@ RZ_ANALYSIS_OP_TYPE_SWI
@ RZ_ANALYSIS_OP_TYPE_SAR
@ RZ_ANALYSIS_OP_TYPE_TRAP
@ RZ_ANALYSIS_OP_TYPE_CCALL
@ RZ_ANALYSIS_OP_TYPE_CALL
@ RZ_ANALYSIS_OP_TYPE_ADD
@ RZ_ANALYSIS_OP_TYPE_STORE
@ RZ_ANALYSIS_OP_TYPE_CRET
@ RZ_ANALYSIS_OP_TYPE_SHR
@ RZ_ANALYSIS_OP_TYPE_RJMP
@ RZ_ANALYSIS_OP_TYPE_CJMP
@ RZ_ANALYSIS_OP_TYPE_DIV
@ RZ_ANALYSIS_OP_TYPE_CAST
@ RZ_ANALYSIS_OP_TYPE_UCJMP
@ RZ_ANALYSIS_OP_TYPE_MOV
@ RZ_ANALYSIS_OP_TYPE_SHL
@ RZ_ANALYSIS_OP_TYPE_ILL
@ RZ_ANALYSIS_OP_TYPE_NOT
@ RZ_ANALYSIS_OP_TYPE_RET
@ RZ_ANALYSIS_OP_TYPE_NOP
@ RZ_ANALYSIS_OP_TYPE_LEA
@ RZ_ANALYSIS_OP_TYPE_RCALL
@ RZ_ANALYSIS_OP_TYPE_XOR
void(* RzListFree)(void *ptr)
RZ_API PJ * pj_ka(PJ *j, const char *k)
RZ_API PJ * pj_ki(PJ *j, const char *k, int d)
RZ_API PJ * pj_end(PJ *j)
RZ_API const char * pj_string(PJ *pj)
RZ_API void pj_free(PJ *j)
RZ_API PJ * pj_ks(PJ *j, const char *k, const char *v)
RZ_API PJ * pj_kN(PJ *j, const char *k, st64 n)
RZ_API bool rz_strbuf_append(RzStrBuf *sb, const char *s)
RZ_API void rz_strbuf_fini(RzStrBuf *sb)
RZ_API void rz_strbuf_init(RzStrBuf *sb)
ppc_op_mem mem
base/disp value for MEM operand
ppc_op_type type
operand type
int64_t imm
immediate value for IMM operand
int32_t disp
displacement/offset value
@ PPC_OP_REG
= CS_OP_REG (Register operand).
@ PPC_OP_IMM
= CS_OP_IMM (Immediate operand).
@ PPC_OP_MEM
= CS_OP_MEM (Memory operand).
@ PPC_OP_CRX
Condition Register field.
@ PPC_OP_INVALID
= CS_OP_INVALID (Uninitialized).
@ PPC_BC_SO
summary overflow
@ PPC_BC_NS
not summary overflow
vle_t * vle_next(vle_handle *handle)
int vle_init(vle_handle *handle, const ut8 *buffer, const ut32 size)
void vle_free(vle_t *instr)
ut64(WINAPI *w32_GetEnabledXStateFeatures)()