xref: /aosp_15_r20/external/capstone/bindings/ocaml/capstone.ml (revision 9a0e4156d50a75a99ec4f1653a0e9602a5d45c18)
1(* Capstone Disassembly Engine
2 * By Nguyen Anh Quynh <[email protected]>, 2013-2014 *)
3
4open Arm
5open Arm64
6open Mips
7open Ppc
8open X86
9open Sparc
10open Systemz
11open Xcore
12open M680x
13open Printf	(* debug *)
14
15(* Hardware architectures *)
16type arch =
17  | CS_ARCH_ARM
18  | CS_ARCH_ARM64
19  | CS_ARCH_MIPS
20  | CS_ARCH_X86
21  | CS_ARCH_PPC
22  | CS_ARCH_SPARC
23  | CS_ARCH_SYSZ
24  | CS_ARCH_XCORE
25  | CS_ARCH_M68K
26  | CS_ARCH_TMS320C64X
27  | CS_ARCH_M680X
28
29(* Hardware modes *)
30type mode =
31  |	CS_MODE_LITTLE_ENDIAN	(* little-endian mode (default mode) *)
32  |	CS_MODE_ARM			(* ARM mode *)
33  |	CS_MODE_16			(* 16-bit mode (for X86) *)
34  |	CS_MODE_32			(* 32-bit mode (for X86) *)
35  |	CS_MODE_64			(* 64-bit mode (for X86, PPC) *)
36  |	CS_MODE_THUMB		(* ARM's Thumb mode, including Thumb-2 *)
37  |	CS_MODE_MCLASS		(* ARM's MClass mode *)
38  |	CS_MODE_V8    		(* ARMv8 A32 encodings for ARM *)
39  |	CS_MODE_MICRO		(* MicroMips mode (MIPS architecture) *)
40  |	CS_MODE_MIPS3		(* Mips3 mode (MIPS architecture) *)
41  |	CS_MODE_MIPS32R6	(* Mips32-R6 mode (MIPS architecture) *)
42  |	CS_MODE_MIPS2	    (* Mips2 mode (MIPS architecture) *)
43  |	CS_MODE_V9			(* SparcV9 mode (Sparc architecture) *)
44  |	CS_MODE_BIG_ENDIAN	(* big-endian mode *)
45  |	CS_MODE_MIPS32		(* Mips32 mode (for Mips) *)
46  |	CS_MODE_MIPS64		(* Mips64 mode (for Mips) *)
47  |	CS_MODE_QPX         (* Quad Processing eXtensions mode (PowerPC) *)
48  |	CS_MODE_M680X_6301	(* M680X Hitachi 6301,6303 mode *)
49  |	CS_MODE_M680X_6309	(* M680X Hitachi 6309 mode *)
50  |	CS_MODE_M680X_6800	(* M680X Motorola 6800,6802 mode *)
51  |	CS_MODE_M680X_6801	(* M680X Motorola 6801,6803 mode *)
52  |	CS_MODE_M680X_6805	(* M680X Motorola 6805 mode *)
53  |	CS_MODE_M680X_6808	(* M680X Motorola 6808 mode *)
54  |	CS_MODE_M680X_6809	(* M680X Motorola 6809 mode *)
55  |	CS_MODE_M680X_6811	(* M680X Motorola/Freescale 68HC11 mode *)
56  |	CS_MODE_M680X_CPU12	(* M680X Motorola/Freescale/NXP CPU12 mode *)
57  |	CS_MODE_M680X_HCS08	(* M680X Freescale HCS08 mode *)
58
59
60
61(* Runtime option for the disassembled engine *)
62type opt_type =
63  |	CS_OPT_SYNTAX		(*  Asssembly output syntax *)
64  |	CS_OPT_DETAIL		(* Break down instruction structure into details *)
65  |	CS_OPT_MODE		(* Change engine's mode at run-time *)
66  |	CS_OPT_MEM		(* User-defined dynamic memory related functions *)
67  |	CS_OPT_SKIPDATA		(* Skip data when disassembling. Then engine is in SKIPDATA mode. *)
68  |	CS_OPT_SKIPDATA_SETUP 	(* Setup user-defined function for SKIPDATA option *)
69
70
71(* Common instruction operand access types - to be consistent across all architectures. *)
72(* It is possible to combine access types, for example: CS_AC_READ | CS_AC_WRITE *)
73let _CS_AC_INVALID = 0;;	(* Uninitialized/invalid access type. *)
74let _CS_AC_READ    = 1 lsl 0;; (* Operand read from memory or register. *)
75let _CS_AC_WRITE   = 1 lsl 1;; (* Operand write to memory or register. *)
76
77(* Runtime option value (associated with option type above) *)
78let _CS_OPT_OFF = 0L;; (* Turn OFF an option - default option of CS_OPT_DETAIL, CS_OPT_SKIPDATA. *)
79let _CS_OPT_ON = 3L;;  (* Turn ON an option (CS_OPT_DETAIL, CS_OPT_SKIPDATA). *)
80let _CS_OPT_SYNTAX_DEFAULT = 0L;; (* Default asm syntax (CS_OPT_SYNTAX). *)
81let _CS_OPT_SYNTAX_INTEL = 1L;; (* X86 Intel asm syntax - default on X86 (CS_OPT_SYNTAX). *)
82let _CS_OPT_SYNTAX_ATT = 2L;; (* X86 ATT asm syntax (CS_OPT_SYNTAX). *)
83let _CS_OPT_SYNTAX_NOREGNAME = 3L;; (* Prints register name with only number (CS_OPT_SYNTAX) *)
84
85(* Common instruction operand types - to be consistent across all architectures. *)
86let _CS_OP_INVALID = 0;;  (* uninitialized/invalid operand. *)
87let _CS_OP_REG     = 1;;  (* Register operand. *)
88let _CS_OP_IMM     = 2;;  (* Immediate operand. *)
89let _CS_OP_MEM     = 3;;  (* Memory operand. *)
90let _CS_OP_FP      = 4;;  (* Floating-Point operand. *)
91
92(* Common instruction groups - to be consistent across all architectures. *)
93let _CS_GRP_INVALID = 0;;  (* uninitialized/invalid group. *)
94let _CS_GRP_JUMP    = 1;;  (* all jump instructions (conditional+direct+indirect jumps) *)
95let _CS_GRP_CALL    = 2;;  (* all call instructions *)
96let _CS_GRP_RET     = 3;;  (* all return instructions *)
97let _CS_GRP_INT     = 4;;  (* all interrupt instructions (int+syscall) *)
98let _CS_GRP_IRET    = 5;;  (* all interrupt return instructions *)
99let _CS_GRP_PRIVILEGE = 6;;  (* all privileged instructions *)
100
101type cs_arch =
102	| CS_INFO_ARM of cs_arm
103	| CS_INFO_ARM64 of cs_arm64
104	| CS_INFO_MIPS of cs_mips
105	| CS_INFO_X86 of cs_x86
106	| CS_INFO_PPC of cs_ppc
107	| CS_INFO_SPARC of cs_sparc
108	| CS_INFO_SYSZ of cs_sysz
109	| CS_INFO_XCORE of cs_xcore
110	| CS_INFO_M680X of cs_m680x
111
112
113type csh = {
114	h: Int64.t;
115	a: arch;
116}
117
118type cs_insn0 = {
119	id: int;
120	address: int;
121	size: int;
122	bytes: int array;
123	mnemonic: string;
124	op_str: string;
125	regs_read: int array;
126	regs_write: int array;
127	groups: int array;
128	arch: cs_arch;
129}
130
131external _cs_open: arch -> mode list -> Int64.t option = "ocaml_open"
132external cs_disasm_quick: arch -> mode list -> string -> Int64.t -> Int64.t -> cs_insn0 list = "ocaml_cs_disasm"
133external _cs_disasm_internal: arch -> Int64.t -> string -> Int64.t -> Int64.t -> cs_insn0 list = "ocaml_cs_disasm_internal"
134external _cs_reg_name: Int64.t -> int -> string = "ocaml_register_name"
135external _cs_insn_name: Int64.t -> int -> string = "ocaml_instruction_name"
136external _cs_group_name: Int64.t -> int -> string = "ocaml_group_name"
137external cs_version: unit -> int = "ocaml_version"
138external _cs_option: Int64.t -> opt_type -> Int64.t -> int = "ocaml_option"
139external _cs_close: Int64.t -> int = "ocaml_close"
140
141
142let cs_open _arch _mode: csh = (
143	let _handle = _cs_open _arch _mode in (
144	match _handle with
145	| None -> { h = 0L; a = _arch }
146	| Some v -> { h = v; a = _arch }
147	);
148);;
149
150let cs_close handle = (
151	_cs_close handle.h;
152)
153
154let cs_option handle opt value = (
155	_cs_option handle.h opt value;
156);;
157
158let cs_disasm handle code address count = (
159	_cs_disasm_internal handle.a handle.h code address count;
160);;
161
162let cs_reg_name handle id = (
163	_cs_reg_name handle.h id;
164);;
165
166let cs_insn_name handle id = (
167	_cs_insn_name handle.h id;
168);;
169
170let cs_group_name handle id = (
171	_cs_group_name handle.h id;
172);;
173
174class cs_insn c a =
175	let csh = c in
176	let (id, address, size, bytes, mnemonic, op_str, regs_read,
177        regs_write, groups, arch) =
178        (a.id, a.address, a.size, a.bytes, a.mnemonic, a.op_str,
179        a.regs_read, a.regs_write, a.groups, a.arch) in
180	object
181		method id = id;
182		method address = address;
183		method size = size;
184	        method bytes = bytes;
185		method mnemonic = mnemonic;
186		method op_str = op_str;
187		method regs_read = regs_read;
188		method regs_write = regs_write;
189		method groups = groups;
190		method arch = arch;
191		method reg_name id = _cs_reg_name csh.h id;
192		method insn_name id = _cs_insn_name csh.h id;
193		method group_name id = _cs_group_name csh.h id;
194	end;;
195
196let cs_insn_group handle insn group_id =
197	List.exists (fun g -> g == group_id) (Array.to_list insn.groups);;
198
199let cs_reg_read handle insn reg_id =
200	List.exists (fun g -> g == reg_id) (Array.to_list insn.regs_read);;
201
202let cs_reg_write handle insn reg_id =
203	List.exists (fun g -> g == reg_id) (Array.to_list insn.regs_write);;
204
205
206class cs a m =
207	let mode = m and arch = a in
208	let handle = cs_open arch mode in
209	object
210		method disasm code offset count =
211			let insns = (_cs_disasm_internal arch handle.h code offset count) in
212			List.map (fun x -> new cs_insn handle x) insns;
213
214	end;;
215