blob: 1cfbdab654e0c736f03a9b752f4a1d11f80d5cde [file] [log] [blame]
#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