-
Notifications
You must be signed in to change notification settings - Fork 128
/
wvm.h
458 lines (398 loc) · 10.8 KB
/
wvm.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
#ifndef JVM_H
#define JVM_H
#include "type.h"
#include "list.h"
#include "slab.h"
#define VM_DEBUG
#define JVM_VERSION 0.03
#define JVM_BANNER "(c) wzt 2012,2013,2014"
#define JVM_LOG_PATH "/tmp/wvm"
#define JVM_LOG_LEVEL 5
#define JVM_LOG_NUM 64
#define JVM_LOG_SIZE 512 // MB bytes.
#define JVM_CLASS_MAGIC 0xcafebabe
#define STACK_ITEM_SIZE sizeof(int)
#define CLASS_READ_U4(s, p) \
do { \
s = (((*(u4 *)p >> 24) & 0x000000ff) | \
((*(u4 *)p >> 8) & 0x0000ff00) | \
((*(u4 *)p << 24) & 0xff000000) | \
((*(u4 *)p << 8) & 0x00ff0000)); \
p += 4; \
} while (0);
#define CLASS_READ_U2(s, p) \
do { \
s = (((*(u2 *)p >> 8) & 0x00ff) | \
((*(u2 *)p << 8) & 0xff00)); \
p += 2; \
} while (0);
#define CLASS_READ_U1(s, p) \
do { \
s = *(u1 *)p; \
p += 1; \
} while (0);
#define CLASS_READ_STRING(s, p, len) \
do { \
memcpy(s, p, len); \
} while (0);
#define CONSTANT_Class 7
#define CONSTANT_Fieldref 9
#define CONSTANT_Methodref 10
#define CONSTANT_InterfaceMethodref 11
#define CONSTANT_String 8
#define CONSTANT_Integer 3
#define CONSTANT_Float 4
#define CONSTANT_Long 5
#define CONSTANT_Double 6
#define CONSTANT_NameAndType 12
#define CONSTANT_Utf8 1
#define CONSTANT_MethodHandle 15
#define CONSTANT_MethodType 16
#define CONSTANT_InvokeDynamic 18
#define ACC_PUBLIC 0x0001
#define ACC_FINAL 0x0010
#define ACC_SUPER 0x0020
#define ACC_INTERFACE 0x0200
#define ACC_ABSTRACT 0X0400
#define ACC_SYNTHETIC 0x1000
#define ACC_ANNOTATION 0x2000
#define ACC_ENUM 0x4000
#define IS_ACC_PUBLIC(x) (x & ACC_PUBLIC)
#define FILED_ACC_PUBLIC 0x0001
#define FILED_ACC_PRIVATE 0x0002
#define FILED_ACC_PROTECTED 0x0004
#define FILED_ACC_STATIC 0x0008
#define FILED_ACC_FINAL 0x0010
#define FILED_ACC_VOLATILE 0x0040
#define FILED_ACC_TRANSIENT 0x0080
#define FILED_ACC_SYNTHETIC 0x1000
#define FILED_ACC_ENUM 0x4000
#define METHOD_ACC_PUBLIC 0x0001
#define METHOD_ACC_PRIVATE 0x0002
#define METHOD_ACC_PROTECTED 0x0004
#define METHOD_ACC_STATIC 0x0008
#define METHOD_ACC_FINAL 0x0010
#define METHOD_ACC_SYNCHRONIED 0x0020
#define METHOD_ACC_BRIDGE 0x0040
#define METHOD_ACC_VARARGS 0x0080
#define METHOD_ACC_NATIVE 0x0100
#define METHOD_ACC_ABSTRACT 0x0400
#define METHOD_ACC_STRICT 0x0800
#define METHOD_ACC_SYNTHETIC 0x1000
#define ITEM_Top 0
#define ITEM_Integer 1
#define ITEM_Float 2
#define ITEM_Double 3
#define ITEM_Long 4
#define ITEM_Null 5
#define ITEM_UninitializedThis 6
#define ITEM_Object 7
#define ITEM_Uninitialized 8
#define ARG_BYTE 'B'
#define ARG_CHAR 'C'
#define ARG_DOUBLE 'D'
#define ARG_FLOAT 'F'
#define ARG_INT 'I'
#define ARG_LONG 'J'
#define ARG_REFERENCE 'L'
#define ARG_SHORT 'S'
#define ARG_BOOLEAN 'Z'
#define ARG_ARRAY '['
typedef struct opcode_st {
int len;
char *base;
struct list_head list;
}OPCODE;
struct constant_info_st {
u2 index;
u1 tag;
u1 *base;
}__attribute__ ((packed));
struct CONSTANT_Class_info {
u2 name_index;
u1 *base;
}__attribute__ ((packed));
struct CONSTANT_Fieldref_info {
u2 class_index;
u2 name_and_type_index;
}__attribute__ ((packed));
struct CONSTANT_Methodref_info {
u2 class_index;
u2 name_and_type_index;
}__attribute__ ((packed));
struct CONSTANT_InterfaceMethodref_info {
u2 class_index;
u2 name_and_type_inex;
}__attribute__ ((packed));
struct CONSTANT_String_info {
u2 string_index;
}__attribute__ ((packed));
struct CONSTANT_Integer_info {
u4 bytes;
}__attribute__ ((packed));
struct CONSTANT_Float_info {
u4 bytes;
}__attribute__ ((packed));
struct CONSTANT_Long_info {
u4 high_bytes;
u4 low_bytes;
}__attribute__ ((packed));
struct CONSTANT_Double_info {
u4 high_bytes;
u4 low_bytes;
}__attribute__ ((packed));
struct CONSTANT_NameAndType_info {
u2 name_index;
u2 descriptor_index;
}__attribute__ ((packed));
struct CONSTANT_Utf8_info {
u2 length;
u1 bytes[];
}__attribute__ ((packed));
struct CONSTANT_MethodHandle_info {
u1 reference_kind;
u2 reference_index;
}__attribute__ ((packed));
struct CONSTANT_MethodType_info {
u2 descriptor_index;
}__attribute__ ((packed));
struct CONSTANT_InvokeDynamic_info {
u2 bootstrap_method_attr_index;
u4 name_and_type_index;
}__attribute__ ((packed));
struct jvm_class;
typedef struct constant_attr {
u2 attribute_name_index;
u4 attribute_length;
u2 constantvalue_index;
}CLASS_CONSTANT;
typedef struct signature_attr {
u2 attribute_name_index;
u4 attribute_length;
u2 signature_index;
}CLASS_SIGNATURE;
typedef struct synthetic_attr {
u2 attribute_name_index;
u4 attribute_length;
}CLASS_SYNTHETIC;
typedef struct deprecated_attr {
u2 attribute_name_index;
u4 attribute_length;
}CLASS_DEPRECATED;
typedef struct filed_info {
u2 access_flag;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
u1 *name_base;
u1 *desc_base;
struct list_head list;
struct jvm_class *class;
CLASS_SIGNATURE *signature;
CLASS_SYNTHETIC *synthetic;
CLASS_CONSTANT *constant;
CLASS_DEPRECATED *deprecated;
union {
int value1;
long value2;
};
}CLASS_FILED;
typedef struct exception_table {
u2 start_pc, end_pc;
u2 handler_pc, catch_type;
}EXCEPTION_TABLE;
typedef struct line_number_table {
u2 start_pc;
u2 line_number;
}LINE_NUMBER_TABLE;
typedef struct line_number_table_attr {
u2 attribute_name_index;
u4 attribute_length;
u2 line_number_table_length;
LINE_NUMBER_TABLE *table_base;
}LINE_NUMBER_TABLE_ATTR;
union verification_type_info {
u1 tag;
struct {
u1 tag;
u2 cpool_index;
}a;
struct {
u1 tag;
u2 offset;
}b;
};
typedef struct stack_map_frame {
union {
struct same_frame {
u1 frame_type;
}a;
struct same_locals_l_stack_item_frame {
u1 frame_type;
union verification_type_info *ver_info;
}b;
struct same_locals_l_stack_item_frame_extended {
u1 frame_type;
u2 offset_delta;
union verification_type_info *ver_info;
}c;
struct chop_frame {
u1 frame_type;
u2 offset_delta;
}d;
struct same_frame_extended {
u1 frame_type;
u2 offset_delta;
}e;
struct append_frame {
u1 frame_type;
u2 offset_delta;
union verification_type_info *ver_info;
}f;
struct full_frame {
u1 frame_type;
u2 offset_delta;
u2 number_of_locals;
union verification_type_info *ver_locals_info;
u2 number_of_stack_items;
union verification_type_info *ver_stack_info;
}g;
};
u1 frame_type;
u1 stack_num;
u1 locals_num;
u1 offset_delta;
}STACK_MAP_FRAME;
typedef struct stack_map_attr {
u2 attribute_name_index;
u4 attribute_length;
u2 number_of_entries;
STACK_MAP_FRAME *stack_frame;
}STACK_MAP_ATTR;
typedef struct jvm_stack_frame {
u1 *local_var_table;
u1 *operand_stack;
u4 *method;
u1 *return_addr;
u4 offset;
u2 max_stack;
u2 max_locals;
struct jvm_stack_frame *prev_stack;
}JVM_STACK_FRAME;
typedef struct code_attr {
u2 attribute_name_index;
u4 attribute_length;
u2 max_stack, max_locals;
u2 exception_table_length;
u2 attributes_count;
u4 code_length;
u1 *op_code;
EXCEPTION_TABLE *exception_table;
LINE_NUMBER_TABLE_ATTR *table_attr;
STACK_MAP_ATTR *stack_map_attr;
JVM_STACK_FRAME stack_frame;
u4 *method;
}CLASS_CODE;
typedef struct exception_attr {
u2 attribute_name_index;
u4 attribute_length;
u2 number_of_exceptions;
u2 *exception_index_table;
}CLASS_EXCEPTION;
typedef struct method_info {
u2 access_flag;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
u1 *name_base;
u1 *desc_base;
CLASS_CODE *code_attr;
CLASS_EXCEPTION *exception_attr;
CLASS_SIGNATURE *signature;
CLASS_SYNTHETIC *synthetic;
CLASS_DEPRECATED *deprecated;
struct jvm_class *class;
struct list_head list;
}CLASS_METHOD;
typedef struct jvm_class {
u4 class_magic;
u2 minor_version;
u2 major_version;
u2 access_flag;
u2 this_class;
u2 super_class;
u2 constant_pool_count;
u2 interfaces_count;
u2 fileds_count;
u2 method_count;
char class_file[1024];
struct constant_info_st *constant_info;
struct list_head interface_list_head;
struct list_head filed_list_head;
struct list_head method_list_head;
u2 attributes_count;
CLASS_SIGNATURE *signature;
CLASS_SYNTHETIC *synthetic;
CLASS_CONSTANT *constant;
CLASS_DEPRECATED *deprecated;
struct list_head list;
}CLASS;
typedef struct jvm_object {
int age;
int ref_count;
CLASS *class;
void *addr;
int size;
struct list_head list;
}JVM_OBJECT;
typedef struct jvm_interp_env {
struct constant_info_st *constant_info;
struct jvm_interp_env *prev_env;
}JVM_INTERP_ENV;
typedef struct jvm_pc_st {
u1 *pc;
}JVM_PC;
typedef struct jvm_arg {
int print_class;
int disass_class;
char class_path[1024];
char log_path[1024];
int log_level;
int log_size;
int log_num;
}JVM_ARG;
JVM_INTERP_ENV *curr_jvm_interp_env;
JVM_STACK_FRAME *curr_jvm_stack;
JVM_PC jvm_pc;
JVM_ARG *jvm_arg;
int jvm_stack_depth;
struct list_head jvm_class_list_head;
struct list_head jvm_obj_list_head;
struct thread_mem *jvm_thread_mem;
int mmap_class_file(const char *class_file);
int mmap_exit(void);
void init_class_parse(void);
void exit_class_parse(void);
void fix_class_info(struct list_head *list_head);
void print_class_info(struct list_head *list_head);
void print_line_number_table(LINE_NUMBER_TABLE_ATTR *table_attr);
void print_stack_map(STACK_MAP_ATTR *stack_map);
CLASS_METHOD *lookup_class_method(struct list_head *list_head, char *class_name,
char *method_name);
int interp_bytecode(CLASS_METHOD *method);
int jvm_stack_init(void);
int jvm_pc_init(CLASS_METHOD *method);
int jvm_interp_env_init(void);
CLASS *jvm_load_class(const char *class_path, const char *class_name);
CLASS *jvm_parse_class_file(const char *class_file, const char *class_name);
int lookup_class_file(struct list_head *list_head, char *class_file);
CLASS_FILED *lookup_class_filed(struct list_head *list_head, char *class_name,
char *method_name);
CLASS_FILED *lookup_class_filed(struct list_head *list_head, char *class_name,
char *method_name);
CLASS_SYNTHETIC *parse_synthetic_attribute(u2 index);
int parse_filed_synthetic(CLASS_FILED *filed, u2 index);
int parse_method_synthetic(CLASS_METHOD *method, u2 index);
int parse_filed_deprecated(CLASS_FILED *filed, u2 index);
int parse_method_deprecated(CLASS_METHOD *method, u2 index);
#endif