Exemple #1
0
/*
 * Issue a method call with a variable number of arguments.  We process
 * the contents of "args" by scanning the method signature.
 *
 * Pass in NULL for "obj" on calls to static methods.
 *
 * We don't need to take the class as an argument because, in Dalvik,
 * we don't need to worry about static synchronized methods.
 */
void dvmCallMethodV(Thread* self, const Method* method, Object* obj,
    bool fromJni, JValue* pResult, va_list args)
{
    const char* desc = &(method->shorty[1]); // [0] is the return type.
    int verifyCount = 0;
    ClassObject* clazz;
    u4* ins;

#ifdef WITH_TAINT_TRACKING
    int slot_cnt = 0;
    bool nativeTarget = dvmIsNativeMethod(method);
#endif

    clazz = callPrep(self, method, obj, false);
    if (clazz == NULL)
        return;

    /* "ins" for new frame start at frame pointer plus locals */
#ifdef WITH_TAINT_TRACKING
    if (nativeTarget) {
	/* native target, no taint tag interleaving */
	ins = ((u4*)self->curFrame) + (method->registersSize - method->insSize);
    } else {
	/* interpreted target, taint tags are interleaved */
	ins = ((u4*)self->curFrame) +
	    ((method->registersSize - method->insSize) << 1);
    }
#else
    ins = ((u4*)self->curFrame) + (method->registersSize - method->insSize);
#endif

    //LOGD("  FP is %p, INs live at >= %p\n", self->curFrame, ins);

    /* put "this" pointer into in0 if appropriate */
    if (!dvmIsStaticMethod(method)) {
#ifdef WITH_EXTRA_OBJECT_VALIDATION
        assert(obj != NULL && dvmIsValidObject(obj));
#endif
        *ins++ = (u4) obj;
#ifdef WITH_TAINT_TRACKING
	if (!nativeTarget) {
	    *ins++ = TAINT_CLEAR;
	}
	slot_cnt++;
#endif
        verifyCount++;
    }

    JNIEnv* env = self->jniEnv;
    while (*desc != '\0') {
        switch (*(desc++)) {
            case 'D': case 'J': {
                u8 val = va_arg(args, u8);
                memcpy(ins, &val, 8);       // EABI prevents direct store
#ifdef WITH_TAINT_TRACKING
		if (nativeTarget) {
		    ins += 2;
		} else { /* adjust for taint tag interleaving */
		    ins[2] = ins[1];
		    ins[1] = TAINT_CLEAR;
		    ins[3] = TAINT_CLEAR;
		    ins += 4;
		}
		slot_cnt += 2;
#else
                ins += 2;
#endif
                verifyCount += 2;
                break;
            }
            case 'F': {
                /* floats were normalized to doubles; convert back */
                float f = (float) va_arg(args, double);
                *ins++ = dvmFloatToU4(f);
#ifdef WITH_TAINT_TRACKING
		if (!nativeTarget) {
		    *ins++ = TAINT_CLEAR;
		}
		slot_cnt++;
#endif
                verifyCount++;
                break;
            }
            case 'L': {     /* 'shorty' descr uses L for all refs, incl array */
                void* argObj = va_arg(args, void*);
                assert(obj == NULL || dvmIsValidObject(obj));
                if (fromJni)
                    *ins++ = (u4) dvmDecodeIndirectRef(env, argObj);
                else
                    *ins++ = (u4) argObj;
#ifdef WITH_TAINT_TRACKING
		if (!nativeTarget) {
		    *ins++ = TAINT_CLEAR;
		}
		slot_cnt++;
#endif
                verifyCount++;
                break;
            }
            default: {
                /* Z B C S I -- all passed as 32-bit integers */
                *ins++ = va_arg(args, u4);
#ifdef WITH_TAINT_TRACKING
		if (!nativeTarget) {
		    *ins++ = TAINT_CLEAR;
		}
		slot_cnt++;
#endif
                verifyCount++;
                break;
            }
        }
    }

#ifdef WITH_TAINT_TRACKING
    /* native hack spacer */
    *ins++ = TAINT_CLEAR; /* if nativeTarget, this is return taint */
    {
	int i;
	if (nativeTarget) {
	    for (i = 0; i < slot_cnt; i++) {
		*ins++ = TAINT_CLEAR;
	    }
	}
    }
#endif

#ifndef NDEBUG
    if (verifyCount != method->insSize) {
        LOGE("Got vfycount=%d insSize=%d for %s.%s\n", verifyCount,
            method->insSize, clazz->descriptor, method->name);
        assert(false);
        goto bail;
    }
#endif

    //dvmDumpThreadStack(dvmThreadSelf());

    if (dvmIsNativeMethod(method)) {
        TRACE_METHOD_ENTER(self, method);
        /*
         * Because we leave no space for local variables, "curFrame" points
         * directly at the method arguments.
         */
        (*method->nativeFunc)(self->curFrame, pResult, method, self);
        TRACE_METHOD_EXIT(self, method);
    } else {
#ifdef WITH_TAINT_TRACKING
	u4 rtaint; /* not used */
        dvmInterpret(self, method, pResult, &rtaint);
#else
        dvmInterpret(self, method, pResult);
#endif
    }

#ifndef NDEBUG
bail:
#endif
    dvmPopFrame(self);
}
Exemple #2
0
/*
 * Issue a method call with a variable number of arguments.  We process
 * the contents of "args" by scanning the method signature.
 *
 * Pass in NULL for "obj" on calls to static methods.
 *
 * We don't need to take the class as an argument because, in Dalvik,
 * we don't need to worry about static synchronized methods.
 */
