import
This commit is contained in:
20
include/hook.h
Normal file
20
include/hook.h
Normal file
@@ -0,0 +1,20 @@
|
||||
/* Unicorn Emulator Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2015 */
|
||||
|
||||
#ifndef UC_HOOK_H
|
||||
#define UC_HOOK_H
|
||||
|
||||
// return -1 on failure, index to traces[] on success.
|
||||
size_t hook_add(uch handle, int type, uint64_t begin, uint64_t end, void *callback, void *user_data);
|
||||
|
||||
// return 0 on success, -1 on failure
|
||||
uc_err hook_del(uch handle, uch *traceh);
|
||||
|
||||
// return NULL on failure
|
||||
struct hook_struct *hook_find(uch handle, int type, uint64_t address);
|
||||
|
||||
// return index of an free hook entry in hook_callbacks[] array.
|
||||
// this realloc memory if needed.
|
||||
size_t hook_find_new(struct uc_struct *uc);
|
||||
|
||||
#endif
|
||||
54
include/qemu.h
Normal file
54
include/qemu.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* By Dang Hoang Vu <dang.hvu -at- gmail.com>, 2015 */
|
||||
|
||||
#ifndef UC_QEMU_H
|
||||
#define UC_QEMU_H
|
||||
|
||||
struct uc_struct;
|
||||
|
||||
#define OPC_BUF_SIZE 640
|
||||
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "sysemu/cpus.h"
|
||||
#include "exec/cpu-common.h"
|
||||
#include "exec/memory.h"
|
||||
|
||||
#include "qemu/thread.h"
|
||||
#include "include/qom/cpu.h"
|
||||
#include "exec/spinlock.h"
|
||||
|
||||
#include "vl.h"
|
||||
|
||||
// This two struct is originally from qemu/include/exec/cpu-all.h
|
||||
// Temporarily moved here since there is circular inclusion.
|
||||
typedef struct RAMBlock {
|
||||
struct MemoryRegion *mr;
|
||||
uint8_t *host;
|
||||
ram_addr_t offset;
|
||||
ram_addr_t length;
|
||||
uint32_t flags;
|
||||
char idstr[256];
|
||||
/* Reads can take either the iothread or the ramlist lock.
|
||||
* Writes must take both locks.
|
||||
*/
|
||||
QTAILQ_ENTRY(RAMBlock) next;
|
||||
int fd;
|
||||
} RAMBlock;
|
||||
|
||||
typedef struct {
|
||||
MemoryRegion *mr;
|
||||
void *buffer;
|
||||
hwaddr addr;
|
||||
hwaddr len;
|
||||
} BounceBuffer;
|
||||
|
||||
typedef struct RAMList {
|
||||
QemuMutex mutex;
|
||||
/* Protected by the iothread lock. */
|
||||
unsigned long *dirty_memory[DIRTY_MEMORY_NUM];
|
||||
RAMBlock *mru_block;
|
||||
/* Protected by the ramlist lock. */
|
||||
QTAILQ_HEAD(, RAMBlock) blocks;
|
||||
uint32_t version;
|
||||
} RAMList;
|
||||
|
||||
#endif
|
||||
13
include/qemu_macro.h
Normal file
13
include/qemu_macro.h
Normal file
@@ -0,0 +1,13 @@
|
||||
/* By Dang Hoang Vu <dang.hvu -at- gmail.com>, 2015 */
|
||||
|
||||
#ifndef UC_QEMU_MACRO_H
|
||||
#define UC_QEMU_MACRO_H
|
||||
|
||||
#define CPU_NEXT(cpu) QTAILQ_NEXT(cpu, node)
|
||||
#define CPU_FOREACH(cpu) QTAILQ_FOREACH(cpu, &uc->cpus, node)
|
||||
#define CPU_FOREACH_SAFE(cpu, next_cpu) \
|
||||
QTAILQ_FOREACH_SAFE(cpu, &cpu->uc->cpus, node, next_cpu)
|
||||
#define first_cpu QTAILQ_FIRST(&uc->cpus)
|
||||
|
||||
#endif
|
||||
|
||||
170
include/uc_priv.h
Normal file
170
include/uc_priv.h
Normal file
@@ -0,0 +1,170 @@
|
||||
/* Unicorn Emulator Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2015 */
|
||||
|
||||
#ifndef UC_PRIV_H
|
||||
#define UC_PRIV_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "qemu.h"
|
||||
#include "unicorn/unicorn.h"
|
||||
#include "hook.h"
|
||||
|
||||
#define ARR_SIZE(a) (sizeof(a)/sizeof(a[0]))
|
||||
|
||||
QTAILQ_HEAD(CPUTailQ, CPUState);
|
||||
|
||||
typedef struct ModuleEntry {
|
||||
void (*init)(void);
|
||||
QTAILQ_ENTRY(ModuleEntry) node;
|
||||
module_init_type type;
|
||||
} ModuleEntry;
|
||||
|
||||
typedef QTAILQ_HEAD(, ModuleEntry) ModuleTypeList;
|
||||
|
||||
// return 0 on success, -1 on failure
|
||||
typedef int (*reg_access_t)(uch handle, unsigned int regid, void *value);
|
||||
|
||||
typedef void (*reg_reset_t)(uch handle);
|
||||
|
||||
typedef bool (*uc_write_mem_t)(AddressSpace *as, hwaddr addr, uint8_t *buf, int len);
|
||||
|
||||
typedef bool (*uc_read_mem_t)(AddressSpace *as, hwaddr addr, uint8_t *buf, int len);
|
||||
|
||||
typedef void (*uc_args_void_t)(void*);
|
||||
|
||||
typedef void (*uc_args_uc_t)(struct uc_struct*);
|
||||
|
||||
typedef bool (*uc_args_tcg_enable_t)(struct uc_struct*);
|
||||
|
||||
typedef void (*uc_minit_t)(struct uc_struct*, ram_addr_t);
|
||||
|
||||
typedef void (*uc_args_uc_long_t)(struct uc_struct*, unsigned long);
|
||||
|
||||
typedef void (*uc_args_uc_u64_t)(struct uc_struct *, uint64_t addr);
|
||||
|
||||
typedef int (*uc_args_uc_ram_size_t)(struct uc_struct*, ram_addr_t begin, size_t size);
|
||||
|
||||
// which interrupt should make emulation stop?
|
||||
typedef bool (*uc_args_int_t)(int intno);
|
||||
|
||||
|
||||
struct hook_struct {
|
||||
int hook_type; // uc_tracecode_type & uc_tracemem_type
|
||||
uint64_t begin, end; // range of address to be monitored
|
||||
void *callback; // either uc_cb_tracecode_t or uc_cb_tracemem_t
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
// extend memory to keep 32 more hooks each time
|
||||
#define HOOK_SIZE 32
|
||||
|
||||
struct uc_struct {
|
||||
uc_arch arch;
|
||||
uc_mode mode;
|
||||
QemuMutex qemu_global_mutex; // qemu/cpus.c
|
||||
QemuCond qemu_cpu_cond; // qemu/cpus.c
|
||||
QemuThread *tcg_cpu_thread; // qemu/cpus.c
|
||||
QemuCond *tcg_halt_cond; // qemu/cpus.c
|
||||
struct CPUTailQ cpus; // qemu/cpu-exec.c
|
||||
uc_err errnum; // qemu/cpu-exec.c
|
||||
AddressSpace as;
|
||||
reg_access_t reg_read, reg_write;
|
||||
reg_reset_t reg_reset;
|
||||
|
||||
uc_write_mem_t write_mem;
|
||||
uc_read_mem_t read_mem;
|
||||
uc_args_void_t release; // release resource when uc_close()
|
||||
uc_args_uc_u64_t set_pc; // set PC for tracecode
|
||||
uc_args_int_t stop_interrupt; // check if the interrupt should stop emulation
|
||||
|
||||
uc_args_uc_t init_arch, pause_all_vcpus, vm_start, cpu_exec_init_all;
|
||||
uc_args_tcg_enable_t tcg_enabled;
|
||||
uc_args_uc_long_t tcg_exec_init;
|
||||
uc_args_uc_ram_size_t memory_map;
|
||||
// list of cpu
|
||||
void* cpu;
|
||||
|
||||
MemoryRegion *system_memory; // qemu/exec.c
|
||||
MemoryRegion *ram;
|
||||
MemoryRegion io_mem_rom; // qemu/exec.c
|
||||
MemoryRegion io_mem_notdirty; // qemu/exec.c
|
||||
MemoryRegion io_mem_unassigned; // qemu/exec.c
|
||||
MemoryRegion io_mem_watch; // qemu/exec.c
|
||||
RAMList ram_list; // qemu/exec.c
|
||||
CPUState *next_cpu; // qemu/cpus.c
|
||||
BounceBuffer bounce; // qemu/cpu-exec.c
|
||||
volatile sig_atomic_t exit_request; // qemu/cpu-exec.c
|
||||
spinlock_t x86_global_cpu_lock; // for X86 arch only
|
||||
bool global_dirty_log; // qemu/memory.c
|
||||
/* This is a multi-level map on the virtual address space.
|
||||
The bottom level has pointers to PageDesc. */
|
||||
void *l1_map; // qemu/translate-all.c
|
||||
size_t l1_map_size;
|
||||
/* code generation context */
|
||||
void *tcg_ctx; // for "TCGContext tcg_ctx" in qemu/translate-all.c
|
||||
/* memory.c */
|
||||
unsigned memory_region_transaction_depth;
|
||||
bool memory_region_update_pending;
|
||||
bool ioeventfd_update_pending;
|
||||
QemuMutex flat_view_mutex;
|
||||
QTAILQ_HEAD(memory_listeners, MemoryListener) memory_listeners;
|
||||
QTAILQ_HEAD(, AddressSpace) address_spaces;
|
||||
// qom/object.c
|
||||
GHashTable *type_table;
|
||||
Type type_interface;
|
||||
Object *root;
|
||||
bool enumerating_types;
|
||||
// util/module.c
|
||||
ModuleTypeList init_type_list[MODULE_INIT_MAX];
|
||||
// hw/intc/apic_common.c
|
||||
DeviceState *vapic;
|
||||
int apic_no;
|
||||
bool mmio_registered;
|
||||
bool apic_report_tpr_access;
|
||||
CPUState *current_cpu;
|
||||
|
||||
// all the hook callbacks
|
||||
size_t hook_size;
|
||||
struct hook_struct *hook_callbacks;
|
||||
|
||||
// hook to count number of instructions for uc_emu_start()
|
||||
struct hook_struct hook_count;
|
||||
uc_cb_hookcode_t hook_count_callback;
|
||||
|
||||
size_t emu_counter; // current counter of uc_emu_start()
|
||||
size_t emu_count; // save counter of uc_emu_start()
|
||||
|
||||
// indexes if hooking ALL block/code/read/write events
|
||||
unsigned int hook_block_idx, hook_insn_idx, hook_read_idx, hook_write_idx;
|
||||
// boolean variables for quick check on hooking block, code, memory accesses
|
||||
bool hook_block, hook_insn, hook_mem_read, hook_mem_write;
|
||||
uint64_t block_addr; // save the last block address we hooked
|
||||
// indexes to event callbacks
|
||||
int hook_mem_idx; // for handling invalid memory access
|
||||
int hook_intr_idx; // for handling interrupt
|
||||
int hook_out_idx; // for handling OUT instruction (X86)
|
||||
int hook_in_idx; // for handling IN instruction (X86)
|
||||
|
||||
|
||||
bool init_tcg; // already initialized local TCGv variables?
|
||||
bool stop_request; // request to immediately stop emulation - for uc_emu_stop()
|
||||
bool emulation_done; // emulation is done by uc_emu_start()
|
||||
QemuThread timer; // timer for emulation timeout
|
||||
uint64_t timeout; // timeout for uc_emu_start()
|
||||
|
||||
uint64_t invalid_addr; // invalid address to be accessed
|
||||
int invalid_error; // invalid memory code: 1 = READ, 2 = WRITE, 3 = CODE
|
||||
|
||||
uint64_t addr_end; // address where emulation stops (@end param of uc_emu_start())
|
||||
|
||||
int thumb; // thumb mode for ARM
|
||||
};
|
||||
|
||||
#include "qemu_macro.h"
|
||||
|
||||
// check if this address is mapped in (via uc_mem_map())
|
||||
bool memory_mapping(uint64_t address);
|
||||
|
||||
#endif
|
||||
146
include/unicorn/arm.h
Normal file
146
include/unicorn/arm.h
Normal file
@@ -0,0 +1,146 @@
|
||||
#ifndef UNICORN_ARM_H
|
||||
#define UNICORN_ARM_H
|
||||
|
||||
/* Unicorn Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2015 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
//> ARM registers
|
||||
typedef enum arm_reg {
|
||||
ARM_REG_INVALID = 0,
|
||||
ARM_REG_APSR,
|
||||
ARM_REG_APSR_NZCV,
|
||||
ARM_REG_CPSR,
|
||||
ARM_REG_FPEXC,
|
||||
ARM_REG_FPINST,
|
||||
ARM_REG_FPSCR,
|
||||
ARM_REG_FPSCR_NZCV,
|
||||
ARM_REG_FPSID,
|
||||
ARM_REG_ITSTATE,
|
||||
ARM_REG_LR,
|
||||
ARM_REG_PC,
|
||||
ARM_REG_SP,
|
||||
ARM_REG_SPSR,
|
||||
ARM_REG_D0,
|
||||
ARM_REG_D1,
|
||||
ARM_REG_D2,
|
||||
ARM_REG_D3,
|
||||
ARM_REG_D4,
|
||||
ARM_REG_D5,
|
||||
ARM_REG_D6,
|
||||
ARM_REG_D7,
|
||||
ARM_REG_D8,
|
||||
ARM_REG_D9,
|
||||
ARM_REG_D10,
|
||||
ARM_REG_D11,
|
||||
ARM_REG_D12,
|
||||
ARM_REG_D13,
|
||||
ARM_REG_D14,
|
||||
ARM_REG_D15,
|
||||
ARM_REG_D16,
|
||||
ARM_REG_D17,
|
||||
ARM_REG_D18,
|
||||
ARM_REG_D19,
|
||||
ARM_REG_D20,
|
||||
ARM_REG_D21,
|
||||
ARM_REG_D22,
|
||||
ARM_REG_D23,
|
||||
ARM_REG_D24,
|
||||
ARM_REG_D25,
|
||||
ARM_REG_D26,
|
||||
ARM_REG_D27,
|
||||
ARM_REG_D28,
|
||||
ARM_REG_D29,
|
||||
ARM_REG_D30,
|
||||
ARM_REG_D31,
|
||||
ARM_REG_FPINST2,
|
||||
ARM_REG_MVFR0,
|
||||
ARM_REG_MVFR1,
|
||||
ARM_REG_MVFR2,
|
||||
ARM_REG_Q0,
|
||||
ARM_REG_Q1,
|
||||
ARM_REG_Q2,
|
||||
ARM_REG_Q3,
|
||||
ARM_REG_Q4,
|
||||
ARM_REG_Q5,
|
||||
ARM_REG_Q6,
|
||||
ARM_REG_Q7,
|
||||
ARM_REG_Q8,
|
||||
ARM_REG_Q9,
|
||||
ARM_REG_Q10,
|
||||
ARM_REG_Q11,
|
||||
ARM_REG_Q12,
|
||||
ARM_REG_Q13,
|
||||
ARM_REG_Q14,
|
||||
ARM_REG_Q15,
|
||||
ARM_REG_R0,
|
||||
ARM_REG_R1,
|
||||
ARM_REG_R2,
|
||||
ARM_REG_R3,
|
||||
ARM_REG_R4,
|
||||
ARM_REG_R5,
|
||||
ARM_REG_R6,
|
||||
ARM_REG_R7,
|
||||
ARM_REG_R8,
|
||||
ARM_REG_R9,
|
||||
ARM_REG_R10,
|
||||
ARM_REG_R11,
|
||||
ARM_REG_R12,
|
||||
ARM_REG_S0,
|
||||
ARM_REG_S1,
|
||||
ARM_REG_S2,
|
||||
ARM_REG_S3,
|
||||
ARM_REG_S4,
|
||||
ARM_REG_S5,
|
||||
ARM_REG_S6,
|
||||
ARM_REG_S7,
|
||||
ARM_REG_S8,
|
||||
ARM_REG_S9,
|
||||
ARM_REG_S10,
|
||||
ARM_REG_S11,
|
||||
ARM_REG_S12,
|
||||
ARM_REG_S13,
|
||||
ARM_REG_S14,
|
||||
ARM_REG_S15,
|
||||
ARM_REG_S16,
|
||||
ARM_REG_S17,
|
||||
ARM_REG_S18,
|
||||
ARM_REG_S19,
|
||||
ARM_REG_S20,
|
||||
ARM_REG_S21,
|
||||
ARM_REG_S22,
|
||||
ARM_REG_S23,
|
||||
ARM_REG_S24,
|
||||
ARM_REG_S25,
|
||||
ARM_REG_S26,
|
||||
ARM_REG_S27,
|
||||
ARM_REG_S28,
|
||||
ARM_REG_S29,
|
||||
ARM_REG_S30,
|
||||
ARM_REG_S31,
|
||||
|
||||
ARM_REG_ENDING, // <-- mark the end of the list or registers
|
||||
|
||||
//> alias registers
|
||||
ARM_REG_R13 = ARM_REG_SP,
|
||||
ARM_REG_R14 = ARM_REG_LR,
|
||||
ARM_REG_R15 = ARM_REG_PC,
|
||||
|
||||
ARM_REG_SB = ARM_REG_R9,
|
||||
ARM_REG_SL = ARM_REG_R10,
|
||||
ARM_REG_FP = ARM_REG_R11,
|
||||
ARM_REG_IP = ARM_REG_R12,
|
||||
} arm_reg;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
297
include/unicorn/arm64.h
Normal file
297
include/unicorn/arm64.h
Normal file
@@ -0,0 +1,297 @@
|
||||
#ifndef UNICORN_ARM64_H
|
||||
#define UNICORN_ARM64_H
|
||||
|
||||
/* Unicorn Emulator Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2015 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
//> ARM64 registers
|
||||
typedef enum arm64_reg {
|
||||
ARM64_REG_INVALID = 0,
|
||||
|
||||
ARM64_REG_X29,
|
||||
ARM64_REG_X30,
|
||||
ARM64_REG_NZCV,
|
||||
ARM64_REG_SP,
|
||||
ARM64_REG_WSP,
|
||||
ARM64_REG_WZR,
|
||||
ARM64_REG_XZR,
|
||||
ARM64_REG_B0,
|
||||
ARM64_REG_B1,
|
||||
ARM64_REG_B2,
|
||||
ARM64_REG_B3,
|
||||
ARM64_REG_B4,
|
||||
ARM64_REG_B5,
|
||||
ARM64_REG_B6,
|
||||
ARM64_REG_B7,
|
||||
ARM64_REG_B8,
|
||||
ARM64_REG_B9,
|
||||
ARM64_REG_B10,
|
||||
ARM64_REG_B11,
|
||||
ARM64_REG_B12,
|
||||
ARM64_REG_B13,
|
||||
ARM64_REG_B14,
|
||||
ARM64_REG_B15,
|
||||
ARM64_REG_B16,
|
||||
ARM64_REG_B17,
|
||||
ARM64_REG_B18,
|
||||
ARM64_REG_B19,
|
||||
ARM64_REG_B20,
|
||||
ARM64_REG_B21,
|
||||
ARM64_REG_B22,
|
||||
ARM64_REG_B23,
|
||||
ARM64_REG_B24,
|
||||
ARM64_REG_B25,
|
||||
ARM64_REG_B26,
|
||||
ARM64_REG_B27,
|
||||
ARM64_REG_B28,
|
||||
ARM64_REG_B29,
|
||||
ARM64_REG_B30,
|
||||
ARM64_REG_B31,
|
||||
ARM64_REG_D0,
|
||||
ARM64_REG_D1,
|
||||
ARM64_REG_D2,
|
||||
ARM64_REG_D3,
|
||||
ARM64_REG_D4,
|
||||
ARM64_REG_D5,
|
||||
ARM64_REG_D6,
|
||||
ARM64_REG_D7,
|
||||
ARM64_REG_D8,
|
||||
ARM64_REG_D9,
|
||||
ARM64_REG_D10,
|
||||
ARM64_REG_D11,
|
||||
ARM64_REG_D12,
|
||||
ARM64_REG_D13,
|
||||
ARM64_REG_D14,
|
||||
ARM64_REG_D15,
|
||||
ARM64_REG_D16,
|
||||
ARM64_REG_D17,
|
||||
ARM64_REG_D18,
|
||||
ARM64_REG_D19,
|
||||
ARM64_REG_D20,
|
||||
ARM64_REG_D21,
|
||||
ARM64_REG_D22,
|
||||
ARM64_REG_D23,
|
||||
ARM64_REG_D24,
|
||||
ARM64_REG_D25,
|
||||
ARM64_REG_D26,
|
||||
ARM64_REG_D27,
|
||||
ARM64_REG_D28,
|
||||
ARM64_REG_D29,
|
||||
ARM64_REG_D30,
|
||||
ARM64_REG_D31,
|
||||
ARM64_REG_H0,
|
||||
ARM64_REG_H1,
|
||||
ARM64_REG_H2,
|
||||
ARM64_REG_H3,
|
||||
ARM64_REG_H4,
|
||||
ARM64_REG_H5,
|
||||
ARM64_REG_H6,
|
||||
ARM64_REG_H7,
|
||||
ARM64_REG_H8,
|
||||
ARM64_REG_H9,
|
||||
ARM64_REG_H10,
|
||||
ARM64_REG_H11,
|
||||
ARM64_REG_H12,
|
||||
ARM64_REG_H13,
|
||||
ARM64_REG_H14,
|
||||
ARM64_REG_H15,
|
||||
ARM64_REG_H16,
|
||||
ARM64_REG_H17,
|
||||
ARM64_REG_H18,
|
||||
ARM64_REG_H19,
|
||||
ARM64_REG_H20,
|
||||
ARM64_REG_H21,
|
||||
ARM64_REG_H22,
|
||||
ARM64_REG_H23,
|
||||
ARM64_REG_H24,
|
||||
ARM64_REG_H25,
|
||||
ARM64_REG_H26,
|
||||
ARM64_REG_H27,
|
||||
ARM64_REG_H28,
|
||||
ARM64_REG_H29,
|
||||
ARM64_REG_H30,
|
||||
ARM64_REG_H31,
|
||||
ARM64_REG_Q0,
|
||||
ARM64_REG_Q1,
|
||||
ARM64_REG_Q2,
|
||||
ARM64_REG_Q3,
|
||||
ARM64_REG_Q4,
|
||||
ARM64_REG_Q5,
|
||||
ARM64_REG_Q6,
|
||||
ARM64_REG_Q7,
|
||||
ARM64_REG_Q8,
|
||||
ARM64_REG_Q9,
|
||||
ARM64_REG_Q10,
|
||||
ARM64_REG_Q11,
|
||||
ARM64_REG_Q12,
|
||||
ARM64_REG_Q13,
|
||||
ARM64_REG_Q14,
|
||||
ARM64_REG_Q15,
|
||||
ARM64_REG_Q16,
|
||||
ARM64_REG_Q17,
|
||||
ARM64_REG_Q18,
|
||||
ARM64_REG_Q19,
|
||||
ARM64_REG_Q20,
|
||||
ARM64_REG_Q21,
|
||||
ARM64_REG_Q22,
|
||||
ARM64_REG_Q23,
|
||||
ARM64_REG_Q24,
|
||||
ARM64_REG_Q25,
|
||||
ARM64_REG_Q26,
|
||||
ARM64_REG_Q27,
|
||||
ARM64_REG_Q28,
|
||||
ARM64_REG_Q29,
|
||||
ARM64_REG_Q30,
|
||||
ARM64_REG_Q31,
|
||||
ARM64_REG_S0,
|
||||
ARM64_REG_S1,
|
||||
ARM64_REG_S2,
|
||||
ARM64_REG_S3,
|
||||
ARM64_REG_S4,
|
||||
ARM64_REG_S5,
|
||||
ARM64_REG_S6,
|
||||
ARM64_REG_S7,
|
||||
ARM64_REG_S8,
|
||||
ARM64_REG_S9,
|
||||
ARM64_REG_S10,
|
||||
ARM64_REG_S11,
|
||||
ARM64_REG_S12,
|
||||
ARM64_REG_S13,
|
||||
ARM64_REG_S14,
|
||||
ARM64_REG_S15,
|
||||
ARM64_REG_S16,
|
||||
ARM64_REG_S17,
|
||||
ARM64_REG_S18,
|
||||
ARM64_REG_S19,
|
||||
ARM64_REG_S20,
|
||||
ARM64_REG_S21,
|
||||
ARM64_REG_S22,
|
||||
ARM64_REG_S23,
|
||||
ARM64_REG_S24,
|
||||
ARM64_REG_S25,
|
||||
ARM64_REG_S26,
|
||||
ARM64_REG_S27,
|
||||
ARM64_REG_S28,
|
||||
ARM64_REG_S29,
|
||||
ARM64_REG_S30,
|
||||
ARM64_REG_S31,
|
||||
ARM64_REG_W0,
|
||||
ARM64_REG_W1,
|
||||
ARM64_REG_W2,
|
||||
ARM64_REG_W3,
|
||||
ARM64_REG_W4,
|
||||
ARM64_REG_W5,
|
||||
ARM64_REG_W6,
|
||||
ARM64_REG_W7,
|
||||
ARM64_REG_W8,
|
||||
ARM64_REG_W9,
|
||||
ARM64_REG_W10,
|
||||
ARM64_REG_W11,
|
||||
ARM64_REG_W12,
|
||||
ARM64_REG_W13,
|
||||
ARM64_REG_W14,
|
||||
ARM64_REG_W15,
|
||||
ARM64_REG_W16,
|
||||
ARM64_REG_W17,
|
||||
ARM64_REG_W18,
|
||||
ARM64_REG_W19,
|
||||
ARM64_REG_W20,
|
||||
ARM64_REG_W21,
|
||||
ARM64_REG_W22,
|
||||
ARM64_REG_W23,
|
||||
ARM64_REG_W24,
|
||||
ARM64_REG_W25,
|
||||
ARM64_REG_W26,
|
||||
ARM64_REG_W27,
|
||||
ARM64_REG_W28,
|
||||
ARM64_REG_W29,
|
||||
ARM64_REG_W30,
|
||||
ARM64_REG_X0,
|
||||
ARM64_REG_X1,
|
||||
ARM64_REG_X2,
|
||||
ARM64_REG_X3,
|
||||
ARM64_REG_X4,
|
||||
ARM64_REG_X5,
|
||||
ARM64_REG_X6,
|
||||
ARM64_REG_X7,
|
||||
ARM64_REG_X8,
|
||||
ARM64_REG_X9,
|
||||
ARM64_REG_X10,
|
||||
ARM64_REG_X11,
|
||||
ARM64_REG_X12,
|
||||
ARM64_REG_X13,
|
||||
ARM64_REG_X14,
|
||||
ARM64_REG_X15,
|
||||
ARM64_REG_X16,
|
||||
ARM64_REG_X17,
|
||||
ARM64_REG_X18,
|
||||
ARM64_REG_X19,
|
||||
ARM64_REG_X20,
|
||||
ARM64_REG_X21,
|
||||
ARM64_REG_X22,
|
||||
ARM64_REG_X23,
|
||||
ARM64_REG_X24,
|
||||
ARM64_REG_X25,
|
||||
ARM64_REG_X26,
|
||||
ARM64_REG_X27,
|
||||
ARM64_REG_X28,
|
||||
|
||||
ARM64_REG_V0,
|
||||
ARM64_REG_V1,
|
||||
ARM64_REG_V2,
|
||||
ARM64_REG_V3,
|
||||
ARM64_REG_V4,
|
||||
ARM64_REG_V5,
|
||||
ARM64_REG_V6,
|
||||
ARM64_REG_V7,
|
||||
ARM64_REG_V8,
|
||||
ARM64_REG_V9,
|
||||
ARM64_REG_V10,
|
||||
ARM64_REG_V11,
|
||||
ARM64_REG_V12,
|
||||
ARM64_REG_V13,
|
||||
ARM64_REG_V14,
|
||||
ARM64_REG_V15,
|
||||
ARM64_REG_V16,
|
||||
ARM64_REG_V17,
|
||||
ARM64_REG_V18,
|
||||
ARM64_REG_V19,
|
||||
ARM64_REG_V20,
|
||||
ARM64_REG_V21,
|
||||
ARM64_REG_V22,
|
||||
ARM64_REG_V23,
|
||||
ARM64_REG_V24,
|
||||
ARM64_REG_V25,
|
||||
ARM64_REG_V26,
|
||||
ARM64_REG_V27,
|
||||
ARM64_REG_V28,
|
||||
ARM64_REG_V29,
|
||||
ARM64_REG_V30,
|
||||
ARM64_REG_V31,
|
||||
|
||||
//> pseudo registers
|
||||
ARM64_REG_PC, // program counter register
|
||||
|
||||
ARM64_REG_ENDING, // <-- mark the end of the list of registers
|
||||
|
||||
//> alias registers
|
||||
|
||||
ARM64_REG_IP1 = ARM64_REG_X16,
|
||||
ARM64_REG_IP0 = ARM64_REG_X17,
|
||||
ARM64_REG_FP = ARM64_REG_X29,
|
||||
ARM64_REG_LR = ARM64_REG_X30,
|
||||
} arm64_reg;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
50
include/unicorn/m68k.h
Normal file
50
include/unicorn/m68k.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#ifndef UNICORN_M68K_H
|
||||
#define UNICORN_M68K_H
|
||||
|
||||
/* Unicorn Emulator Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2014-2015 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
//> M68K registers
|
||||
typedef enum m68k_reg {
|
||||
M68K_REG_INVALID = 0,
|
||||
|
||||
M68K_REG_A0,
|
||||
M68K_REG_A1,
|
||||
M68K_REG_A2,
|
||||
M68K_REG_A3,
|
||||
M68K_REG_A4,
|
||||
M68K_REG_A5,
|
||||
M68K_REG_A6,
|
||||
M68K_REG_A7,
|
||||
|
||||
M68K_REG_D0,
|
||||
M68K_REG_D1,
|
||||
M68K_REG_D2,
|
||||
M68K_REG_D3,
|
||||
M68K_REG_D4,
|
||||
M68K_REG_D5,
|
||||
M68K_REG_D6,
|
||||
M68K_REG_D7,
|
||||
|
||||
M68K_REG_SR,
|
||||
M68K_REG_PC,
|
||||
|
||||
M68K_REG_ENDING, // <-- mark the end of the list of registers
|
||||
} m68k_reg;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
226
include/unicorn/mips.h
Normal file
226
include/unicorn/mips.h
Normal file
@@ -0,0 +1,226 @@
|
||||
#ifndef UNICORN_MIPS_H
|
||||
#define UNICORN_MIPS_H
|
||||
|
||||
/* Unicorn Emulator Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2015 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// GCC MIPS toolchain has a default macro called "mips" which breaks
|
||||
// compilation
|
||||
#undef mips
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
//> MIPS registers
|
||||
typedef enum mips_reg {
|
||||
MIPS_REG_INVALID = 0,
|
||||
//> General purpose registers
|
||||
MIPS_REG_PC,
|
||||
|
||||
MIPS_REG_0,
|
||||
MIPS_REG_1,
|
||||
MIPS_REG_2,
|
||||
MIPS_REG_3,
|
||||
MIPS_REG_4,
|
||||
MIPS_REG_5,
|
||||
MIPS_REG_6,
|
||||
MIPS_REG_7,
|
||||
MIPS_REG_8,
|
||||
MIPS_REG_9,
|
||||
MIPS_REG_10,
|
||||
MIPS_REG_11,
|
||||
MIPS_REG_12,
|
||||
MIPS_REG_13,
|
||||
MIPS_REG_14,
|
||||
MIPS_REG_15,
|
||||
MIPS_REG_16,
|
||||
MIPS_REG_17,
|
||||
MIPS_REG_18,
|
||||
MIPS_REG_19,
|
||||
MIPS_REG_20,
|
||||
MIPS_REG_21,
|
||||
MIPS_REG_22,
|
||||
MIPS_REG_23,
|
||||
MIPS_REG_24,
|
||||
MIPS_REG_25,
|
||||
MIPS_REG_26,
|
||||
MIPS_REG_27,
|
||||
MIPS_REG_28,
|
||||
MIPS_REG_29,
|
||||
MIPS_REG_30,
|
||||
MIPS_REG_31,
|
||||
|
||||
//> DSP registers
|
||||
MIPS_REG_DSPCCOND,
|
||||
MIPS_REG_DSPCARRY,
|
||||
MIPS_REG_DSPEFI,
|
||||
MIPS_REG_DSPOUTFLAG,
|
||||
MIPS_REG_DSPOUTFLAG16_19,
|
||||
MIPS_REG_DSPOUTFLAG20,
|
||||
MIPS_REG_DSPOUTFLAG21,
|
||||
MIPS_REG_DSPOUTFLAG22,
|
||||
MIPS_REG_DSPOUTFLAG23,
|
||||
MIPS_REG_DSPPOS,
|
||||
MIPS_REG_DSPSCOUNT,
|
||||
|
||||
//> ACC registers
|
||||
MIPS_REG_AC0,
|
||||
MIPS_REG_AC1,
|
||||
MIPS_REG_AC2,
|
||||
MIPS_REG_AC3,
|
||||
|
||||
//> COP registers
|
||||
MIPS_REG_CC0,
|
||||
MIPS_REG_CC1,
|
||||
MIPS_REG_CC2,
|
||||
MIPS_REG_CC3,
|
||||
MIPS_REG_CC4,
|
||||
MIPS_REG_CC5,
|
||||
MIPS_REG_CC6,
|
||||
MIPS_REG_CC7,
|
||||
|
||||
//> FPU registers
|
||||
MIPS_REG_F0,
|
||||
MIPS_REG_F1,
|
||||
MIPS_REG_F2,
|
||||
MIPS_REG_F3,
|
||||
MIPS_REG_F4,
|
||||
MIPS_REG_F5,
|
||||
MIPS_REG_F6,
|
||||
MIPS_REG_F7,
|
||||
MIPS_REG_F8,
|
||||
MIPS_REG_F9,
|
||||
MIPS_REG_F10,
|
||||
MIPS_REG_F11,
|
||||
MIPS_REG_F12,
|
||||
MIPS_REG_F13,
|
||||
MIPS_REG_F14,
|
||||
MIPS_REG_F15,
|
||||
MIPS_REG_F16,
|
||||
MIPS_REG_F17,
|
||||
MIPS_REG_F18,
|
||||
MIPS_REG_F19,
|
||||
MIPS_REG_F20,
|
||||
MIPS_REG_F21,
|
||||
MIPS_REG_F22,
|
||||
MIPS_REG_F23,
|
||||
MIPS_REG_F24,
|
||||
MIPS_REG_F25,
|
||||
MIPS_REG_F26,
|
||||
MIPS_REG_F27,
|
||||
MIPS_REG_F28,
|
||||
MIPS_REG_F29,
|
||||
MIPS_REG_F30,
|
||||
MIPS_REG_F31,
|
||||
|
||||
MIPS_REG_FCC0,
|
||||
MIPS_REG_FCC1,
|
||||
MIPS_REG_FCC2,
|
||||
MIPS_REG_FCC3,
|
||||
MIPS_REG_FCC4,
|
||||
MIPS_REG_FCC5,
|
||||
MIPS_REG_FCC6,
|
||||
MIPS_REG_FCC7,
|
||||
|
||||
//> AFPR128
|
||||
MIPS_REG_W0,
|
||||
MIPS_REG_W1,
|
||||
MIPS_REG_W2,
|
||||
MIPS_REG_W3,
|
||||
MIPS_REG_W4,
|
||||
MIPS_REG_W5,
|
||||
MIPS_REG_W6,
|
||||
MIPS_REG_W7,
|
||||
MIPS_REG_W8,
|
||||
MIPS_REG_W9,
|
||||
MIPS_REG_W10,
|
||||
MIPS_REG_W11,
|
||||
MIPS_REG_W12,
|
||||
MIPS_REG_W13,
|
||||
MIPS_REG_W14,
|
||||
MIPS_REG_W15,
|
||||
MIPS_REG_W16,
|
||||
MIPS_REG_W17,
|
||||
MIPS_REG_W18,
|
||||
MIPS_REG_W19,
|
||||
MIPS_REG_W20,
|
||||
MIPS_REG_W21,
|
||||
MIPS_REG_W22,
|
||||
MIPS_REG_W23,
|
||||
MIPS_REG_W24,
|
||||
MIPS_REG_W25,
|
||||
MIPS_REG_W26,
|
||||
MIPS_REG_W27,
|
||||
MIPS_REG_W28,
|
||||
MIPS_REG_W29,
|
||||
MIPS_REG_W30,
|
||||
MIPS_REG_W31,
|
||||
|
||||
MIPS_REG_HI,
|
||||
MIPS_REG_LO,
|
||||
|
||||
MIPS_REG_P0,
|
||||
MIPS_REG_P1,
|
||||
MIPS_REG_P2,
|
||||
|
||||
MIPS_REG_MPL0,
|
||||
MIPS_REG_MPL1,
|
||||
MIPS_REG_MPL2,
|
||||
|
||||
MIPS_REG_ENDING, // <-- mark the end of the list or registers
|
||||
|
||||
// alias registers
|
||||
MIPS_REG_ZERO = MIPS_REG_0,
|
||||
MIPS_REG_AT = MIPS_REG_1,
|
||||
MIPS_REG_V0 = MIPS_REG_2,
|
||||
MIPS_REG_V1 = MIPS_REG_3,
|
||||
MIPS_REG_A0 = MIPS_REG_4,
|
||||
MIPS_REG_A1 = MIPS_REG_5,
|
||||
MIPS_REG_A2 = MIPS_REG_6,
|
||||
MIPS_REG_A3 = MIPS_REG_7,
|
||||
MIPS_REG_T0 = MIPS_REG_8,
|
||||
MIPS_REG_T1 = MIPS_REG_9,
|
||||
MIPS_REG_T2 = MIPS_REG_10,
|
||||
MIPS_REG_T3 = MIPS_REG_11,
|
||||
MIPS_REG_T4 = MIPS_REG_12,
|
||||
MIPS_REG_T5 = MIPS_REG_13,
|
||||
MIPS_REG_T6 = MIPS_REG_14,
|
||||
MIPS_REG_T7 = MIPS_REG_15,
|
||||
MIPS_REG_S0 = MIPS_REG_16,
|
||||
MIPS_REG_S1 = MIPS_REG_17,
|
||||
MIPS_REG_S2 = MIPS_REG_18,
|
||||
MIPS_REG_S3 = MIPS_REG_19,
|
||||
MIPS_REG_S4 = MIPS_REG_20,
|
||||
MIPS_REG_S5 = MIPS_REG_21,
|
||||
MIPS_REG_S6 = MIPS_REG_22,
|
||||
MIPS_REG_S7 = MIPS_REG_23,
|
||||
MIPS_REG_T8 = MIPS_REG_24,
|
||||
MIPS_REG_T9 = MIPS_REG_25,
|
||||
MIPS_REG_K0 = MIPS_REG_26,
|
||||
MIPS_REG_K1 = MIPS_REG_27,
|
||||
MIPS_REG_GP = MIPS_REG_28,
|
||||
MIPS_REG_SP = MIPS_REG_29,
|
||||
MIPS_REG_FP = MIPS_REG_30, MIPS_REG_S8 = MIPS_REG_30,
|
||||
MIPS_REG_RA = MIPS_REG_31,
|
||||
|
||||
MIPS_REG_HI0 = MIPS_REG_AC0,
|
||||
MIPS_REG_HI1 = MIPS_REG_AC1,
|
||||
MIPS_REG_HI2 = MIPS_REG_AC2,
|
||||
MIPS_REG_HI3 = MIPS_REG_AC3,
|
||||
|
||||
MIPS_REG_LO0 = MIPS_REG_HI0,
|
||||
MIPS_REG_LO1 = MIPS_REG_HI1,
|
||||
MIPS_REG_LO2 = MIPS_REG_HI2,
|
||||
MIPS_REG_LO3 = MIPS_REG_HI3,
|
||||
} mips_reg;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
28
include/unicorn/platform.h
Normal file
28
include/unicorn/platform.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/* Unicorn Emulator Engine */
|
||||
/* By Axel Souchet & Nguyen Anh Quynh, 2014 */
|
||||
|
||||
// handle C99 issue (for pre-2013 VisualStudio)
|
||||
#ifndef UNICORN_PLATFORM_H
|
||||
#define UNICORN_PLATFORM_H
|
||||
|
||||
#if !defined(__MINGW32__) && !defined(__MINGW64__) && (defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64))
|
||||
// MSVC
|
||||
|
||||
// stdbool.h
|
||||
#if (_MSC_VER < 1800)
|
||||
#ifndef __cplusplus
|
||||
typedef unsigned char bool;
|
||||
#define false 0
|
||||
#define true 1
|
||||
#endif
|
||||
|
||||
#else
|
||||
// VisualStudio 2013+ -> C99 is supported
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#else // not MSVC -> C99 is supported
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
130
include/unicorn/sparc.h
Normal file
130
include/unicorn/sparc.h
Normal file
@@ -0,0 +1,130 @@
|
||||
#ifndef UNICORN_SPARC_H
|
||||
#define UNICORN_SPARC_H
|
||||
|
||||
/* Unicorn Emulator Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2014-2015 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include "platform.h"
|
||||
|
||||
// GCC SPARC toolchain has a default macro called "sparc" which breaks
|
||||
// compilation
|
||||
#undef sparc
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
//> SPARC registers
|
||||
typedef enum sparc_reg {
|
||||
SPARC_REG_INVALID = 0,
|
||||
|
||||
SPARC_REG_F0,
|
||||
SPARC_REG_F1,
|
||||
SPARC_REG_F2,
|
||||
SPARC_REG_F3,
|
||||
SPARC_REG_F4,
|
||||
SPARC_REG_F5,
|
||||
SPARC_REG_F6,
|
||||
SPARC_REG_F7,
|
||||
SPARC_REG_F8,
|
||||
SPARC_REG_F9,
|
||||
SPARC_REG_F10,
|
||||
SPARC_REG_F11,
|
||||
SPARC_REG_F12,
|
||||
SPARC_REG_F13,
|
||||
SPARC_REG_F14,
|
||||
SPARC_REG_F15,
|
||||
SPARC_REG_F16,
|
||||
SPARC_REG_F17,
|
||||
SPARC_REG_F18,
|
||||
SPARC_REG_F19,
|
||||
SPARC_REG_F20,
|
||||
SPARC_REG_F21,
|
||||
SPARC_REG_F22,
|
||||
SPARC_REG_F23,
|
||||
SPARC_REG_F24,
|
||||
SPARC_REG_F25,
|
||||
SPARC_REG_F26,
|
||||
SPARC_REG_F27,
|
||||
SPARC_REG_F28,
|
||||
SPARC_REG_F29,
|
||||
SPARC_REG_F30,
|
||||
SPARC_REG_F31,
|
||||
SPARC_REG_F32,
|
||||
SPARC_REG_F34,
|
||||
SPARC_REG_F36,
|
||||
SPARC_REG_F38,
|
||||
SPARC_REG_F40,
|
||||
SPARC_REG_F42,
|
||||
SPARC_REG_F44,
|
||||
SPARC_REG_F46,
|
||||
SPARC_REG_F48,
|
||||
SPARC_REG_F50,
|
||||
SPARC_REG_F52,
|
||||
SPARC_REG_F54,
|
||||
SPARC_REG_F56,
|
||||
SPARC_REG_F58,
|
||||
SPARC_REG_F60,
|
||||
SPARC_REG_F62,
|
||||
SPARC_REG_FCC0, // Floating condition codes
|
||||
SPARC_REG_FCC1,
|
||||
SPARC_REG_FCC2,
|
||||
SPARC_REG_FCC3,
|
||||
SPARC_REG_FP,
|
||||
SPARC_REG_G0,
|
||||
SPARC_REG_G1,
|
||||
SPARC_REG_G2,
|
||||
SPARC_REG_G3,
|
||||
SPARC_REG_G4,
|
||||
SPARC_REG_G5,
|
||||
SPARC_REG_G6,
|
||||
SPARC_REG_G7,
|
||||
SPARC_REG_I0,
|
||||
SPARC_REG_I1,
|
||||
SPARC_REG_I2,
|
||||
SPARC_REG_I3,
|
||||
SPARC_REG_I4,
|
||||
SPARC_REG_I5,
|
||||
SPARC_REG_I7,
|
||||
SPARC_REG_ICC, // Integer condition codes
|
||||
SPARC_REG_L0,
|
||||
SPARC_REG_L1,
|
||||
SPARC_REG_L2,
|
||||
SPARC_REG_L3,
|
||||
SPARC_REG_L4,
|
||||
SPARC_REG_L5,
|
||||
SPARC_REG_L6,
|
||||
SPARC_REG_L7,
|
||||
SPARC_REG_O0,
|
||||
SPARC_REG_O1,
|
||||
SPARC_REG_O2,
|
||||
SPARC_REG_O3,
|
||||
SPARC_REG_O4,
|
||||
SPARC_REG_O5,
|
||||
SPARC_REG_O7,
|
||||
SPARC_REG_SP,
|
||||
SPARC_REG_Y,
|
||||
|
||||
// special register
|
||||
SPARC_REG_XCC,
|
||||
|
||||
// pseudo register
|
||||
SPARC_REG_PC, // program counter register
|
||||
|
||||
SPARC_REG_ENDING, // <-- mark the end of the list of registers
|
||||
|
||||
// extras
|
||||
SPARC_REG_O6 = SPARC_REG_SP,
|
||||
SPARC_REG_I6 = SPARC_REG_FP,
|
||||
} sparc_reg;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
408
include/unicorn/unicorn.h
Normal file
408
include/unicorn/unicorn.h
Normal file
@@ -0,0 +1,408 @@
|
||||
/* Unicorn Emulator Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2015 */
|
||||
|
||||
#ifndef UNICORN_ENGINE_H
|
||||
#define UNICORN_ENGINE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#if defined(UNICORN_HAS_OSXKERNEL)
|
||||
#include <libkern/libkern.h>
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#include "m68k.h"
|
||||
#include "x86.h"
|
||||
#include "arm.h"
|
||||
#include "arm64.h"
|
||||
#include "mips.h"
|
||||
#include "sparc.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#pragma warning(disable:4100)
|
||||
#ifdef UNICORN_SHARED
|
||||
#define UNICORN_EXPORT __declspec(dllexport)
|
||||
#else // defined(UNICORN_STATIC)
|
||||
#define UNICORN_EXPORT
|
||||
#endif
|
||||
#else
|
||||
#ifdef __GNUC__
|
||||
#define UNICORN_EXPORT __attribute__((visibility("default")))
|
||||
#else
|
||||
#define UNICORN_EXPORT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define UNICORN_DEPRECATED __attribute__((deprecated))
|
||||
#elif defined(_MSC_VER)
|
||||
#define UNICORN_DEPRECATED __declspec(deprecated)
|
||||
#else
|
||||
#pragma message("WARNING: You need to implement UNICORN_DEPRECATED for this compiler")
|
||||
#define UNICORN_DEPRECATED
|
||||
#endif
|
||||
|
||||
// Unicorn API version
|
||||
#define UC_API_MAJOR 0
|
||||
#define UC_API_MINOR 9
|
||||
|
||||
// Macro to create combined version which can be compared to
|
||||
// result of uc_version() API.
|
||||
#define UC_MAKE_VERSION(major, minor) ((major << 8) + minor)
|
||||
|
||||
// Scales to calculate timeout on microsecond unit
|
||||
// 1 second = 1000,000 microseconds
|
||||
#define UC_SECOND_SCALE 1000000
|
||||
// 1 milisecond = 1000 nanoseconds
|
||||
#define UC_MILISECOND_SCALE 1000
|
||||
|
||||
// Handle using with all API
|
||||
typedef size_t uch;
|
||||
|
||||
// Architecture type
|
||||
typedef enum uc_arch {
|
||||
UC_ARCH_ARM = 1, // ARM architecture (including Thumb, Thumb-2)
|
||||
UC_ARCH_ARM64, // ARM-64, also called AArch64
|
||||
UC_ARCH_MIPS, // Mips architecture
|
||||
UC_ARCH_X86, // X86 architecture (including x86 & x86-64)
|
||||
UC_ARCH_PPC, // PowerPC architecture
|
||||
UC_ARCH_SPARC, // Sparc architecture
|
||||
UC_ARCH_M68K, // M68K architecture
|
||||
UC_ARCH_MAX,
|
||||
UC_ARCH_ALL = 0xFFFF, // All architectures - for uc_support()
|
||||
} uc_arch;
|
||||
|
||||
// Mode type
|
||||
typedef enum uc_mode {
|
||||
UC_MODE_LITTLE_ENDIAN = 0, // little-endian mode (default mode)
|
||||
UC_MODE_ARM = 0, // 32-bit ARM
|
||||
UC_MODE_16 = 1 << 1, // 16-bit mode (X86)
|
||||
UC_MODE_32 = 1 << 2, // 32-bit mode (X86)
|
||||
UC_MODE_64 = 1 << 3, // 64-bit mode (X86, PPC)
|
||||
UC_MODE_THUMB = 1 << 4, // ARM's Thumb mode, including Thumb-2
|
||||
UC_MODE_MCLASS = 1 << 5, // ARM's Cortex-M series
|
||||
UC_MODE_V8 = 1 << 6, // ARMv8 A32 encodings for ARM
|
||||
UC_MODE_MICRO = 1 << 4, // MicroMips mode (MIPS)
|
||||
UC_MODE_MIPS3 = 1 << 5, // Mips III ISA
|
||||
UC_MODE_MIPS32R6 = 1 << 6, // Mips32r6 ISA
|
||||
UC_MODE_V9 = 1 << 4, // SparcV9 mode (Sparc)
|
||||
UC_MODE_QPX = 1 << 4, // Quad Processing eXtensions mode (PPC)
|
||||
UC_MODE_BIG_ENDIAN = 1 << 31, // big-endian mode
|
||||
UC_MODE_MIPS32 = UC_MODE_32, // Mips32 ISA (Mips)
|
||||
UC_MODE_MIPS64 = UC_MODE_64, // Mips64 ISA (Mips)
|
||||
} uc_mode;
|
||||
|
||||
// All type of errors encountered by Unicorn API.
|
||||
// These are values returned by uc_errno()
|
||||
typedef enum uc_err {
|
||||
UC_ERR_OK = 0, // No error: everything was fine
|
||||
UC_ERR_OOM, // Out-Of-Memory error: uc_open(), uc_emulate()
|
||||
UC_ERR_ARCH, // Unsupported architecture: uc_open()
|
||||
UC_ERR_HANDLE, // Invalid handle
|
||||
UC_ERR_UCH, // Invalid handle (uch)
|
||||
UC_ERR_MODE, // Invalid/unsupported mode: uc_open()
|
||||
UC_ERR_VERSION, // Unsupported version (bindings)
|
||||
UC_ERR_MEM_READ, // Quit emulation due to invalid memory READ: uc_emu_start()
|
||||
UC_ERR_MEM_WRITE, // Quit emulation due to invalid memory WRITE: uc_emu_start()
|
||||
UC_ERR_CODE_INVALID, // Quit emulation due to invalid code address: uc_emu_start()
|
||||
UC_ERR_HOOK, // Invalid hook type: uc_hook_add()
|
||||
UC_ERR_INSN_INVALID, // Quit emulation due to invalid instruction: uc_emu_start()
|
||||
} uc_err;
|
||||
|
||||
|
||||
// Callback function for tracing code (UC_HOOK_CODE & UC_HOOK_BLOCK)
|
||||
// @address: address where the code is being executed
|
||||
// @size: size of machine instruction being executed
|
||||
// @user_data: user data passed to tracing APIs.
|
||||
typedef void (*uc_cb_hookcode_t)(uch handle, uint64_t address, uint32_t size, void *user_data);
|
||||
|
||||
// Callback function for tracing interrupts (for uc_hook_intr())
|
||||
// @intno: interrupt number
|
||||
// @user_data: user data passed to tracing APIs.
|
||||
typedef void (*uc_cb_hookintr_t)(uch handle, uint32_t intno, void *user_data);
|
||||
|
||||
// Callback function for tracing IN instruction of X86
|
||||
// @port: port number
|
||||
// @size: data size (1/2/4) to be read from this port
|
||||
// @user_data: user data passed to tracing APIs.
|
||||
typedef uint32_t (*uc_cb_insn_in_t)(uch handle, uint32_t port, int size, void *user_data);
|
||||
|
||||
// x86's handler for OUT
|
||||
// @port: port number
|
||||
// @size: data size (1/2/4) to be written to this port
|
||||
// @value: data value to be written to this port
|
||||
typedef void (*uc_cb_insn_out_t)(uch handle, uint32_t port, int size, uint32_t value, void *user_data);
|
||||
|
||||
// All type of memory accesses for UC_HOOK_MEM_*
|
||||
typedef enum uc_mem_type {
|
||||
UC_MEM_READ = 16, // Memory is read from
|
||||
UC_MEM_WRITE, // Memory is written to
|
||||
UC_MEM_READ_WRITE, // Memory is accessed (either READ or WRITE)
|
||||
} uc_mem_type;
|
||||
|
||||
// All type of hooks for uc_hook_add() API.
|
||||
typedef enum uc_hook_t {
|
||||
UC_HOOK_INTR = 32, // Hook all interrupt events
|
||||
UC_HOOK_INSN, // Hook a particular instruction
|
||||
UC_HOOK_CODE, // Hook a range of code
|
||||
UC_HOOK_BLOCK, // Hook basic blocks
|
||||
UC_HOOK_MEM_INVALID, // Hook for all invalid memory access events
|
||||
UC_HOOK_MEM_READ, // Hook all memory read events.
|
||||
UC_HOOK_MEM_WRITE, // Hook all memory write events.
|
||||
UC_HOOK_MEM_READ_WRITE, // Hook all memory accesses (either READ or WRITE).
|
||||
} uc_hook_t;
|
||||
|
||||
// Callback function for hooking memory (UC_HOOK_MEM_*)
|
||||
// @type: this memory is being READ, or WRITE
|
||||
// @address: address where the code is being executed
|
||||
// @size: size of data being read or written
|
||||
// @value: value of data being written to memory, or irrelevant if type = READ.
|
||||
// @user_data: user data passed to tracing APIs
|
||||
typedef void (*uc_cb_hookmem_t)(uch handle, uc_mem_type type,
|
||||
uint64_t address, int size, int64_t value, void *user_data);
|
||||
|
||||
// Callback function for handling memory events (for UC_HOOK_MEM_INVALID)
|
||||
// @type: this memory is being READ, or WRITE
|
||||
// @address: address where the code is being executed
|
||||
// @size: size of data being read or written
|
||||
// @value: value of data being written to memory, or irrelevant if type = READ.
|
||||
// @user_data: user data passed to tracing APIs
|
||||
// @return: return true to continue, or false to stop program (due to invalid memory).
|
||||
typedef bool (*uc_cb_eventmem_t)(uch handle, uc_mem_type type,
|
||||
uint64_t address, int size, int64_t value, void *user_data);
|
||||
|
||||
|
||||
/*
|
||||
Return combined API version & major and minor version numbers.
|
||||
|
||||
@major: major number of API version
|
||||
@minor: minor number of API version
|
||||
|
||||
@return hexical number as (major << 8 | minor), which encodes both
|
||||
major & minor versions.
|
||||
NOTE: This returned value can be compared with version number made
|
||||
with macro UC_MAKE_VERSION
|
||||
|
||||
For example, second API version would return 1 in @major, and 1 in @minor
|
||||
The return value would be 0x0101
|
||||
|
||||
NOTE: if you only care about returned value, but not major and minor values,
|
||||
set both @major & @minor arguments to NULL.
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
unsigned int uc_version(unsigned int *major, unsigned int *minor);
|
||||
|
||||
|
||||
/*
|
||||
This API can be used to either ask for archs supported by this library.
|
||||
|
||||
To check if a particular arch is supported by this library, set @query to
|
||||
arch mode (UC_ARCH_* value).
|
||||
To verify if this library supports all the archs, use UC_ARCH_ALL.
|
||||
|
||||
@return True if this library supports the given arch.
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
bool uc_support(int query);
|
||||
|
||||
|
||||
/*
|
||||
Initialize UC handle: this must be done before any usage of UC.
|
||||
|
||||
@arch: architecture type (UC_ARCH_*)
|
||||
@mode: hardware mode. This is combined of UC_MODE_*
|
||||
@handle: pointer to handle, which will be updated at return time
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_open(uc_arch arch, uc_mode mode, uch *handle);
|
||||
|
||||
/*
|
||||
Close UC handle: MUST do to release the handle when it is not used anymore.
|
||||
NOTE: this must be called only when there is no longer usage of Unicorn.
|
||||
The reason is the this API releases some cached memory, thus access to any
|
||||
Unicorn API after uc_close() might crash your application.
|
||||
After this, @handle is invalid, and nolonger usable.
|
||||
|
||||
@handle: pointer to a handle returned by uc_open()
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_close(uch *handle);
|
||||
|
||||
/*
|
||||
Report the last error number when some API function fail.
|
||||
Like glibc's errno, uc_errno might not retain its old value once accessed.
|
||||
|
||||
@handle: handle returned by uc_open()
|
||||
|
||||
@return: error code of uc_err enum type (UC_ERR_*, see above)
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_errno(uch handle);
|
||||
|
||||
/*
|
||||
Return a string describing given error code.
|
||||
|
||||
@code: error code (see UC_ERR_* above)
|
||||
|
||||
@return: returns a pointer to a string that describes the error code
|
||||
passed in the argument @code
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
const char *uc_strerror(uc_err code);
|
||||
|
||||
/*
|
||||
Write to register.
|
||||
|
||||
@handle: handle returned by uc_open()
|
||||
@regid: register ID that is to be modified.
|
||||
@value: pointer to the value that will set to register @regid
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_reg_write(uch handle, int regid, void *value);
|
||||
|
||||
/*
|
||||
Read register value.
|
||||
|
||||
@handle: handle returned by uc_open()
|
||||
@regid: register ID that is to be retrieved.
|
||||
@value: pointer to a variable storing the register value.
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_reg_read(uch handle, int regid, void *value);
|
||||
|
||||
/*
|
||||
Write to a range of bytes in memory.
|
||||
|
||||
@handle: handle returned by uc_open()
|
||||
@address: starting memory address of bytes to set.
|
||||
@bytes: pointer to a variable containing data to be written to memory.
|
||||
@size: size of memory to write to.
|
||||
|
||||
NOTE: @bytes must be big enough to contain @size bytes.
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_mem_write(uch handle, uint64_t address, uint8_t *bytes, size_t size);
|
||||
|
||||
/*
|
||||
Read a range of bytes in memory.
|
||||
|
||||
@handle: handle returned by uc_open()
|
||||
@address: starting memory address of bytes to get.
|
||||
@bytes: pointer to a variable containing data copied from memory.
|
||||
@size: size of memory to read.
|
||||
|
||||
NOTE: @bytes must be big enough to contain @size bytes.
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_mem_read(uch handle, uint64_t address, uint8_t *bytes, size_t size);
|
||||
|
||||
/*
|
||||
Emulate machine code in a specific duration of time.
|
||||
|
||||
@handle: handle returned by uc_open()
|
||||
@begin: address where emulation starts
|
||||
@until: address where emulation stops (i.e when this address is hit)
|
||||
@timeout: duration to emulate the code (in microseconds). When this value is 0,
|
||||
we will emulate the code in infinite time, until the code is finished.
|
||||
@count: the number of instructions to be emulated. When this value is 0,
|
||||
we will emulate all the code available, until the code is finished.
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_emu_start(uch handle, uint64_t begin, uint64_t until, uint64_t timeout, size_t count);
|
||||
|
||||
/*
|
||||
Stop emulation (which was started by uc_emu_start() API.
|
||||
This is typically called from callback functions registered via tracing APIs.
|
||||
NOTE: for now, this will stop the execution only after the current block.
|
||||
|
||||
@handle: handle returned by uc_open()
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_emu_stop(uch handle);
|
||||
|
||||
/*
|
||||
Register callback for a hook event.
|
||||
The callback will be run when the hook event is hit.
|
||||
|
||||
@handle: handle returned by uc_open()
|
||||
@h2: hook handle returned from this registration. To be used in uc_hook_del() API
|
||||
@type: hook type
|
||||
@callback: callback to be run when instruction is hit
|
||||
@user_data: user-defined data. This will be passed to callback function in its
|
||||
last argument @user_data
|
||||
@...: variable arguments (depending on @type)
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_hook_add(uch handle, uch *h2, uc_hook_t type, void *callback, void *user_data, ...);
|
||||
|
||||
/*
|
||||
Unregister (remove) a hook callback.
|
||||
This API removes the hook callback registered by uc_hook_add().
|
||||
NOTE: this should be called only when you no longer want to trace.
|
||||
After this, @hhandle is invalid, and nolonger usable.
|
||||
|
||||
@handle: handle returned by uc_open()
|
||||
@h2: handle returned by uc_hook_add()
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_hook_del(uch handle, uch *h2);
|
||||
|
||||
/*
|
||||
Map memory in for emulation.
|
||||
This API adds a memory region that can be used by emulation.
|
||||
|
||||
@handle: handle returned by uc_open()
|
||||
@address: starting address of the new memory region to be mapped in.
|
||||
@size: size of the new memory region to be mapped in. This will be round up to
|
||||
the next 8KB boundary.
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_mem_map(uch handle, uint64_t address, size_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
1416
include/unicorn/x86.h
Normal file
1416
include/unicorn/x86.h
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user