Rizin
unix-like reverse engineering framework and cli tools
opcode.c File Reference
#include "opcode.h"

Go to the source code of this file.

Functions

bool pyc_opcodes_equal (pyc_opcodes *op, const char *version)
 
pyc_opcodesget_opcode_by_version (char *version)
 
pyc_opcodesnew_pyc_opcodes ()
 
void free_opcode (pyc_opcodes *opcodes)
 
void add_arg_fmt (pyc_opcodes *ret, char *op_name, const char *(*formatter)(ut32 oparg))
 
void() def_opN (struct op_parameter par)
 
void() name_opN (struct op_parameter par)
 
void() local_opN (struct op_parameter par)
 
void() free_opN (struct op_parameter par)
 
void() store_opN (struct op_parameter par)
 
void() varargs_op (struct op_parameter par)
 
void() const_opN (struct op_parameter par)
 
void() compare_op (struct op_parameter par)
 
void() jabs_opN (struct op_parameter par)
 
void() jrel_opN (struct op_parameter par)
 
void() nargs_op (struct op_parameter par)
 
void() rm_op (struct op_parameter par)
 

Variables

static version_opcode version_op []
 

Function Documentation

◆ add_arg_fmt()

void add_arg_fmt ( pyc_opcodes ret,
char *  op_name,
const char *(*)(ut32 oparg)  formatter 
)

Definition at line 234 of file opcode.c.

234  {
236  if (!fmt) {
237  return;
238  }
239  fmt->op_name = op_name;
240  fmt->formatter = formatter;
241  rz_list_append(ret->opcode_arg_fmt, fmt);
242 }
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
#define RZ_NEW0(x)
Definition: rz_types.h:284
char * op_name
Definition: opcode.h:55
const char *(* formatter)(ut32 oparg)
Definition: opcode.h:56
RzList * opcode_arg_fmt
Definition: opcode.h:50

References pyc_arg_fmt::formatter, pyc_arg_fmt::op_name, pyc_opcodes::opcode_arg_fmt, rz_list_append(), and RZ_NEW0.

Referenced by opcode_10(), opcode_11(), opcode_12(), opcode_13(), opcode_14(), opcode_15(), opcode_16(), opcode_20(), opcode_21(), opcode_22(), opcode_23(), opcode_24(), opcode_25(), opcode_26(), opcode_27(), opcode_30(), opcode_31(), opcode_32(), opcode_33(), opcode_34(), opcode_35(), opcode_36(), opcode_37(), opcode_38(), opcode_39(), and opcode_3x().

◆ compare_op()

void() compare_op ( struct op_parameter  par)

Definition at line 301 of file opcode.c.

301  {
302  def_op(.op_obj = par.op_obj, .op_name = par.op_name, .op_code = par.op_code, .pop = par.pop, .push = par.push);
303  par.op_obj[par.op_code].type |= HASCOMPARE;
304 }
#define def_op(...)
Definition: opcode.h:127
@ HASCOMPARE
Definition: opcode.h:16
pyc_opcode_object * op_obj
Definition: opcode.h:117
ut8 op_code
Definition: opcode.h:119
const char * op_name
Definition: opcode.h:118
st8 push
Definition: opcode.h:121
char * op_name
Definition: opcode.h:38

References def_op, HASCOMPARE, pyc_opcode_object::op_name, and op_parameter::op_obj.

◆ const_opN()

void() const_opN ( struct op_parameter  par)

Definition at line 296 of file opcode.c.

296  {
297  def_op(.op_obj = par.op_obj, .op_name = par.op_name, .op_code = par.op_code, .pop = par.pop, .push = par.push);
298  par.op_obj[par.op_code].type |= HASCONST;
299 }
@ HASCONST
Definition: opcode.h:18

References def_op, HASCONST, pyc_opcode_object::op_name, and op_parameter::op_obj.

◆ def_opN()

void() def_opN ( struct op_parameter  par)

Definition at line 244 of file opcode.c.