void dvmCallMethodV(Thread* self, const Method* method, Object* obj,
    bool fromJni, JValue* pResult, va_list args)
{
	//salma
	//__android_log_print(ANDROID_LOG_DEBUG, "DVM DEBUG", "dvmCallMethodV method name = %s, clazz name: %s", method->name, method->clazz->descriptor);
    //end salma

	const char* desc = &(method->shorty[1]); // [0] is the return type.
    int verifyCount = 0;
    ClassObject* clazz;
    u4* ins;

    clazz = callPrep(self, method, obj, false);
    if (clazz == NULL)
        return;

    /* "ins" for new frame start at frame pointer plus locals */
    ins = ((u4*)self->interpSave.curFrame) +
           (method->registersSize - method->insSize);

    //ALOGD("  FP is %p, INs live at >= %p", self->interpSave.curFrame, ins);

    /* put "this" pointer into in0 if appropriate */
    if (!dvmIsStaticMethod(method)) {
#ifdef WITH_EXTRA_OBJECT_VALIDATION
        assert(obj != NULL && dvmIsHeapAddress(obj));
#endif
        *ins++ = (u4) obj;
        verifyCount++;
    }

    while (*desc != '\0') {
        switch (*(desc++)) {
            case 'D': case 'J': {
                u8 val = va_arg(args, u8);
                memcpy(ins, &val, 8);       // EABI prevents direct store
                ins += 2;
                verifyCount += 2;
                break;
            }
            case 'F': {
                /* floats were normalized to doubles; convert back */
                float f = (float) va_arg(args, double);
                *ins++ = dvmFloatToU4(f);
                verifyCount++;
                break;
            }
            case 'L': {     /* 'shorty' descr uses L for all refs, incl array */
                void* arg = va_arg(args, void*);
                assert(obj == NULL || dvmIsHeapAddress(obj));
                jobject argObj = reinterpret_cast<jobject>(arg);
                if (fromJni)
                    *ins++ = (u4) dvmDecodeIndirectRef(self, argObj);
                else
                    *ins++ = (u4) argObj;
                verifyCount++;
                break;
            }
            default: {
                /* Z B C S I -- all passed as 32-bit integers */
                *ins++ = va_arg(args, u4);
                verifyCount++;
                break;
            }
        }
    }

#ifndef NDEBUG
    if (verifyCount != method->insSize) {
        ALOGE("Got vfycount=%d insSize=%d for %s.%s", verifyCount,
            method->insSize, clazz->descriptor, method->name);
        assert(false);
        goto bail;
    }
#endif

    //dvmDumpThreadStack(dvmThreadSelf());

    if (dvmIsNativeMethod(method)) {
        TRACE_METHOD_ENTER(self, method);
        /*
         * Because we leave no space for local variables, "curFrame" points
         * directly at the method arguments.
         */
        (*method->nativeFunc)((u4*)self->interpSave.curFrame, pResult,
                              method, self);
        TRACE_METHOD_EXIT(self, method);
    } else {
        dvmInterpret(self, method, pResult);
    }

#ifndef NDEBUG
bail:
#endif
    dvmPopFrame(self);
}
Exemple #3
0
/*
 * Issue a method call with a variable number of arguments.  We process
 * the contents of "args" by scanning the method signature.
 *
 * Pass in NULL for "obj" on calls to static methods.
 *
 * We don't need to take the class as an argument because, in Dalvik,
 * we don't need to worry about static synchronized methods.
 */
