Exemple #1
0
void test_move()
{
	assert(NULL != sexp_parse("(move/from16 v12,v1234)", &sexp));
	/*assert(0 == dalvik_instruction_from_sexp(sexp, &inst, 0, NULL));
	assert(inst.opcode == DVM_MOVE);
	assert(inst.num_operands == 2);
	assert(inst.operands[0].payload.uint16 == 12);
	assert(inst.operands[1].payload.uint16 == 1234);
	assert(inst.operands[0].header.info.size == 0);*/
	sexp_free(sexp);
	
	assert(NULL != sexp_parse("(move-wide/from16 v12,v1234)", &sexp));
	assert(0 == dalvik_instruction_from_sexp(sexp, &inst, 0));
	assert(inst.opcode == DVM_MOVE);
	assert(inst.num_operands == 2);
	assert(inst.operands[0].payload.uint16 == 12);
	assert(inst.operands[1].payload.uint16 == 1234);
	assert(inst.operands[0].header.info.size == 1);
	assert(inst.operands[1].header.info.size == 1);
	sexp_free(sexp);
	
	assert(NULL != sexp_parse("(move v12,v1234)", &sexp));
	assert(0 == dalvik_instruction_from_sexp(sexp, &inst, 0));
	assert(inst.opcode == DVM_MOVE);
	assert(inst.num_operands == 2);
	assert(inst.operands[0].payload.uint16 == 12);
	assert(inst.operands[1].payload.uint16 == 1234);
	assert(inst.operands[0].header.info.size == 0);
	assert(inst.operands[1].header.info.size == 0);
	sexp_free(sexp);

	assert(NULL != sexp_parse("(move-result/wide v1234)", &sexp));
	assert(0 == dalvik_instruction_from_sexp(sexp, &inst, 0));
	assert(inst.opcode == DVM_MOVE);
	assert(inst.num_operands == 2);
	assert(inst.operands[0].payload.uint16 == 1234);
	assert(inst.operands[0].header.info.size == 1);
	assert(inst.operands[1].header.info.is_result);
	sexp_free(sexp);

	assert(NULL != sexp_parse("(move-result-object v1234)", &sexp));
	assert(0 == dalvik_instruction_from_sexp(sexp, &inst, 0));
	assert(inst.opcode == DVM_MOVE);
	assert(inst.num_operands == 2);
	assert(inst.operands[0].payload.uint16 == 1234);
	assert(inst.operands[0].header.info.size == 0);
	assert(inst.operands[0].header.info.type = DVM_OPERAND_TYPE_OBJECT);
	assert(inst.operands[1].header.info.type = DVM_OPERAND_TYPE_OBJECT);
	assert(inst.operands[1].header.info.is_result);
	sexp_free(sexp);
}
Exemple #2
0
void test_packed()
{
	assert(NULL != sexp_parse(
		   "(packed-switch v123, 456,\n"
		   "  l456,     ;case456\n"
		   "  l457,     ;case457\n"
		   "  l458,     ;case458\n"
		   "  ldefault  ;default\n"
		   ")", &sexp));
	assert(0 == dalvik_instruction_from_sexp(sexp, &inst, 0));
	assert(DVM_SWITCH == inst.opcode);
	assert(3 == inst.num_operands);
	assert(123 == inst.operands[0].payload.uint16);
	assert(0 == inst.operands[0].header.flags);
	assert(1 == inst.operands[1].header.info.is_const);
	assert(456 == inst.operands[1].payload.uint16);
	assert(inst.operands[1].header.info.type == DVM_OPERAND_TYPE_INT);
	assert(inst.operands[2].header.info.type == DVM_OPERAND_TYPE_LABELVECTOR);
	assert(inst.operands[2].header.info.is_const == 1);
	assert(inst.operands[2].payload.branches != NULL);
	vector_t* v = inst.operands[2].payload.branches;
	assert(0 == *(int*)vector_get(v, 0));
	assert(1 == *(int*)vector_get(v, 1));
	assert(2 == *(int*)vector_get(v, 2));
	assert(3 == *(int*)vector_get(v, 3));
	assert(0 == dalvik_label_get_label_id(stringpool_query("l456")));
	assert(1 == dalvik_label_get_label_id(stringpool_query("l457")));
	assert(2 == dalvik_label_get_label_id(stringpool_query("l458")));
	assert(3 == dalvik_label_get_label_id(stringpool_query("ldefault")));
	sexp_free(sexp);
	dalvik_instruction_free(&inst);
}
Exemple #3
0
void test_arrayops()
{
#if DALVIK_ARRAY_SUPPORT
	assert(NULL != sexp_parse("(aput v1 v2 v3)", &sexp));
	assert(0 == dalvik_instruction_from_sexp(sexp, &inst, 0));
	assert(inst.opcode == DVM_ARRAY);
	assert(inst.flags = DVM_FLAG_ARRAY_PUT);
	assert(inst.num_operands == 3);
	assert(inst.operands[0].header.flags == 0);
	assert(inst.operands[0].payload.uint16 == 1);
	assert(inst.operands[1].header.info.type == DVM_OPERAND_TYPE_OBJECT);
	assert(inst.operands[1].payload.uint16 == 2);
	assert(inst.operands[2].header.info.type == DVM_OPERAND_TYPE_INT);
	assert(inst.operands[2].payload.uint16 == 3);
	sexp_free(sexp);
	dalvik_instruction_free(&inst);

	assert(NULL != sexp_parse("(aput-object v1 v2 v3)", &sexp));
	assert(0 == dalvik_instruction_from_sexp(sexp, &inst, 0));
	assert(inst.opcode == DVM_ARRAY);
	assert(inst.flags = DVM_FLAG_ARRAY_PUT);
	assert(inst.num_operands == 3);
	assert(inst.operands[0].header.info.type == DVM_OPERAND_TYPE_OBJECT);
	assert(inst.operands[0].payload.uint16 == 1);
	assert(inst.operands[1].header.info.type == DVM_OPERAND_TYPE_OBJECT);
	assert(inst.operands[1].payload.uint16 == 2);
	assert(inst.operands[2].header.info.type == DVM_OPERAND_TYPE_INT);
	assert(inst.operands[2].payload.uint16 == 3);
	sexp_free(sexp);
	dalvik_instruction_free(&inst);
	
	assert(NULL != sexp_parse("(aget-object v1 v2 v3)", &sexp));
	assert(0 == dalvik_instruction_from_sexp(sexp, &inst, 0));
	assert(inst.opcode == DVM_ARRAY);
	assert(inst.flags = DVM_FLAG_ARRAY_GET);
	assert(inst.num_operands == 3);
	assert(inst.operands[0].header.info.type == DVM_OPERAND_TYPE_OBJECT);
	assert(inst.operands[0].payload.uint16 == 1);
	assert(inst.operands[1].header.info.type == DVM_OPERAND_TYPE_OBJECT);
	assert(inst.operands[1].payload.uint16 == 2);
	assert(inst.operands[2].header.info.type == DVM_OPERAND_TYPE_INT);
	assert(inst.operands[2].payload.uint16 == 3);
	sexp_free(sexp);
	dalvik_instruction_free(&inst);
#endif
}
Exemple #4
0
void test_return()
{
	assert(NULL != sexp_parse("(return-object v1234)", &sexp));
	assert(0 == dalvik_instruction_from_sexp(sexp, &inst, 0));
	assert(inst.opcode == DVM_RETURN);
	assert(inst.num_operands == 1);
	assert(inst.operands[0].payload.uint16 == 1234);
	assert(inst.operands[0].header.info.size == 0);
	assert(inst.operands[0].header.info.type = DVM_OPERAND_TYPE_OBJECT);
	sexp_free(sexp);
	
	assert(NULL != sexp_parse("(return-void)", &sexp));
	assert(0 == dalvik_instruction_from_sexp(sexp, &inst, 0));
	assert(inst.opcode == DVM_RETURN);
	assert(inst.num_operands == 1);
	assert(inst.operands[0].header.info.type = DVM_OPERAND_TYPE_VOID);
	sexp_free(sexp);
}
Exemple #5
0
void test_invoke()
{
	assert(NULL != sexp_parse("(invoke-virtual {v1,v2,v3} this/is/a/test (int int int) int)", &sexp));
	assert(0 == dalvik_instruction_from_sexp(sexp,&inst, 0));
	assert(inst.opcode == DVM_INVOKE);
	assert(inst.flags == DVM_FLAG_INVOKE_VIRTUAL);
	assert(inst.num_operands == 7);
	//TODO: test it 
}
Exemple #6
0
void test_instanceops()
{
	assert(NULL != sexp_parse("(iput v1 v2 myclass.Property1 [array [object java.lang.String]])", &sexp));
	assert(0 == dalvik_instruction_from_sexp(sexp, &inst, 0));
	assert(inst.opcode == DVM_INSTANCE);
	assert(inst.flags = DVM_FLAG_INSTANCE_PUT);
	assert(inst.num_operands == 5);
	sexp_free(sexp);
	dalvik_instruction_free(&inst);
}
Exemple #7
0
void test_monitor()
{
	assert(NULL != sexp_parse("(monitor-enter v123)", &sexp));
	assert(0 == dalvik_instruction_from_sexp(sexp, &inst, 0));
	assert(inst.opcode == DVM_MONITOR);
	assert(inst.num_operands == 1);
	assert(inst.operands[0].header.info.type == 0);
	assert(inst.operands[0].payload.uint16 == 123);
	assert(inst.operands[0].header.info.is_const == 0);
	assert(inst.flags == DVM_FLAG_MONITOR_ENT);
	sexp_free(sexp);
	
	assert(NULL != sexp_parse("(monitor-exit v123)", &sexp));
	assert(0 == dalvik_instruction_from_sexp(sexp, &inst, 0));
	assert(inst.opcode == DVM_MONITOR);
	assert(inst.num_operands == 1);
	assert(inst.operands[0].header.info.type == 0);
	assert(inst.operands[0].payload.uint16 == 123);
	assert(inst.operands[0].header.info.is_const == 0);
	assert(inst.flags == DVM_FLAG_MONITOR_EXT);
	sexp_free(sexp);
}
Exemple #8
0
void test_sparse()
{
	assert(NULL != sexp_parse(
		   "(sparse-switch v4 \n"
		   "    (9 sp1) \n"
		   "    (10 sp2) \n"
		   "    (13 sp3) \n"
		   "    (65535 sp4)\n"
		   "    (default sp5))", 
		   &sexp));
	assert(0 == dalvik_instruction_from_sexp(sexp, &inst, 0));
	assert(inst.opcode == DVM_SWITCH);
	assert(inst.flags == DVM_FLAG_SWITCH_SPARSE);
	assert(inst.num_operands == 2);
	assert(inst.operands[0].header.flags == 0);
	assert(inst.operands[0].payload.uint16 = 4);
	assert(inst.operands[1].header.info.is_const == 1);
	assert(inst.operands[1].header.info.type == DVM_OPERAND_TYPE_SPARSE);
	assert(inst.operands[1].payload.sparse != NULL);
	vector_t* v = inst.operands[1].payload.branches;
	assert(4 ==((dalvik_sparse_switch_branch_t *)vector_get(v, 0))->labelid);
	assert(5 ==((dalvik_sparse_switch_branch_t *)vector_get(v, 1))->labelid);
	assert(6 ==((dalvik_sparse_switch_branch_t *)vector_get(v, 2))->labelid);
	assert(7 ==((dalvik_sparse_switch_branch_t *)vector_get(v, 3))->labelid);
	assert(8 ==((dalvik_sparse_switch_branch_t *)vector_get(v, 4))->labelid);

	assert(9 ==((dalvik_sparse_switch_branch_t *)vector_get(v, 0))->cond);
	assert(10 ==((dalvik_sparse_switch_branch_t *)vector_get(v, 1))->cond);
	assert(13 ==((dalvik_sparse_switch_branch_t *)vector_get(v, 2))->cond);
	assert(65535 ==((dalvik_sparse_switch_branch_t *)vector_get(v, 3))->cond);
	assert(0 ==((dalvik_sparse_switch_branch_t *)vector_get(v, 4))->cond);
	
	assert(0 ==((dalvik_sparse_switch_branch_t *)vector_get(v, 0))->is_default);
	assert(0 ==((dalvik_sparse_switch_branch_t *)vector_get(v, 1))->is_default);
	assert(0 ==((dalvik_sparse_switch_branch_t *)vector_get(v, 2))->is_default);
	assert(0 ==((dalvik_sparse_switch_branch_t *)vector_get(v, 3))->is_default);
	assert(1 ==((dalvik_sparse_switch_branch_t *)vector_get(v, 4))->is_default);

	assert(5 == vector_size(v));

	sexp_free(sexp);
	dalvik_instruction_free(&inst);
}
Exemple #9
0
dalvik_method_t* dalvik_method_from_sexp(const sexpression_t* sexp, const char* class_path,const char* file)
{

#ifdef PARSER_COUNT
    dalvik_method_count ++;
#endif

    dalvik_method_t* method = NULL;

    if(SEXP_NIL == sexp) return NULL;
    
    if(NULL == class_path) class_path = "(undefined)";
    if(NULL == file) file = "(undefined)";

    const char* name;
    sexpression_t *attrs, *arglist, *ret, *body;
    /* matches (method (attribute-list) method-name (arg-list) return-type body) */
    if(!sexp_match(sexp, "(L=C?L?C?_?A", DALVIK_TOKEN_METHOD, &attrs, &name, &arglist, &ret, &body))
    {
        LOG_ERROR("bad method defination"); 
        return NULL;
    }

    /* get attributes */
    int attrnum;
    if((attrnum = dalvik_attrs_from_sexp(attrs)) < 0)
    {
        LOG_ERROR("can not parse attributes");
        return NULL;
    }

    /* get number of arguments */
    int num_args;
    num_args = sexp_length(arglist);

    /* Now we know the size we have to allocate for this method */
    method = (dalvik_method_t*)malloc(sizeof(dalvik_method_t) + sizeof(dalvik_type_t*) * (num_args + 1));
    if(NULL == method) 
    {
        LOG_ERROR("can not allocate memory for method argument list");
        return NULL;
    }
    memset(method->args_type, 0, sizeof(dalvik_type_t*) * (num_args + 1));

    method->num_args = num_args;
    method->path = class_path;
    method->file = file;
    method->name = name;

    /* Setup the type of argument list */
    int i;
    for(i = 0;arglist != SEXP_NIL && i < num_args; i ++)
    {
        sexpression_t *this_arg;
        if(!sexp_match(arglist, "(_?A", &this_arg, &arglist))
        {
            LOG_ERROR("invalid argument list");
            goto ERR;
        }
        if(NULL == (method->args_type[i] = dalvik_type_from_sexp(this_arg)))
        {
            LOG_ERROR("invalid argument type @ #%d", i);
            goto ERR;
        }
    }

    /* Setup the return type */
    if(NULL == (method->return_type = dalvik_type_from_sexp(ret)))
    {
        LOG_ERROR("invalid return type");
        goto ERR;
    }

    /* Now fetch the body */
    
    //TODO: process other parts of a method
    int current_line_number = 0;    /* Current Line Number */
    uint32_t last = DALVIK_INSTRUCTION_INVALID;
    //int last_label = -1;
    int label_stack[DALVIK_METHOD_LABEL_STACK_SIZE];  /* how many label can one isntruction assign to */
    int label_sp;
    int from_label[DALVIK_MAX_CATCH_BLOCK];    /* NOTICE: the maximum number of catch block is limited to this constant */
    int to_label  [DALVIK_MAX_CATCH_BLOCK];
    int label_st  [DALVIK_MAX_CATCH_BLOCK];    /* 0: haven't seen any label related to the label. 
                                                * 1: seen from label before
                                                * 2: seen from and to label
                                                */
    label_sp  = 0;
    dalvik_exception_handler_t* excepthandler[DALVIK_MAX_CATCH_BLOCK] = {};
    dalvik_exception_handler_set_t* current_ehset = NULL;
    int number_of_exception_handler = 0;
    for(;body != SEXP_NIL;)
    {
        sexpression_t *this_smt;
        if(!sexp_match(body, "(C?A", &this_smt, &body))
        {
            LOG_ERROR("invalid method body");
            goto ERR;
        }
        /* First check if the statement is a psuedo-instruction */
        const char* arg;
#if LOG_LEVEL >= 6
        char buf[40906];
        static int counter = 0;
#endif
        LOG_DEBUG("#%d current instruction : %s",(++counter) ,sexp_to_string(this_smt, buf) );
        if(sexp_match(this_smt, "(L=L=L?", DALVIK_TOKEN_LIMIT, DALVIK_TOKEN_REGISTERS, &arg))
        {
            /* (limit-registers k) */
            method->num_regs = atoi(arg);
            LOG_DEBUG("uses %d registers", method->num_regs);
        }
        else if(sexp_match(this_smt, "(L=L?", DALVIK_TOKEN_LINE, &arg))
        {
            /* (line arg) */
            current_line_number = atoi(arg);
        }
        else if(sexp_match(this_smt, "(L=L?", DALVIK_TOKEN_LABEL, &arg))
        {
            /* (label arg) */
            int lid = dalvik_label_get_label_id(arg);
            int i;
            if(lid == -1) 
            {
                LOG_ERROR("can not create label for %s", arg);
                goto ERR;
            }
            //last_label = lid;
            if(label_sp < DALVIK_METHOD_LABEL_STACK_SIZE)
                label_stack[label_sp++] = lid;
            else
                LOG_WARNING("label stack overflow, might loss some label here");
            int enbaled_count = 0;
            dalvik_exception_handler_t* exceptionset[DALVIK_MAX_CATCH_BLOCK];
            for(i = 0; i < number_of_exception_handler; i ++)
            {
                if(lid == from_label[i] && label_st[i] == 0)
                    label_st[i] = 1;
                else if(lid == to_label[i] && label_st[i] == 1)
                    label_st[i] = 2;
                else if(lid == from_label[i] && label_st[i] != 0)
                    LOG_WARNING("meet from label twice, it might be a mistake");
                else if(lid == to_label[i] && label_st[i] != 1)
                    LOG_WARNING("to label is before from label, it might be a mistake");
                
                if(label_st[i] == 1)
                    exceptionset[enbaled_count++] = excepthandler[i];
            }
            current_ehset = dalvik_exception_new_handler_set(enbaled_count, exceptionset);
        }
        else if(sexp_match(this_smt, "(L=A", DALVIK_TOKEN_ANNOTATION, &arg))
        {
            /* Simplely ignore */
            LOG_INFO("fixme: ignored psuedo-insturction (annotation)");
        }
        else if(sexp_match(this_smt, "(L=L=A", DALVIK_TOKEN_DATA, DALVIK_TOKEN_ARRAY, &arg))
        {
            /* TODO: what is (data-array ....)statement currently ignored */
            LOG_INFO("fixme: (data-array) psuedo-insturction is to be implemented");
        }
        else if(sexp_match(this_smt, "(L=A", DALVIK_TOKEN_CATCH, &arg) || 
                sexp_match(this_smt, "(L=A", DALVIK_TOKEN_CATCHALL, &arg))
        {
            excepthandler[number_of_exception_handler] = 
                dalvik_exception_handler_from_sexp(
                        this_smt, 
                        from_label + number_of_exception_handler, 
                        to_label + number_of_exception_handler);
            if(excepthandler[number_of_exception_handler] == NULL)
            {
                LOG_WARNING("invalid exception handler %s", sexp_to_string(this_smt, NULL));
                continue;
            }
            LOG_DEBUG("exception %s is handlered in label #%d", 
                      excepthandler[number_of_exception_handler]->exception, 
                      excepthandler[number_of_exception_handler]->handler_label);
            //label_st[number_of_exception_handler] = 0;   /* TODO: verify this is a bug */
            number_of_exception_handler ++;
        }
        else if(sexp_match(this_smt, "(L=A", DALVIK_TOKEN_FILL, &arg))
        {
            //TODO: fill-array-data psuedo-instruction
            LOG_INFO("fixme: (fill-array-data) is to be implemented");
        }
        else
        {
            dalvik_instruction_t* inst = dalvik_instruction_new();
            if(NULL == inst) 
            {
                LOG_ERROR("can not create new instruction");
                goto ERR;
            }
            if(dalvik_instruction_from_sexp(this_smt, inst, current_line_number) < 0)
            {
                LOG_ERROR("can not recognize instuction %s", sexp_to_string(this_smt, NULL));
                goto ERR;
            }
            if(DALVIK_INSTRUCTION_INVALID == last) 
                method->entry = dalvik_instruction_get_index(inst);
            else
                dalvik_instruction_set_next(last, inst);
            last = dalvik_instruction_get_index(inst);
            inst->handler_set = current_ehset; 
            if(label_sp > 0)
            {
                int i;
                for(i = 0; i < label_sp; i++)
                {
                    LOG_DEBUG("assigned instruction@%p to label #%d", inst, label_stack[i]);
                    dalvik_label_jump_table[label_stack[i]] = dalvik_instruction_get_index(inst);
                }
                label_sp = 0;
            }
        }
    }
    return method;
ERR:
    dalvik_method_free(method);
    return NULL;
}
Exemple #10
0
void test_const()
{
	assert(NULL != sexp_parse("(const/high16 v123,1)", &sexp));
	assert(0 == dalvik_instruction_from_sexp(sexp, &inst, 0));
	assert(inst.opcode == DVM_CONST);
	assert(inst.num_operands == 2);
	assert(inst.operands[0].header.flags == 0);
	assert(inst.operands[0].header.info.type == 0);
	assert(inst.operands[0].payload.uint16 == 123);
	assert(inst.operands[1].header.info.is_const == 1);
	assert(inst.operands[1].payload.uint32 == 0x10000);
	sexp_free(sexp);


	assert(NULL != sexp_parse("(const v123,1235)", &sexp));
	assert(0 == dalvik_instruction_from_sexp(sexp, &inst, 0));
	assert(inst.opcode == DVM_CONST);
	assert(inst.num_operands == 2);
	assert(inst.operands[0].header.flags == 0);
	assert(inst.operands[0].header.info.type == 0);
	assert(inst.operands[0].payload.uint16 == 123);
	assert(inst.operands[1].header.info.is_const == 1);
	assert(inst.operands[1].payload.uint32 == 1235);
	sexp_free(sexp);
	
	assert(NULL != sexp_parse("(const/4 v123,1235)", &sexp));
	assert(0 == dalvik_instruction_from_sexp(sexp, &inst, 0));
	assert(inst.opcode == DVM_CONST);
	assert(inst.num_operands == 2);
	assert(inst.operands[0].header.flags == 0);
	assert(inst.operands[0].header.info.type == 0);
	assert(inst.operands[0].payload.uint16 == 123);
	assert(inst.operands[1].header.info.is_const == 1);
	assert(inst.operands[1].payload.uint32 == 1235);
	sexp_free(sexp);
	
	assert(NULL != sexp_parse("(const/16 v123,1235)", &sexp));
	assert(0 == dalvik_instruction_from_sexp(sexp, &inst, 0));
	assert(inst.opcode == DVM_CONST);
	assert(inst.num_operands == 2);
	assert(inst.operands[0].header.flags == 0);
	assert(inst.operands[0].header.info.type == 0);
	assert(inst.operands[0].payload.uint16 == 123);
	assert(inst.operands[1].header.info.is_const == 1);
	assert(inst.operands[1].payload.uint32 == 1235);
	sexp_free(sexp);
	
	assert(NULL != sexp_parse("(const-wide v123,123456789)", &sexp));
	assert(0 == dalvik_instruction_from_sexp(sexp, &inst, 0));
	assert(inst.opcode == DVM_CONST);
	assert(inst.num_operands == 2);
	assert(inst.operands[0].header.info.size == 1);
	assert(inst.operands[0].header.info.type == 0);
	assert(inst.operands[0].payload.uint16 == 123);
	assert(inst.operands[1].header.info.is_const == 1);
	assert(inst.operands[1].payload.uint64 == 123456789);
	sexp_free(sexp);
	
	assert(NULL != sexp_parse("(const-wide v123,123456789)", &sexp));
	assert(0 == dalvik_instruction_from_sexp(sexp, &inst, 0));
	assert(inst.opcode == DVM_CONST);
	assert(inst.num_operands == 2);
	assert(inst.operands[0].header.info.size == 1);
	assert(inst.operands[0].header.info.type == 0);
	assert(inst.operands[0].payload.uint16 == 123);
	assert(inst.operands[1].header.info.is_const == 1);
	assert(inst.operands[1].payload.uint64 == 123456789);
	sexp_free(sexp);
	
	assert(NULL != sexp_parse("(const-wide/high16 v123,1)", &sexp));
	assert(0 == dalvik_instruction_from_sexp(sexp, &inst, 0));
	assert(inst.opcode == DVM_CONST);
	assert(inst.num_operands == 2);
	assert(inst.operands[0].header.info.size == 1);
	assert(inst.operands[0].header.info.type == 0);
	assert(inst.operands[0].payload.uint16 == 123);
	assert(inst.operands[1].header.info.is_const == 1);
	assert(inst.operands[1].payload.uint64 == 0x0001000000000000ull);
	sexp_free(sexp);
	
	assert(NULL != sexp_parse("(const-string v123,\"this is a test case for const-string\")", &sexp));
	assert(0 == dalvik_instruction_from_sexp(sexp, &inst, 0));
	assert(inst.opcode == DVM_CONST);
	assert(inst.num_operands == 2);
	assert(inst.operands[1].header.info.type == DVM_OPERAND_TYPE_STRING);
	assert(inst.operands[1].payload.string == stringpool_query("this is a test case for const-string"));
	assert(inst.operands[1].header.info.is_const == 1);
	sexp_free(sexp);
	
	assert(NULL != sexp_parse("(const-class v123,this/is/a/test/class)", &sexp));
	assert(0 == dalvik_instruction_from_sexp(sexp, &inst, 0));
	assert(inst.opcode == DVM_CONST);
	assert(inst.num_operands == 2);
	assert(inst.operands[1].header.info.type == DVM_OPERAND_TYPE_CLASS);
	assert(inst.operands[1].payload.string == stringpool_query("this/is/a/test/class"));
	assert(inst.operands[1].header.info.is_const == 1);
	sexp_free(sexp);
}