1 /* radare2 - LGPL - Copyright 2017-2018 - cgvwzq */
2 
3 #include <r_types.h>
4 #include <r_util.h>
5 #include <r_lib.h>
6 #include <r_bin.h>
7 
8 #ifndef _INCLUDE_WASM_H_
9 #define _INCLUDE_WASM_H_
10 
11 // version 0x1 (WIP)
12 // https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md
13 
14 #define R_BIN_WASM_MAGIC_BYTES "\x00" \
15 			       "asm"
16 #define R_BIN_WASM_VERSION 0x1
17 #define R_BIN_WASM_STRING_LENGTH 256
18 #define R_BIN_WASM_END_OF_CODE 0xb
19 
20 #define R_BIN_WASM_SECTION_CUSTOM 0x0
21 #define R_BIN_WASM_SECTION_TYPE 0x1
22 #define R_BIN_WASM_SECTION_IMPORT 0x2
23 #define R_BIN_WASM_SECTION_FUNCTION 0x3
24 #define R_BIN_WASM_SECTION_TABLE 0x4
25 #define R_BIN_WASM_SECTION_MEMORY 0x5
26 #define R_BIN_WASM_SECTION_GLOBAL 0x6
27 #define R_BIN_WASM_SECTION_EXPORT 0x7
28 #define R_BIN_WASM_SECTION_START 0x8
29 #define R_BIN_WASM_SECTION_ELEMENT 0x9
30 #define R_BIN_WASM_SECTION_CODE 0xa
31 #define R_BIN_WASM_SECTION_DATA 0xb
32 
33 typedef enum {
34 	R_BIN_WASM_VALUETYPE_i32 = 0x1,
35 	R_BIN_WASM_VALUETYPE_i64 = 0x2,
36 	R_BIN_WASM_VALUETYPE_f32 = 0x3,
37 	R_BIN_WASM_VALUETYPE_f64 = 0x4,
38 	R_BIN_WASM_VALUETYPE_v128 = 0x5,
39 	R_BIN_WASM_VALUETYPE_ANYFUNC = 0x10,
40 	R_BIN_WASM_VALUETYPE_FUNC = 0x20,
41 	R_BIN_WASM_VALUETYPE_EMPTY = 0x40,
42 } r_bin_wasm_value_type_t;
43 
44 typedef enum {
45 	R_BIN_WASM_EXTERNALKIND_Function = 0x0,
46 	R_BIN_WASM_EXTERNALKIND_Table = 0x1,
47 	R_BIN_WASM_EXTERNALKIND_Memory = 0x2,
48 	R_BIN_WASM_EXTERNALKIND_Global = 0x3,
49 } r_bin_wasm_external_kind_t;
50 
51 typedef enum {
52 	R_BIN_WASM_NAMETYPE_Module = 0x0,
53 	R_BIN_WASM_NAMETYPE_Function = 0x1,
54 	R_BIN_WASM_NAMETYPE_Local = 0x2,
55 } r_bin_wasm_custom_name_type_t;
56 
57 struct r_bin_wasm_init_expr_t {
58 	// bytecode	terminated in 0xb
59 	size_t len;
60 };
61 
62 struct r_bin_wasm_resizable_limits_t {
63 	ut8 flags; // 1 if max field is present, 0 otherwise
64 	ut32 initial;
65 	ut32 maximum;
66 };
67 
68 typedef struct r_bin_wasm_name_t {
69 	ut32 len;
70 	ut8 *name;
71 } RBinWasmName;
72 
73 typedef struct r_bin_wasm_section_t {
74 	ut8 id;
75 	ut32 size;
76 	ut32 name_len;
77 	char *name;
78 	ut32 offset;
79 	ut32 payload_data;
80 	ut32 payload_len;
81 	ut32 count;
82 } RBinWasmSection;
83 
84 typedef struct r_bin_wasm_type_t {
85 	ut8 form;
86 	ut32 param_count;
87 	r_bin_wasm_value_type_t *param_types;
88 	st8 return_count; // MVP = 1
89 	r_bin_wasm_value_type_t return_type;
90 	char to_str[R_BIN_WASM_STRING_LENGTH];
91 } RBinWasmTypeEntry;
92 
93 // Other Types
94 struct r_bin_wasm_global_type_t {
95 	r_bin_wasm_value_type_t content_type;
96 	ut8 mutability;
97 };
98 
99 struct r_bin_wasm_table_type_t {
100 	r_bin_wasm_value_type_t elem_type;
101 	struct r_bin_wasm_resizable_limits_t limits;
102 };
103 
104 struct r_bin_wasm_memory_type_t {
105 	struct r_bin_wasm_resizable_limits_t limits;
106 };
107 
108 typedef struct r_bin_wasm_import_t {
109 	ut32 module_len;
110 	char module_str[R_BIN_WASM_STRING_LENGTH];
111 	ut32 field_len;
112 	char field_str[R_BIN_WASM_STRING_LENGTH];
113 	ut8 kind;
114 	union {
115 		ut32 type_f;
116 		struct r_bin_wasm_global_type_t type_g;
117 		struct r_bin_wasm_table_type_t type_t;
118 		struct r_bin_wasm_memory_type_t type_m;
119 	};
120 
121 } RBinWasmImportEntry;
122 
123 typedef struct r_bin_wasm_function_t {
124 	ut32 type_index; // index to Type entries
125 } RBinWasmFunctionEntry;
126 
127 typedef struct r_bin_wasm_table_t {
128 	ut8 element_type; // only anyfunc
129 	struct r_bin_wasm_resizable_limits_t limits;
130 } RBinWasmTableEntry;
131 
132 typedef struct r_bin_wasm_memory_t {
133 	struct r_bin_wasm_resizable_limits_t limits;
134 } RBinWasmMemoryEntry;
135 
136 typedef struct r_bin_wasm_global_t {
137 	r_bin_wasm_value_type_t content_type;
138 	ut8 mutability; // 0 if immutable, 1 if mutable
139 	struct r_bin_wasm_init_expr_t init;
140 } RBinWasmGlobalEntry;
141 
142 typedef struct r_bin_wasm_export_t {
143 	ut32 field_len;
144 	char field_str[R_BIN_WASM_STRING_LENGTH];
145 	ut8 kind;
146 	ut32 index;
147 } RBinWasmExportEntry;
148 
149 typedef struct r_bin_wasm_start_t {
150 	ut32 index;
151 } RBinWasmStartEntry;
152 
153 struct r_bin_wasm_local_entry_t {
154 	ut32 count;
155 	r_bin_wasm_value_type_t type;
156 };
157 
158 typedef struct r_bin_wasm_element_t {
159 	ut32 index;
160 	struct r_bin_wasm_init_expr_t init;
161 	ut32 num_elem;
162 	ut32 elems[];
163 } RBinWasmElementEntry;
164 
165 typedef struct r_bin_wasm_code_t {
166 	ut32 body_size;
167 	ut32 local_count; // numer of local entries
168 	struct r_bin_wasm_local_entry_t *locals;
169 	ut32 code; // offset
170 	ut32 len; // real bytecode length
171 	ut8 byte; // 0xb, indicating end of the body
172 	char *name;
173 	char *signature;
174 } RBinWasmCodeEntry;
175 
176 typedef struct r_bin_wasm_data_t {
177 	ut32 index; // linear memory index (0 in MVP)
178 	struct r_bin_wasm_init_expr_t offset; // bytecode evaluated at runtime
179 	ut32 size;
180 	ut32 data; // offset
181 } RBinWasmDataEntry;
182 
183 // TODO: custom sections
184 
185 
186 typedef struct r_bin_wasm_custom_name_function_names_t {
187 	ut32 count;
188 	RIDStorage *names;
189 } RBinWasmCustomNameFunctionNames;
190 
191 typedef struct r_bin_wasm_custom_name_local_name_t {
192 	ut32 index; // function index
193 
194 	ut32 names_count;
195 	RIDStorage *names; // local names
196 } RBinWasmCustomNameLocalName;
197 
198 typedef struct r_bin_wasm_custom_name_local_names_t {
199 	ut32 count;
200 	RList *locals; // RBinWasmCustomNameLocalName
201 } RBinWasmCustomNameLocalNames;
202 
203 // "name" section entry
204 typedef struct r_bin_wasm_custom_name_entry_t {
205 	ut8 type;
206 	ut32 size;
207 
208 	ut8 payload_data;
209 	union {
210 		struct r_bin_wasm_name_t* mod_name;
211 		RBinWasmCustomNameFunctionNames *func;
212 		RBinWasmCustomNameLocalNames *local;
213 	};
214 } RBinWasmCustomNameEntry;
215 
216 typedef struct r_bin_wasm_obj_t {
217 
218 	RBuffer *buf;
219 	size_t size;
220 
221 	ut32 entrypoint;
222 
223 	// cache purposes
224 	RList *g_sections;
225 	RList *g_types;
226 	RList *g_imports;
227 	RList *g_exports;
228 	RList *g_tables;
229 	RList *g_memories;
230 	RList *g_globals;
231 	RList *g_elements;
232 	RList *g_codes;
233 	RList *g_datas;
234 	RBinWasmStartEntry *g_start;
235 
236 	RList *g_names;
237 	// etc...
238 
239 } RBinWasmObj;
240 
241 RBinWasmObj *r_bin_wasm_init(RBinFile *bf, RBuffer *buf);
242 void r_bin_wasm_destroy(RBinFile *bf);
243 RList *r_bin_wasm_get_sections(RBinWasmObj *bin);
244 RList *r_bin_wasm_get_types(RBinWasmObj *bin);
245 RList *r_bin_wasm_get_imports(RBinWasmObj *bin);
246 RList *r_bin_wasm_get_exports(RBinWasmObj *bin);
247 RList *r_bin_wasm_get_tables(RBinWasmObj *bin);
248 RList *r_bin_wasm_get_memories(RBinWasmObj *bin);
249 RList *r_bin_wasm_get_globals(RBinWasmObj *bin);
250 RList *r_bin_wasm_get_elements(RBinWasmObj *bin);
251 RList *r_bin_wasm_get_codes(RBinWasmObj *bin);
252 RList *r_bin_wasm_get_datas(RBinWasmObj *bin);
253 RList *r_bin_wasm_get_custom_names(RBinWasmObj *bin);
254 ut32 r_bin_wasm_get_entrypoint(RBinWasmObj *bin);
255 const char *r_bin_wasm_get_function_name(RBinWasmObj *bin, ut32 idx);
256 const char *r_bin_wasm_valuetype_to_string(r_bin_wasm_value_type_t type);
257 
258 #endif
259