void dvmCallMethodV(Thread* self, const Method* method, Object* obj,
    JValue* pResult, va_list args)
{
    const char* desc = &(method->shorty[1]); // [0] is the return type.
    int verifyCount = 0;
    ClassObject* clazz;
    u4* ins;

    clazz = callPrep(self, method, obj, false);
    if (clazz == NULL)
        return;

    /* "ins" for new frame start at frame pointer plus locals */
    ins = ((u4*)self->curFrame) + (method->registersSize - method->insSize);

    //LOGD("  FP is %p, INs live at >= %p\n", self->curFrame, ins);

    /* put "this" pointer into in0 if appropriate */
    if (!dvmIsStaticMethod(method)) {
#ifdef WITH_EXTRA_OBJECT_VALIDATION
        assert(obj != NULL && dvmIsValidObject(obj));
#endif
        *ins++ = (u4) obj;
        verifyCount++;
    }

    while (*desc != '\0') {
        switch (*(desc++)) {
            case 'D': case 'J': {
                u8 val = va_arg(args, u8);
                memcpy(ins, &val, 8);       // EABI prevents direct store
                ins += 2;
                verifyCount += 2;
                break;
            }
            case 'F': {
                /* floats were normalized to doubles; convert back */
                float f = (float) va_arg(args, double);
                *ins++ = dvmFloatToU4(f);
                verifyCount++;
                break;
            }
#ifdef WITH_EXTRA_OBJECT_VALIDATION
            case 'L': {     /* 'shorty' descr uses L for all refs, incl array */
                Object* argObj = (Object*) va_arg(args, u4);
                assert(obj == NULL || dvmIsValidObject(obj));
                *ins++ = (u4) argObj;
                verifyCount++;
                break;
            }
#endif
            default: {
                *ins++ = va_arg(args, u4);
                verifyCount++;
                break;
            }
        }
    }

#ifndef NDEBUG
    if (verifyCount != method->insSize) {
        LOGE("Got vfycount=%d insSize=%d for %s.%s\n", verifyCount,
            method->insSize, clazz->descriptor, method->name);
        assert(false);
        goto bail;
    }
#endif

    //dvmDumpThreadStack(dvmThreadSelf());

    if (dvmIsNativeMethod(method)) {
        /*
         * Because we leave no space for local variables, "curFrame" points
         * directly at the method arguments.
         */
        (*method->nativeFunc)(self->curFrame, pResult, method, self);
    } else {
        dvmInterpret(self, method, pResult);
    }

bail:
    dvmPopFrame(self);
}