radare2/libr/include/r_arch.h
2023-02-02 17:49:11 +01:00

281 lines
9.4 KiB
C

/* radare2 - LGPL - Copyright 2022-2023 - pancake, condret */
#ifndef R2_ARCH_H
#define R2_ARCH_H
#include <r_util.h>
#include <r_bin.h>
#include <r_reg.h>
// Rename to R_ARCH_VALTYPE_*
typedef enum {
R_ANAL_VAL_REG,
R_ANAL_VAL_MEM,
R_ANAL_VAL_IMM,
} RArchValueType;
#define RAnalValueType RArchValueType
#define USE_REG_NAMES 0
// base + reg + regdelta * mul + delta
typedef struct r_arch_value_t {
RArchValueType type;
int access; // rename to `perm` and use R_PERM_R | _W | _X
int absolute; // if true, unsigned cast is used
int memref; // is memory reference? which size? 1, 2 ,4, 8
ut64 base ; // numeric address
st64 delta; // numeric delta
st64 imm; // immediate value
int mul; // multiplier (reg*4+base)
#if USE_REG_NAMES
const char *seg;
const char *reg;
const char *regdelta;
#else
// XXX can be invalidated if regprofile changes causing an UAF
RRegItem *seg; // segment selector register
RRegItem *reg; // register item reference
RRegItem *regdelta; // register index used
#endif
} RArchValue;
#include <r_anal/op.h>
#ifdef __cplusplus
extern "C" {
#endif
R_LIB_VERSION_HEADER (r_arch);
#include <r_util.h>
struct r_reg_item_t;
struct r_reg_t;
#include <r_reg.h>
#include <r_io.h>
#include <sdb/sdb.h>
enum {
R_ARCH_SYNTAX_NONE = 0,
R_ARCH_SYNTAX_INTEL,
R_ARCH_SYNTAX_ATT,
R_ARCH_SYNTAX_MASM,
R_ARCH_SYNTAX_REGNUM, // alias for capstone's NOREGNAME
R_ARCH_SYNTAX_JZ, // hack to use jz instead of je on x86
};
typedef struct r_arch_config_t {
char *decoder;
char *arch;
char *cpu;
char *os;
int bits;
union {
int big_endian;
ut32 endian;
};
int syntax;
int pcalign;
int dataalign;
int addrbytes; // move from RIO->addrbytes to RArchConfig->addrbytes
int segbas;
int seggrn;
int invhex;
int bitshift;
char *abi;
R_REF_TYPE;
} RArchConfig;
#define R_ARCH_CONFIG_IS_BIG_ENDIAN(cfg_) (((cfg_)->endian & R_SYS_ENDIAN_BIG) == R_SYS_ENDIAN_BIG)
#define R_ARCH_INFO_MIN_OP_SIZE 0
#define R_ARCH_INFO_MAX_OP_SIZE 1
#define R_ARCH_INFO_INV_OP_SIZE 2
#define R_ARCH_INFO_ALIGN 4
#define R_ARCH_INFO_DATA_ALIGN 8
#define R_ARCH_INFO_JMPMID 16
typedef enum {
R_ARCH_OP_MASK_BASIC = 0, // Just fills basic op info , it's fast
R_ARCH_OP_MASK_ESIL = 1, // It fills RAnalop->esil info
R_ARCH_OP_MASK_VAL = 2, // It fills RAnalop->dst/src info
R_ARCH_OP_MASK_HINT = 4, // It calls r_anal_op_hint to override anal options
R_ARCH_OP_MASK_OPEX = 8, // It fills RAnalop->opex info
R_ARCH_OP_MASK_DISASM = 16, // It fills RAnalop->mnemonic // should be RAnalOp->disasm // only from r_core_anal_op()
R_ARCH_OP_MASK_ALL = 1 | 2 | 4 | 8 | 16
} RAnalOpMask;
#if 0
// XXX R2_590 - backward compatible, shouldnt be used
#define R_ANAL_OP_MASK_BASIC 0, // Just fills basic op info , it's fast
#define R_ANAL_OP_MASK_ESIL 1, // It fills RAnalop->esil info
#define R_ANAL_OP_MASK_VAL 2, // It fills RAnalop->dst/src info
#define R_ANAL_OP_MASK_HINT 4, // It calls r_anal_op_hint to override anal options
#define R_ANAL_OP_MASK_OPEX 8, // It fills RAnalop->opex info
#define R_ANAL_OP_MASK_DISASM 16, // It fills RAnalop->mnemonic // should be RAnalOp->disasm // only from r_core_anal_op()
#define R_ANAL_OP_MASK_ALL (1 | 2 | 4 | 8 | 16)
#endif
typedef struct r_arch_t {
RList *plugins; // all plugins
RBinBind binb; // required for java, dalvik, wasm, pickle and pyc plugin... pending refactor
RNum *num; // XXX maybe not required
struct r_arch_session_t *session;
RArchConfig *cfg; // global / default config
} RArch;
typedef struct r_arch_session_t {
struct r_arch_t *arch;
struct r_arch_plugin_t *plugin;
RArchConfig *config; // TODO remove arch->config!
void *data;
void *user;
R_REF_TYPE;
} RArchSession;
typedef ut32 RArchDecodeMask;
typedef ut32 RArchEncodeMask; // syntax ?
typedef ut32 RArchModifyMask; // syntax ?
typedef int (*RArchPluginInfoCallback)(RArchSession *cfg, ut32 query);
typedef char *(*RArchPluginRegistersCallback)(RArchSession *ai);
typedef char *(*RArchPluginMnemonicsCallback)(RArchSession *s, int id, bool json);
typedef bool (*RArchPluginDecodeCallback)(RArchSession *s, struct r_anal_op_t *op, RArchDecodeMask mask);
typedef bool (*RArchPluginEncodeCallback)(RArchSession *s, struct r_anal_op_t *op, RArchEncodeMask mask);
typedef bool (*RArchPluginModifyCallback)(RArchSession *s, struct r_anal_op_t *op, RArchModifyMask mask);
typedef RList *(*RArchPluginPreludesCallback)(RArchSession *s);
typedef bool (*RArchPluginInitCallback)(RArchSession *s);
typedef bool (*RArchPluginFiniCallback)(RArchSession *s);
// TODO: use `const char *const` instead of `char*`
typedef struct r_arch_plugin_t {
// RPluginMeta meta; // = { .name = ... }
char *name;
char *desc;
char *author;
char *version;
char *license;
// all const
char *arch;
char *cpus;
ut32 endian;
RSysBits bits;
RSysBits addr_bits;
RArchPluginInitCallback init;
RArchPluginInitCallback fini;
RArchPluginInfoCallback info;
RArchPluginRegistersCallback regs;
RArchPluginEncodeCallback encode;
RArchPluginDecodeCallback decode;
RArchPluginModifyCallback patch;
RArchPluginMnemonicsCallback mnemonics;
RArchPluginPreludesCallback preludes;
//TODO: reenable this later? maybe it should be called reset() or setenv().. but esilinit/fini
// seems to specific to esil and those functions may want to do moreo things like io stuff
// bool (*esil_init)(REsil *esil);
// void (*esil_fini)(REsil *esil);
} RArchPlugin;
// decoder.c
//dname is name of decoder to use, NULL if current
R_API bool r_arch_load_decoder(RArch *arch, const char *dname);
R_API bool r_arch_use_decoder(RArch *arch, const char *dname);
R_API bool r_arch_unload_decoder(RArch *arch, const char *dname);
// deprecate
R_API int r_arch_info(RArch *arch, int query);
R_API bool r_arch_decode(RArch *a, RAnalOp *op, RArchDecodeMask mask);
R_API bool r_arch_encode(RArch *a, RAnalOp *op, RArchEncodeMask mask);
//R_API bool r_arch_esil_init(RArch *arch, const char *dname, REsil *esil);
//R_API void r_arch_esil_fini(RArch *arch, const char *dname, REsil *esil);
R_API RArchSession *r_arch_session(RArch *arch, RArchConfig *cfg, RArchPlugin *ap);
R_API bool r_arch_session_decode(RArchSession *ai, RAnalOp *op, RArchDecodeMask mask);
R_API bool r_arch_session_encode(RArchSession *ai, RAnalOp *op, RArchEncodeMask mask);
R_API bool r_arch_session_patch(RArchSession *ai, RAnalOp *op, RArchModifyMask mask);
R_API int r_arch_session_info(RArchSession *ai, int q);
R_API RList *r_arch_session_preludes(RArchSession *ai);
// arch.c
R_API RArch *r_arch_new(void);
R_API bool r_arch_use(RArch *arch, RArchConfig *config, const char *name);
// arch plugins management apis
R_API bool r_arch_add(RArch *arch, RArchPlugin *ap);
R_API bool r_arch_del(RArch *arch, const char *name);
R_API void r_arch_free(RArch *arch);
// deprecate
R_API bool r_arch_set_bits(RArch *arch, ut32 bits);
R_API bool r_arch_set_endian(RArch *arch, ut32 endian);
R_API bool r_arch_set_arch(RArch *arch, char *archname);
// aconfig.c
R_API void r_arch_config_use(RArchConfig *config, R_NULLABLE const char *arch);
R_API void r_arch_config_set_cpu(RArchConfig *config, R_NULLABLE const char *cpu);
R_API bool r_arch_config_set_syntax(RArchConfig *config, int syntax);
R_API bool r_arch_config_set_bits(RArchConfig *c, int bits);
R_API RArchConfig *r_arch_config_new(void);
R_API RArchConfig *r_arch_config_clone(RArchConfig *c);
R_API void r_arch_config_free(RArchConfig *);
// backward compat
#define RAnalValue RArchValue
R_API RArchValue *r_arch_value_new(void);
#if 0
// switchop
R_API RArchSwitchOp *r_arch_switch_op_new(ut64 addr, ut64 min_val, ut64 max_val, ut64 def_val);
R_API RArchCaseOp *r_arch_case_op_new(ut64 addr, ut64 val, ut64 jump);
R_API void r_arch_switch_op_free(RArchSwitchOp *swop);
R_API RArchCaseOp* r_arch_switch_op_add_case(RArchSwitchOp *swop, ut64 addr, ut64 value, ut64 jump);
// archvalue.c
R_API RArchValue *r_arch_value_copy(RArchValue *ov);
R_API void r_arch_value_free(RArchValue *value);
R_API ut64 r_arch_value_to_ut64(RArchValue *val, struct r_reg_t *reg);
R_API bool r_arch_value_set_ut64(RArchValue *val, struct r_reg_t *reg, RIOBind *iob, ut64 num);
R_API char *r_arch_value_tostring(RArchValue *value);
R_API RAnalOp *r_arch_op_new(void);
R_API void r_arch_op_init(RAnalOp *op);
R_API void r_arch_op_fini(RAnalOp *op);
R_API void r_arch_op_free(void *_op);
#endif
R_API int r_arch_optype_from_string(const char *type);
R_API const char *r_arch_optype_tostring(int t);
R_API const char *r_arch_stackop_tostring(int s);
R_API const char *r_arch_op_family_tostring(int n);
R_API int r_arch_op_family_from_string(const char *f);
R_API const char *r_arch_op_direction_tostring(struct r_anal_op_t *op);
extern RArchPlugin r_arch_plugin_null;
extern RArchPlugin r_arch_plugin_i4004;
extern RArchPlugin r_arch_plugin_amd29k;
extern RArchPlugin r_arch_plugin_jdh8;
extern RArchPlugin r_arch_plugin_pickle;
extern RArchPlugin r_arch_plugin_sh;
extern RArchPlugin r_arch_plugin_v810;
extern RArchPlugin r_arch_plugin_rsp;
extern RArchPlugin r_arch_plugin_riscv;
extern RArchPlugin r_arch_plugin_any_as;
extern RArchPlugin r_arch_plugin_any_vasm;
extern RArchPlugin r_arch_plugin_arm;
extern RArchPlugin r_arch_plugin_x86_nz;
extern RArchPlugin r_arch_plugin_x86_nasm;
extern RArchPlugin r_arch_plugin_snes;
extern RArchPlugin r_arch_plugin_6502;
extern RArchPlugin r_arch_plugin_xap;
extern RArchPlugin r_arch_plugin_v850;
extern RArchPlugin r_arch_plugin_propeller;
extern RArchPlugin r_arch_plugin_mcore;
extern RArchPlugin r_arch_plugin_nios2;
extern RArchPlugin r_arch_plugin_or1k;
extern RArchPlugin r_arch_plugin_evm;
#ifdef __cplusplus
}
#endif
#endif