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