244  {
245  free(par.op_obj[par.op_code].op_name);
246  par.op_obj[par.op_code].op_name = strdup(par.op_name);
247  par.op_obj[par.op_code].op_code = par.op_code;
248  par.op_obj[par.op_code].op_pop = par.pop;
249  par.op_obj[par.op_code].op_push = par.push;
250  if (!par.fallthrough) {
251  par.op_obj[par.op_code].type |= NOFOLLOW;
252  }
253 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
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")
@ NOFOLLOW
Definition: opcode.h:27
bool fallthrough
Definition: opcode.h:124

References free(), NOFOLLOW, and strdup().

Referenced by opcode_15().

◆ free_opcode()

void free_opcode ( pyc_opcodes opcodes)

Definition at line 217 of file opcode.c.

217  {
218  size_t i;
219  if (opcodes == NULL || opcodes->opcodes == NULL) {
220  return;
221  }
222  for (i = 0; i < 256; i++) {
223  if (opcodes->opcodes[i].op_name) {
224  free(opcodes->opcodes[i].op_name);
225  }
226  }
227  free(opcodes->opcodes);
228  if (opcodes->opcode_arg_fmt) {
229  rz_list_free(opcodes->opcode_arg_fmt);
230  }
231  free(opcodes);
232 }
lzma_index ** i
Definition: index.h:629
OPCODE_DESC opcodes[]
Definition: avr_esil.c:1270
#define NULL
Definition: cris-opc.c:27
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137

References free(), i, NULL, opcodes, and rz_list_free().

Referenced by finish(), and pyc_op().

◆ free_opN()

void() free_opN ( struct op_parameter  par)

Definition at line 265 of file opcode.c.

265  {
266  def_op(.op_obj = par.op_obj, .op_name = par.op_name, .op_code = par.op_code, .pop = par.pop, .push = par.push);
267  par.op_obj[par.op_code].type |= HASFREE;
268 }
@ HASFREE
Definition: opcode.h:19

References def_op, HASFREE, pyc_opcode_object::op_name, and op_parameter::op_obj.

◆ get_opcode_by_version()

pyc_opcodes* get_opcode_by_version ( char *  version)

Definition at line 169 of file opcode.c.

169  {
170  if (version == NULL) {
171  return NULL;
172  }
173  version_opcode *vop = version_op;
174 
175  while (vop->version) {
176  if (!strcmp(vop->version, version)) {
177  return vop->opcode_func();
178  }
179  vop++;
180  }
181 
182  return NULL; // No match version
183 }
static version_opcode version_op[]
Definition: opcode.c:6
pyc_opcodes *(* opcode_func)()
Definition: opcode.h:61
char * version
Definition: opcode.h:60

References NULL, version_opcode::opcode_func, version_opcode::version, and version_op.

Referenced by disassemble(), and pyc_op().

◆ jabs_opN()

void() jabs_opN ( struct op_parameter  par)

Definition at line 306 of file opcode.c.

306  {
307  def_op00(.op_obj = par.op_obj, .op_name = par.op_name, .op_code = par.op_code, .pop = par.pop, .push = par.push, .fallthrough = par.fallthrough);
308  par.op_obj[par.op_code].type |= HASJABS;
309  if (par.conditional) {
310  par.op_obj[par.op_code].type |= HASCONDITION;
311  }
312 }
#define def_op00(...)
Definition: opcode.h:129
@ HASCONDITION
Definition: opcode.h:17
@ HASJABS
Definition: opcode.h:20
bool conditional
Definition: opcode.h:123

References def_op00, HASCONDITION, HASJABS, pyc_opcode_object::op_name, and op_parameter::op_obj.

◆ jrel_opN()

void() jrel_opN ( struct op_parameter  par)

Definition at line 314 of file opcode.c.

314  {
315  def_op00(.op_obj = par.op_obj, .op_name = par.op_name, .op_code = par.op_code, .pop = par.pop, .push = par.push, .fallthrough = par.fallthrough);
316  par.op_obj[par.op_code].type |= HASJREL;
317  if (par.conditional) {
318  par.op_obj[par.op_code].type |= HASCONDITION;
319  }
320 }
@ HASJREL
Definition: opcode.h:21

References def_op00, HASCONDITION, HASJREL, pyc_opcode_object::op_name, and op_parameter::op_obj.

◆ local_opN()

void() local_opN ( struct op_parameter  par)

Definition at line 260 of file opcode.c.

260  {
261  def_op(.op_obj = par.op_obj, .op_name = par.op_name, .op_code = par.op_code, .pop = par.pop, .push = par.push);
262  par.op_obj[par.op_code].type |= HASLOCAL;
263 }
@ HASLOCAL
Definition: opcode.h:22

References def_op, HASLOCAL, pyc_opcode_object::op_name, and op_parameter::op_obj.

◆ name_opN()

void() name_opN ( struct op_parameter  par)

Definition at line 255 of file opcode.c.

255  {
256  def_op(.op_obj = par.op_obj, .op_name = par.op_name, .op_code = par.op_code, .pop = par.pop, .push = par.push);
257  par.op_obj[par.op_code].type |= HASNAME;
258 }
@ HASNAME
Definition: opcode.h:23

References def_op, HASNAME, pyc_opcode_object::op_name, and op_parameter::op_obj.

◆ nargs_op()

void() nargs_op ( struct op_parameter  par)

Definition at line 322 of file opcode.c.

322  {
323  def_op(.op_obj = par.op_obj, .op_name = par.op_name, .op_code = par.op_code, .pop = par.pop, .push = par.push);
324  par.op_obj[par.op_code].type |= HASNARGS;
325 }
@ HASNARGS
Definition: opcode.h:24

References def_op, HASNARGS, pyc_opcode_object::op_name, and op_parameter::op_obj.

◆ new_pyc_opcodes()

pyc_opcodes* new_pyc_opcodes ( )

Definition at line 185 of file opcode.c.

185  {
186  size_t i, j;
188  if (!ret) {
189  return NULL;
190  }
191  ret->have_argument = 90;
192  ret->opcodes = malloc(sizeof(pyc_opcode_object) * 256);
193  if (!ret->opcodes) {
194  free(ret);
195  return NULL;
196  }
197  for (i = 0; i < 256; i++) {
198  ret->opcodes[i].op_name = rz_str_newf("<%zu>", i);
199  if (!ret->opcodes[i].op_name) {
200  for (j = 0; j < i; j++) {
201  free(ret->opcodes[j].op_name);
202  }
203  free(ret->opcodes);
204  RZ_FREE(ret);
205  return NULL;
206  }
207  ret->opcodes[i].type = 0;
208  ret->opcodes[i].op_code = i;
209  ret->opcodes[i].op_push = 0;
210  ret->opcodes[i].op_pop = 0;
211  }
212 
214  return ret;
215 }
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
void * malloc(size_t size)
Definition: malloc.c:123
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
#define RZ_FREE(x)
Definition: rz_types.h:369
ut8 have_argument
Definition: opcode.h:47
pyc_opcode_object * opcodes
Definition: opcode.h:51

References free(), pyc_opcodes::have_argument, i, malloc(), NULL, pyc_opcode_object::op_code, pyc_opcode_object::op_name, pyc_opcode_object::op_pop, pyc_opcode_object::op_push, pyc_opcodes::opcode_arg_fmt, pyc_opcodes::opcodes, RZ_FREE, rz_list_newf(), RZ_NEW0, rz_str_newf(), and pyc_opcode_object::type.

Referenced by opcode_15(), opcode_2x(), and opcode_3x().

◆ pyc_opcodes_equal()

bool pyc_opcodes_equal ( pyc_opcodes op,
const char *  version 
)

Definition at line 151 of file opcode.c.

151  {
152  if (version == NULL || op == NULL) {
153  return false;
154  }
155  version_opcode *vop = version_op;
156 
157  while (vop->version) {
158  if (!strcmp(vop->version, version)) {
159  if (vop->opcode_func == (pyc_opcodes * (*)())(op->version_sig)) {
160  return true;
161  }
162  }
163  vop++;
164  }
165 
166  return false;
167 }
Definition: dis.c:32

References NULL, version_opcode::opcode_func, version_opcode::version, and version_op.

Referenced by disassemble(), and pyc_op().

◆ rm_op()

void() rm_op ( struct op_parameter  par)

Definition at line 327 of file opcode.c.

327  {
328  pyc_opcode_object *op_obj = &par.op_obj[par.op_code];
329  if (op_obj->op_code == par.op_code && !strcmp(op_obj->op_name, par.op_name)) {
330  free(op_obj->op_name);
331  op_obj->op_name = rz_str_newf("<%u>", par.op_code);
332  op_obj->type = op_obj->op_pop = op_obj->op_push = 0;
333  } else {
334  RZ_LOG_ERROR("Error in rm_op() while constructing opcodes for .pyc file: \n .op_code = %u, .op_name = %s", par.op_code, par.op_name);
335  }
336 }
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58

References free(), pyc_opcode_object::op_code, pyc_opcode_object::op_name, op_parameter::op_obj, pyc_opcode_object::op_pop, pyc_opcode_object::op_push, RZ_LOG_ERROR, rz_str_newf(), and pyc_opcode_object::type.

◆ store_opN()

void() store_opN ( struct op_parameter  par)

Definition at line 270 of file opcode.c.

270  {
271  switch (par.func) {
272  case NAME_OP:
273  name_op(.op_obj = par.op_obj, .op_name = par.op_name, .op_code = par.op_code, .pop = par.pop, .push = par.push);
274  break;
275  case LOCAL_OP:
276  local_op(.op_obj = par.op_obj, .op_name = par.op_name, .op_code = par.op_code, .pop = par.pop, .push = par.push);
277  break;
278  case FREE_OP:
279  free_op(.op_obj = par.op_obj, .op_name = par.op_name, .op_code = par.op_code, .pop = par.pop, .push = par.push);
280  break;
281  case DEF_OP:
282  def_op(.op_obj = par.op_obj, .op_name = par.op_name, .op_code = par.op_code, .pop = par.pop, .push = par.push);
283  break;
284  default:
285  RZ_LOG_ERROR("Error in store_op in pyc/opcode.c, call function %u.\n", par.func);
286  return;
287  }
288  par.op_obj[par.op_code].type |= HASSTORE;
289 }
#define free_op(...)
Definition: opcode.h:141
#define local_op(...)
Definition: opcode.h:137
@ LOCAL_OP
Definition: opcode.h:32
@ DEF_OP
Definition: opcode.h:34
@ FREE_OP
Definition: opcode.h:33
@ NAME_OP
Definition: opcode.h:31
@ HASSTORE
Definition: opcode.h:25
#define name_op(...)
Definition: opcode.h:133
pyc_store_op_func func
Definition: opcode.h:122

References DEF_OP, def_op, FREE_OP, free_op, HASSTORE, LOCAL_OP, local_op, NAME_OP, name_op, pyc_opcode_object::op_name, op_parameter::op_obj, and RZ_LOG_ERROR.

◆ varargs_op()

void() varargs_op ( struct op_parameter  par)

Definition at line 291 of file opcode.c.

291  {
292  def_op(.op_obj = par.op_obj, .op_name = par.op_name, .op_code = par.op_code, .pop = par.pop, .push = par.push);
293  par.op_obj[par.op_code].type |= HASVARGS;
294 }
@ HASVARGS
Definition: opcode.h:26

References def_op, HASVARGS, pyc_opcode_object::op_name, and op_parameter::op_obj.

Variable Documentation

◆ version_op

version_opcode version_op[]
static

Definition at line 6 of file opcode.c.

Referenced by get_opcode_by_version(), and pyc_opcodes_equal().