1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Dalvik verification subroutines.
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Dalvik.h"
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "analysis/CodeVerify.h"
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "libdex/InstrUtils.h"
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
269fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * This is used when debugging to apply a magnifying glass to the
279fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * verification of a particular method.
289fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden */
299fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFaddenbool dvmWantVerboseVerification(const Method* meth)
309fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden{
319fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    return false;       /* COMMENT OUT to enable verbose debugging */
329fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
339fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    const char* cd = "Lcom/android/server/am/ActivityManagerService;";
349fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    const char* mn = "trimApplications";
359fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    const char* sg = "()V";
369fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    return (strcmp(meth->clazz->descriptor, cd) == 0 &&
379fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            dvmCompareNameDescriptorAndMethod(mn, sg, meth) == 0);
389fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden}
399fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
409fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden/*
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Output a code verifier warning message.  For the pre-verifier it's not
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a big deal if something fails (and it may even be expected), but if
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we're doing just-in-time verification it's significant.
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmLogVerifyFailure(const Method* meth, const char* format, ...)
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    va_list ap;
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int logLevel;
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (gDvm.optimizing) {
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return;
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //logLevel = ANDROID_LOG_DEBUG;
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        logLevel = ANDROID_LOG_WARN;
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    va_start(ap, format);
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOG_PRI_VA(logLevel, LOG_TAG, format, ap);
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (meth != NULL) {
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        char* desc = dexProtoCopyMethodDescriptor(&meth->prototype);
6160fc806b679a3655c228b4093058c59941a49cfeDan Bornstein        LOG_PRI(logLevel, LOG_TAG, "VFY:  rejected %s.%s %s",
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            meth->clazz->descriptor, meth->name, desc);
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        free(desc);
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Show a relatively human-readable message describing the failure to
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * resolve a class.
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO: this is somewhat misleading when resolution fails because of
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * illegal access rather than nonexistent class.
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmLogUnableToResolveClass(const char* missingClassDescr,
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const Method* meth)
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
77b08e2b6017770e887f6072c1520b2d7f2ef6916cElliott Hughes    if (gDvm.optimizing) {
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return;
79b08e2b6017770e887f6072c1520b2d7f2ef6916cElliott Hughes    }
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
81b08e2b6017770e887f6072c1520b2d7f2ef6916cElliott Hughes    std::string dotMissingClass = dvmHumanReadableDescriptor(missingClassDescr);
82b08e2b6017770e887f6072c1520b2d7f2ef6916cElliott Hughes    std::string dotFromClass = dvmHumanReadableDescriptor(meth->clazz->descriptor);
83c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block    ALOGE("Could not find class '%s', referenced from method %s.%s",
84b08e2b6017770e887f6072c1520b2d7f2ef6916cElliott Hughes            dotMissingClass.c_str(), dotFromClass.c_str(), meth->name);
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Extract the relative offset from a branch instruction.
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "false" on failure (e.g. this isn't a branch instruction).
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
92701d2720fa693621a3c0c4d0bdf9e32e3eb8e731Andy McFaddenbool dvmGetBranchOffset(const Method* meth, const InsnFlags* insnFlags,
93701d2720fa693621a3c0c4d0bdf9e32e3eb8e731Andy McFadden    int curOffset, s4* pOffset, bool* pConditional)
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const u2* insns = meth->insns + curOffset;
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (*insns & 0xff) {
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case OP_GOTO:
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pOffset = ((s2) *insns) >> 8;
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pConditional = false;
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case OP_GOTO_32:
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pOffset = insns[1] | (((u4) insns[2]) << 16);
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pConditional = false;
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case OP_GOTO_16:
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pOffset = (s2) insns[1];
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pConditional = false;
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case OP_IF_EQ:
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case OP_IF_NE:
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case OP_IF_LT:
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case OP_IF_GE:
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case OP_IF_GT:
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case OP_IF_LE:
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case OP_IF_EQZ:
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case OP_IF_NEZ:
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case OP_IF_LTZ:
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case OP_IF_GEZ:
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case OP_IF_GTZ:
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case OP_IF_LEZ:
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pOffset = (s2) insns[1];
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pConditional = true;
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return true;
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
132