| #ifndef __VM_VERIFIER_H |
| #define __VM_VERIFIER_H |
| |
| #include "vm/types.h" |
| #include "lib/list.h" |
| |
| extern bool opt_trace_verifier; |
| |
| #define vrf_err(format, args...) opt_trace_verifier ? do_warn("%s: " format, __func__, ## args) : 0 |
| |
| struct verifier_operand { |
| enum vm_type vm_type; |
| bool is_fragment; /* If it is not the first slot of a multi-slot op */ |
| }; |
| |
| struct verifier_stack { |
| struct verifier_operand op; |
| struct list_head slots; |
| }; |
| |
| enum verifier_local_var_state { |
| DEFINED, |
| UNDEFINED, |
| UNKNOWN, |
| }; |
| |
| struct verifier_local_var { |
| enum verifier_local_var_state state; |
| struct verifier_operand op; |
| }; |
| |
| struct verifier_state { |
| struct verifier_local_var *vars; /* Array of local_vars. */ |
| unsigned int nb_vars; |
| struct verifier_stack *stack; /* Stack of verifier_operands stored as a list. */ |
| }; |
| |
| struct verifier_block { |
| uint32_t begin_offset; |
| uint32_t *following_offsets; |
| uint32_t nb_followers; |
| |
| struct verifier_state *initial_state; |
| struct verifier_state *final_state; |
| |
| unsigned char *code; |
| unsigned long pc; |
| unsigned char opc; |
| bool is_wide; |
| |
| struct verifier_context *parent_ctx; |
| struct list_head blocks; |
| }; |
| |
| struct verifier_jump_destinations { |
| unsigned long dest; |
| struct list_head list; |
| }; |
| |
| struct verifier_context { |
| struct vm_method *method; |
| unsigned char *code; |
| unsigned long code_size; |
| |
| unsigned long max_stack; |
| unsigned long max_locals; |
| |
| struct verifier_jump_destinations *jmp_dests; |
| struct verifier_block *vb_list; |
| }; |
| |
| struct verifier_local_var *alloc_verifier_local_var(int nb_vars); |
| struct verifier_stack *alloc_verifier_stack(enum vm_type vm_type); |
| struct verifier_state *alloc_verifier_state(int nb_vars); |
| struct verifier_block *alloc_verifier_block(struct verifier_context *vrf, uint32_t begin_offset); |
| struct verifier_jump_destinations *alloc_verifier_jump_destinations(unsigned long initial_size); |
| struct verifier_context *alloc_verifier_context(struct vm_method *vmm); |
| |
| void free_verifier_local_var(struct verifier_local_var *vars); |
| void free_verifier_stack(struct verifier_stack *stack); |
| void free_verifier_state(struct verifier_state *state); |
| void free_verifier_block(struct verifier_block *block); |
| void free_verifier_jump_destinations(struct verifier_jump_destinations *jmp_dests); |
| void free_verifier_context(struct verifier_context *ctx); |
| |
| int store_vrf_lvar(struct verifier_block *b, enum vm_type vm_type, unsigned int idx); |
| int peek_vrf_lvar(struct verifier_block *b, enum vm_type vm_type, unsigned int idx); |
| |
| int vrf_stack_size(struct verifier_stack *st); |
| int push_vrf_op(struct verifier_block *b, enum vm_type vm_type); |
| int pop_vrf_op(struct verifier_block *b, enum vm_type vm_type); |
| int peek_vrf_op(struct verifier_block *b, enum vm_type vm_type); |
| |
| int add_jump_destination(struct verifier_jump_destinations *jd, unsigned long dest); |
| int add_tableswitch_destinations(struct verifier_jump_destinations *jd, const unsigned char *code, unsigned long pc, unsigned long code_size); |
| int add_lookupswitch_destinations(struct verifier_jump_destinations *jd, const unsigned char *code, unsigned long pc, unsigned long code_size); |
| |
| int verify_instruction(struct verifier_block *bb); |
| |
| int transition_verifier_stack(struct verifier_stack *stc, struct verifier_stack *stn); |
| int transition_verifier_local_var(struct verifier_local_var *varsc, struct verifier_local_var *varsn, int nb_vars); |
| int transition_verifier_state(struct verifier_state *s1, struct verifier_state *s2); |
| |
| int vm_method_verify(struct vm_method *vmm); |
| |
| typedef int (*verify_fn_t) (struct verifier_block *); |
| |
| #define E_NOT_IMPLEMENTED (-ENOSYS) |
| #define E_TYPE_CHECKING (-1) |
| #define E_MALFORMED_BC (-2) |
| #define E_WRONG_LOCAL_INDEX (-3) |
| #define E_WRONG_CONSTANT_POOL_INDEX (-4) |
| #define E_INVALID_BRANCH (-5) |
| #define E_FALLING_OFF (-6) |
| #define E_INVALID_EXCEPTION_HANDLER (-7) |
| #define E_OVERRIDES_FINAL (-8) |
| |
| #define INITIAL_FOLLOWERS_SIZE (8) |
| |
| #define DECLARE_VERIFIER(name) int verify_##name(struct verifier_block *) |
| |
| DECLARE_VERIFIER(aaload); |
| DECLARE_VERIFIER(aastore); |
| DECLARE_VERIFIER(aconst_null); |
| DECLARE_VERIFIER(aload); |
| DECLARE_VERIFIER(aload_n); |
| DECLARE_VERIFIER(anewarray); |
| DECLARE_VERIFIER(arraylength); |
| DECLARE_VERIFIER(astore); |
| DECLARE_VERIFIER(astore_n); |
| DECLARE_VERIFIER(athrow); |
| DECLARE_VERIFIER(baload); |
| DECLARE_VERIFIER(bastore); |
| DECLARE_VERIFIER(bipush); |
| DECLARE_VERIFIER(caload); |
| DECLARE_VERIFIER(castore); |
| DECLARE_VERIFIER(checkcast); |
| DECLARE_VERIFIER(d2f); |
| DECLARE_VERIFIER(d2i); |
| DECLARE_VERIFIER(d2l); |
| DECLARE_VERIFIER(dadd); |
| DECLARE_VERIFIER(daload); |
| DECLARE_VERIFIER(dastore); |
| DECLARE_VERIFIER(dconst_n); |
| DECLARE_VERIFIER(ddiv); |
| DECLARE_VERIFIER(dload); |
| DECLARE_VERIFIER(dload_n); |
| DECLARE_VERIFIER(dmul); |
| DECLARE_VERIFIER(dneg); |
| DECLARE_VERIFIER(drem); |
| DECLARE_VERIFIER(dstore); |
| DECLARE_VERIFIER(dstore_n); |
| DECLARE_VERIFIER(dsub); |
| DECLARE_VERIFIER(dup); |
| DECLARE_VERIFIER(dup2); |
| DECLARE_VERIFIER(dup2_x1); |
| DECLARE_VERIFIER(dup2_x2); |
| DECLARE_VERIFIER(dup_x1); |
| DECLARE_VERIFIER(dup_x2); |
| DECLARE_VERIFIER(f2d); |
| DECLARE_VERIFIER(f2i); |
| DECLARE_VERIFIER(f2l); |
| DECLARE_VERIFIER(fadd); |
| DECLARE_VERIFIER(faload); |
| DECLARE_VERIFIER(fastore); |
| DECLARE_VERIFIER(fconst_n); |
| DECLARE_VERIFIER(fdiv); |
| DECLARE_VERIFIER(fload); |
| DECLARE_VERIFIER(fload_n); |
| DECLARE_VERIFIER(fmul); |
| DECLARE_VERIFIER(fneg); |
| DECLARE_VERIFIER(frem); |
| DECLARE_VERIFIER(fstore); |
| DECLARE_VERIFIER(fstore_n); |
| DECLARE_VERIFIER(fsub); |
| DECLARE_VERIFIER(getfield); |
| DECLARE_VERIFIER(getstatic); |
| DECLARE_VERIFIER(goto); |
| DECLARE_VERIFIER(goto_w); |
| DECLARE_VERIFIER(i2b); |
| DECLARE_VERIFIER(i2c); |
| DECLARE_VERIFIER(i2d); |
| DECLARE_VERIFIER(i2f); |
| DECLARE_VERIFIER(i2l); |
| DECLARE_VERIFIER(i2s); |
| DECLARE_VERIFIER(iadd); |
| DECLARE_VERIFIER(iaload); |
| DECLARE_VERIFIER(iand); |
| DECLARE_VERIFIER(iastore); |
| DECLARE_VERIFIER(iconst_n); |
| DECLARE_VERIFIER(idiv); |
| DECLARE_VERIFIER(if_acmpeq); |
| DECLARE_VERIFIER(if_acmpne); |
| DECLARE_VERIFIER(ifeq); |
| DECLARE_VERIFIER(ifge); |
| DECLARE_VERIFIER(ifgt); |
| DECLARE_VERIFIER(if_icmpeq); |
| DECLARE_VERIFIER(if_icmpge); |
| DECLARE_VERIFIER(if_icmpgt); |
| DECLARE_VERIFIER(if_icmple); |
| DECLARE_VERIFIER(if_icmplt); |
| DECLARE_VERIFIER(if_icmpne); |
| DECLARE_VERIFIER(ifle); |
| DECLARE_VERIFIER(iflt); |
| DECLARE_VERIFIER(ifne); |
| DECLARE_VERIFIER(ifnonnull); |
| DECLARE_VERIFIER(ifnull); |
| DECLARE_VERIFIER(iinc); |
| DECLARE_VERIFIER(iload); |
| DECLARE_VERIFIER(iload_n); |
| DECLARE_VERIFIER(imul); |
| DECLARE_VERIFIER(ineg); |
| DECLARE_VERIFIER(instanceof); |
| DECLARE_VERIFIER(invokeinterface); |
| DECLARE_VERIFIER(invokespecial); |
| DECLARE_VERIFIER(invokestatic); |
| DECLARE_VERIFIER(invokevirtual); |
| DECLARE_VERIFIER(ior); |
| DECLARE_VERIFIER(irem); |
| DECLARE_VERIFIER(ishl); |
| DECLARE_VERIFIER(ishr); |
| DECLARE_VERIFIER(istore); |
| DECLARE_VERIFIER(istore_n); |
| DECLARE_VERIFIER(isub); |
| DECLARE_VERIFIER(iushr); |
| DECLARE_VERIFIER(ixor); |
| DECLARE_VERIFIER(jsr); |
| DECLARE_VERIFIER(jsr_w); |
| DECLARE_VERIFIER(l2d); |
| DECLARE_VERIFIER(l2f); |
| DECLARE_VERIFIER(l2i); |
| DECLARE_VERIFIER(ladd); |
| DECLARE_VERIFIER(laload); |
| DECLARE_VERIFIER(land); |
| DECLARE_VERIFIER(lastore); |
| DECLARE_VERIFIER(lcmp); |
| DECLARE_VERIFIER(lconst_n); |
| DECLARE_VERIFIER(ldc); |
| DECLARE_VERIFIER(ldc2_w); |
| DECLARE_VERIFIER(ldc_w); |
| DECLARE_VERIFIER(ldiv); |
| DECLARE_VERIFIER(lload); |
| DECLARE_VERIFIER(lload_n); |
| DECLARE_VERIFIER(lmul); |
| DECLARE_VERIFIER(lneg); |
| DECLARE_VERIFIER(lookupswitch); |
| DECLARE_VERIFIER(lor); |
| DECLARE_VERIFIER(lrem); |
| DECLARE_VERIFIER(lshl); |
| DECLARE_VERIFIER(lshr); |
| DECLARE_VERIFIER(lstore); |
| DECLARE_VERIFIER(lstore_n); |
| DECLARE_VERIFIER(lsub); |
| DECLARE_VERIFIER(lushr); |
| DECLARE_VERIFIER(lxor); |
| DECLARE_VERIFIER(monitorenter); |
| DECLARE_VERIFIER(monitorexit); |
| DECLARE_VERIFIER(multianewarray); |
| DECLARE_VERIFIER(new); |
| DECLARE_VERIFIER(newarray); |
| DECLARE_VERIFIER(nop); |
| DECLARE_VERIFIER(pop); |
| DECLARE_VERIFIER(pop2); |
| DECLARE_VERIFIER(putfield); |
| DECLARE_VERIFIER(putstatic); |
| DECLARE_VERIFIER(ret); |
| DECLARE_VERIFIER(return); |
| DECLARE_VERIFIER(saload); |
| DECLARE_VERIFIER(sastore); |
| DECLARE_VERIFIER(sipush); |
| DECLARE_VERIFIER(swap); |
| DECLARE_VERIFIER(tableswitch); |
| DECLARE_VERIFIER(wide); |
| DECLARE_VERIFIER(dcmpg); |
| DECLARE_VERIFIER(fcmpg); |
| DECLARE_VERIFIER(dcmpl); |
| DECLARE_VERIFIER(fcmpl); |
| DECLARE_VERIFIER(areturn); |
| DECLARE_VERIFIER(dreturn); |
| DECLARE_VERIFIER(freturn); |
| DECLARE_VERIFIER(ireturn); |
| DECLARE_VERIFIER(lreturn); |
| |
| #endif |