rizin/librz/arch/arch-asm/pyc/opcode.h
2024-03-07 18:38:49 +08:00

180 lines
6 KiB
C

// SPDX-FileCopyrightText: 2016-2020 c0riolis
// SPDX-FileCopyrightText: 2016-2020 x0urc3
// SPDX-License-Identifier: LGPL-3.0-only
#ifndef OPCODE_H
#define OPCODE_H
#include <rz_types.h>
#include <rz_list.h>
#include <rz_util.h>
#include <rz_analysis.h>
#define OBJECT_SIZE_ON_STACK 1
typedef enum {
HASCOMPARE = 0x1,
HASCONDITION = 0x2, // conditional operator; has jump offset
HASCONST = 0x4,
HASFREE = 0x8,
HASJABS = 0x10, // Will appear with HASCONDITION sometimes
HASJREL = 0x20, // Will appear with HASCONDITION sometimes
HASLOCAL = 0x40,
HASNAME = 0x80,
HASNARGS = 0x100, // For function-like calls
HASSTORE = 0x200, // Some sort of store operation
HASVARGS = 0x400, // Similar but for operators BUILD_xxx
NOFOLLOW = 0x800, // Instruction doesn't fall to the next opcode
} pyc_opcode_type;
typedef enum {
NAME_OP = 0x1,
LOCAL_OP = 0x2,
FREE_OP = 0x4,
DEF_OP = 0x8,
} pyc_store_op_func;
typedef struct {
char *op_name;
ut16 type;
ut8 op_code;
st8 op_push;
st8 op_pop;
} pyc_opcode_object;
typedef struct {
ut8 extended_arg;
ut8 have_argument;
ut8 bits;
bool jump_use_instruction_offset;
void *(*version_sig)();
RzList /*<pyc_arg_fmt *>*/ *opcode_arg_fmt;
pyc_opcode_object *opcodes;
} pyc_opcodes;
typedef struct {
char *op_name;
const char *(*formatter)(ut32 oparg);
} pyc_arg_fmt;
typedef struct {
char *version;
pyc_opcodes *(*opcode_func)();
} version_opcode;
typedef struct {
char *op_name;
void (*func)(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg);
} op_analysis_func;
void analysis_pyc_op(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg);
pyc_opcodes *opcode_2x(void);
pyc_opcodes *opcode_3x(void);
pyc_opcodes *opcode_10(void);
pyc_opcodes *opcode_11(void);
pyc_opcodes *opcode_12(void);
pyc_opcodes *opcode_13(void);
pyc_opcodes *opcode_14(void);
pyc_opcodes *opcode_15(void);
pyc_opcodes *opcode_16(void);
pyc_opcodes *opcode_20(void);
pyc_opcodes *opcode_21(void);
pyc_opcodes *opcode_22(void);
pyc_opcodes *opcode_23(void);
pyc_opcodes *opcode_24(void);
pyc_opcodes *opcode_25(void);
pyc_opcodes *opcode_26(void);
pyc_opcodes *opcode_27(void);
pyc_opcodes *opcode_30(void);
pyc_opcodes *opcode_31(void);
pyc_opcodes *opcode_32(void);
pyc_opcodes *opcode_33(void);
pyc_opcodes *opcode_34(void);
pyc_opcodes *opcode_35(void);
pyc_opcodes *opcode_36(void);
pyc_opcodes *opcode_37(void);
pyc_opcodes *opcode_38(void);
pyc_opcodes *opcode_39(void);
pyc_opcodes *opcode_310(void);
pyc_opcodes *get_opcode_by_version(char *version);
pyc_opcodes *new_pyc_opcodes();
void free_opcode(pyc_opcodes *opcodes);
bool pyc_opcodes_equal(pyc_opcodes *op, const char *version);
void add_arg_fmt(pyc_opcodes *ret, char *op_name, const char *(*formatter)(ut32 oparg));
const char *format_MAKE_FUNCTION_arg_3x(ut32 oparg);
const char *format_extended_arg(ut32 oparg);
const char *format_CALL_FUNCTION_pos_name_encoded(ut32 oparg);
const char *format_CALL_FUNCTION_KW_36(ut32 oparg);
const char *format_CALL_FUNCTION_EX_36(ut32 oparg);
const char *format_MAKE_FUNCTION_arg_36(ut32 oparg);
const char *format_value_flags_36(ut32 oparg);
const char *format_extended_arg_36(ut32 oparg);
struct op_parameter {
pyc_opcode_object *op_obj;
const char *op_name;
ut8 op_code;
st8 pop;
st8 push;
pyc_store_op_func func;
bool conditional;
bool fallthrough;
};
#define def_op(...) def_opN((struct op_parameter){ .fallthrough = true, __VA_ARGS__ })
#define def_op0(...) def_opN((struct op_parameter){ .pop = -2, .push = -2, .fallthrough = true, __VA_ARGS__ })
#define def_op00(...) def_opN((struct op_parameter){ __VA_ARGS__ })
void(def_opN)(struct op_parameter par);
#define name_op0(...) name_opN((struct op_parameter){ .pop = -2, .push = -2, __VA_ARGS__ })
#define name_op(...) name_opN((struct op_parameter){ __VA_ARGS__ })
void(name_opN)(struct op_parameter par);
#define local_op0(...) local_opN((struct op_parameter){ .pop = 0, .push = 1, __VA_ARGS__ })
#define local_op(...) local_opN((struct op_parameter){ __VA_ARGS__ })
void(local_opN)(struct op_parameter par);
#define free_op0(...) free_opN((struct op_parameter){ .pop = 0, .push = 1, __VA_ARGS__ })
#define free_op(...) free_opN((struct op_parameter){ __VA_ARGS__ })
void(free_opN)(struct op_parameter par);
#define store_op00(...) store_opN((struct op_parameter){ __VA_ARGS__ })
#define store_op(...) store_opN((struct op_parameter){ .func = DEF_OP, __VA_ARGS__ })
#define store_op0(...) store_opN((struct op_parameter){ .pop = 0, .push = 1, .func = DEF_OP, __VA_ARGS__ })
void(store_opN)(struct op_parameter par);
#define varargs_op(...) varargs_op((struct op_parameter){ __VA_ARGS__ })
#define varargs_op0(...) varargs_op((struct op_parameter){ .pop = -1, .push = 1, __VA_ARGS__ })
void(varargs_op)(struct op_parameter par);
#define const_op(...) const_opN((struct op_parameter){ .pop = 0, .push = 1, __VA_ARGS__ })
#define const_op00(...) const_opN((struct op_parameter){ __VA_ARGS__ })
void(const_opN)(struct op_parameter par);
#define compare_op0(...) compare_op((struct op_parameter){ .pop = 2, .push = 1, __VA_ARGS__ })
#define compare_op(...) compare_op((struct op_parameter){ __VA_ARGS__ })
void(compare_op)(struct op_parameter par);
#define jabs_op00(...) jabs_opN((struct op_parameter){ __VA_ARGS__ })
#define jabs_op0(...) jabs_opN((struct op_parameter){ .pop = 0, .push = 0, .conditional = false, .fallthrough = true, __VA_ARGS__ })
#define jabs_op(...) jabs_opN((struct op_parameter){ .fallthrough = true, __VA_ARGS__ })
void(jabs_opN)(struct op_parameter par);
#define jrel_op00(...) jrel_opN((struct op_parameter){ __VA_ARGS__ })
#define jrel_op0(...) jrel_opN((struct op_parameter){ .pop = 0, .push = 0, .conditional = false, .fallthrough = true, __VA_ARGS__ })
#define jrel_op(...) jrel_opN((struct op_parameter){ .fallthrough = true, __VA_ARGS__ })
void(jrel_opN)(struct op_parameter par);
#define nargs_op(...) nargs_op((struct op_parameter){ __VA_ARGS__ })
#define nargs_op0(...) nargs_op((struct op_parameter){ .pop = -2, .push = -2, __VA_ARGS__ })
void(nargs_op)(struct op_parameter par);
#define rm_op(...) rm_op((struct op_parameter){ __VA_ARGS__ })
void(rm_op)(struct op_parameter par);
#endif