Rizin
unix-like reverse engineering framework and cli tools
asm_ppc_cs.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2014-2018 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_asm.h>
5 #include <rz_lib.h>
6 #include <capstone/capstone.h>
7 #include "../arch/ppc/libvle/vle.h"
8 #include "../arch/ppc/libps/libps.h"
9 
10 static csh handle = 0;
11 
12 static bool the_end(void *p) {
13  if (handle) {
14  cs_close(&handle);
15  handle = 0;
16  }
17  return true;
18 }
19 
20 static int decompile_vle(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
21  vle_t *instr = 0;
22  vle_handle handle = { 0 };
23  if (len < 2) {
24  return -1;
25  }
26  if (!vle_init(&handle, buf, len) && (instr = vle_next(&handle))) {
27  op->size = instr->size;
28  char buf_asm[64];
29  vle_snprint(buf_asm, sizeof(buf_asm), a->pc, instr);
30  rz_asm_op_set_asm(op, buf_asm);
31  vle_free(instr);
32  } else {
33  rz_asm_op_set_asm(op, "invalid");
34  op->size = 2;
35  return -1;
36  }
37  return op->size;
38 }
39 
40 static int decompile_ps(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
41  ppcps_t instr = { 0 };
42  if (len < 4) {
43  return -1;
44  }
45  op->size = 4;
46  const ut32 data = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
47  if (libps_decode(data, &instr) < 1) {
48  rz_asm_op_set_asm(op, "invalid");
49  return -1;
50  }
51  char buf_asm[64];
52  libps_snprint(buf_asm, sizeof(buf_asm), a->pc, &instr);
53  rz_asm_op_set_asm(op, buf_asm);
54  return op->size;
55 }
56 
57 static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
58  static int omode = -1, obits = -1;
59  int n, ret, mode;
60  ut64 off = a->pc;
61  cs_insn *insn;
62  if (a->cpu && strncmp(a->cpu, "vle", 3) == 0) {
63  // vle is big-endian only
64  if (!a->big_endian) {
65  return -1;
66  }
67  ret = decompile_vle(a, op, buf, len);
68  if (ret >= 0) {
69  return op->size;
70  }
71  } else if (a->cpu && strncmp(a->cpu, "ps", 2) == 0) {
72  // libps is big-endian only
73  if (!a->big_endian) {
74  return -1;
75  }
76  ret = decompile_ps(a, op, buf, len);
77  if (ret >= 0) {
78  return op->size;
79  }
80  }
81  switch (a->bits) {
82  case 32:
83  mode = CS_MODE_32;
84  break;
85  case 64:
86  mode = CS_MODE_64;
87  break;
88  default:
89  mode = 0;
90  break;
91  }
93  if (mode != omode || a->bits != obits) {
94  cs_close(&handle);
95  handle = 0;
96  omode = mode;
97  obits = a->bits;
98  }
99  if (handle == 0) {
100  ret = cs_open(CS_ARCH_PPC, mode, &handle);
101  if (ret != CS_ERR_OK) {
102  return -1;
103  }
104  }
105  op->size = 4;
107  n = cs_disasm(handle, (const ut8 *)buf, len, off, 1, &insn);
108  op->size = 4;
109  if (n > 0 && insn->size > 0) {
110  const char *opstr = sdb_fmt("%s%s%s", insn->mnemonic,
111  insn->op_str[0] ? " " : "", insn->op_str);
113  cs_free(insn, n);
114  return op->size;
115  }
116  rz_asm_op_set_asm(op, "invalid");
117  op->size = 4;
118  cs_free(insn, n);
119  return op->size;
120 }
121 
123  .name = "ppc",
124  .desc = "Capstone PowerPC disassembler",
125  .license = "BSD",
126  .author = "pancake",
127  .arch = "ppc",
128  .cpus = "ppc,vle,ps",
129  .bits = 32 | 64,
131  .fini = the_end,
132  .disassemble = &disassemble,
133 };
134 
135 #ifndef RZ_PLUGIN_INCORE
138  .data = &rz_asm_plugin_ppc_cs,
140 };
141 #endif
size_t len
Definition: 6502dis.c:15
RZ_API void rz_asm_op_set_asm(RzAsmOp *op, const char *str)
Definition: aop.c:53
static csh handle
Definition: asm_ppc_cs.c:10
static int decompile_vle(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len)
Definition: asm_ppc_cs.c:20
RzAsmPlugin rz_asm_plugin_ppc_cs
Definition: asm_ppc_cs.c:122
static int decompile_ps(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len)
Definition: asm_ppc_cs.c:40
RZ_API RzLibStruct rizin_plugin
Definition: asm_ppc_cs.c:136
static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len)
Definition: asm_ppc_cs.c:57
static bool the_end(void *p)
Definition: asm_ppc_cs.c:12
static int opstr(RzAsm *a, ut8 *data, const Opcode *op)
Definition: asm_x86_nz.c:4054
@ CS_ARCH_PPC
PowerPC architecture.
Definition: capstone.h:79
@ CS_MODE_64
64-bit mode (X86, PPC)
Definition: capstone.h:107
@ CS_MODE_32
32-bit mode (X86)
Definition: capstone.h:106
@ CS_MODE_BIG_ENDIAN
big-endian mode
Definition: capstone.h:123
@ CS_MODE_LITTLE_ENDIAN
little-endian mode (default mode)
Definition: capstone.h:103
@ CS_OPT_DETAIL
Break down instruction structure into details.
Definition: capstone.h:171
size_t csh
Definition: capstone.h:71
@ CS_OPT_OFF
Turn OFF an option - default for CS_OPT_DETAIL, CS_OPT_SKIPDATA, CS_OPT_UNSIGNED.
Definition: capstone.h:182
#define RZ_API
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)
Definition: cs.c:798
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_open(cs_arch arch, cs_mode mode, csh *handle)
Definition: cs.c:453
CAPSTONE_EXPORT void CAPSTONE_API cs_free(cs_insn *insn, size_t count)
Definition: cs.c:1017
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_close(csh *handle)
Definition: cs.c:501
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_option(csh ud, cs_opt_type type, size_t value)
Definition: cs.c:646
uint32_t ut32
RZ_API char * sdb_fmt(const char *fmt,...)
Definition: fmt.c:26
const char int mode
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
void * p
Definition: libc.cpp:67
void libps_snprint(char *str, int size, ut64 addr, ppcps_t *instr)
Definition: libps.c:177
bool libps_decode(ut32 data, ppcps_t *ps)
Definition: libps.c:97
int n
Definition: mipsasm.c:19
int CS_ERR_OK
Definition: __init__.py:235
int off
Definition: pal.c:13
@ RZ_LIB_TYPE_ASM
Definition: rz_lib.h:72
#define RZ_SYS_ENDIAN_BIG
Definition: rz_types.h:527
#define RZ_SYS_ENDIAN_LITTLE
Definition: rz_types.h:526
#define RZ_VERSION
Definition: rz_version.h:8
#define a(i)
Definition: sha256.c:41
Definition: libps.h:13
const char * name
Definition: rz_asm.h:130
const char * version
Definition: rz_asm.h:133
Definition: vle.h:18
Definition: vle.h:30
ut16 size
Definition: vle.h:34
Definition: dis.c:32
vle_t * vle_next(vle_handle *handle)
Definition: vle.c:889
int vle_init(vle_handle *handle, const ut8 *buffer, const ut32 size)
Definition: vle.c:870
void vle_snprint(char *str, int size, ut32 addr, vle_t *instr)
Definition: vle.c:915
void vle_free(vle_t *instr)
Definition: vle.c:911
ut64(WINAPI *w32_GetEnabledXStateFeatures)()